Search Unity

Automatic Version Increment Script

Discussion in 'Scripting' started by QuantumRyan, Jul 24, 2012.

  1. QuantumRyan

    QuantumRyan

    Joined:
    Aug 30, 2011
    Posts:
    11
    I've searched the forums for something to allow me to do version numbering on my game, but I couldn't find anything specific. Does anyone have a nice solution for version numbering?

    I've been programming a little Android game lately but I've been having problems knowing which version my other team mates are commenting on. I added a simple version number string to help, but I kept forgetting to increment it before pushing out a build for others to try so made a little script to do it automagically.

    The logic is pretty simple. I have it read, increment and then save a text file that has a string in the format "0.0.0.text". I control the "0.0" values by modifying the text file, but the last number is incremented any time the game code is compiled, or the game is run in the editor.

    Let me know what you think.

    Put this in an Editor folder (copy text below or download attached C# file).
    Code (csharp):
    1. //inspired by http://answers.unity3d.com/questions/45186/can-i-auto-run-a-script-when-editor-launches-or-a.html
    2.  
    3. using UnityEngine;
    4. using UnityEditor;
    5. using System.IO;
    6.        
    7. [InitializeOnLoad]
    8. public class VersionIncrementor
    9. {
    10.     static VersionIncrementor()    {
    11.         //If you want the scene to be fully loaded before your startup operation,
    12.         // for example to be able to use Object.FindObjectsOfType, you can defer your
    13.         // logic until the first editor update, like this:
    14.         EditorApplication.update += RunOnce;
    15.     }
    16.  
    17.     static void RunOnce()    {
    18.         EditorApplication.update -= RunOnce;
    19.         ReadVersionAndIncrement();
    20.     }
    21.  
    22.     static void ReadVersionAndIncrement()    {
    23.         //the file name and path.  No path is the base of the Unity project directory (same level as Assets folder)
    24.         string versionTextFileNameAndPath = "version.txt";
    25.  
    26.         string versionText = CommonUtils.ReadTextFile(versionTextFileNameAndPath);
    27.  
    28.         if (versionText != null)        {
    29.             versionText = versionText.Trim(); //clean up whitespace if necessary
    30.             string[] lines = versionText.Split('.');
    31.  
    32.             int MajorVersion = int.Parse(lines[0]);
    33.             int MinorVersion = int.Parse(lines[1]);
    34.             int SubMinorVersion = int.Parse(lines[2]) + 1; //increment here
    35.             string SubVersionText = lines[3].Trim();
    36.  
    37.             Debug.Log("Major, Minor, SubMinor, SubVerLetter: " + MajorVersion + " " + MinorVersion + " " + SubMinorVersion + " " + SubVersionText);
    38.  
    39.             versionText = MajorVersion.ToString("0") + "." +
    40.                           MinorVersion.ToString("0") + "." +
    41.                           SubMinorVersion.ToString("000") + "." +
    42.                           SubVersionText;
    43.  
    44.             Debug.Log("Version Incremented " + versionText);
    45.  
    46.             //save the file (overwrite the original) with the new version number
    47.             CommonUtils.WriteTextFile(versionTextFileNameAndPath, versionText);
    48.             //save the file to the Resources directory so it can be used by Game code
    49.             CommonUtils.WriteTextFile("Assets/Resources/version.txt", versionText);
    50.  
    51.             //tell unity the file changed (important if the versionTextFileNameAndPath is in the Assets folder)
    52.             AssetDatabase.Refresh();
    53.         }
    54.         else {
    55.             //no file at that path, make it
    56.             CommonUtils.WriteTextFile(versionTextFileNameAndPath, "0.0.0.a");
    57.         }
    58.     }
    59. }
    It uses some simple read/write text file logic which I have in a Scripts/Common directory. I've simplified it for this and called it CommonUtils.cs

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.IO;
    4.  
    5. public class CommonUtils
    6. {
    7.     public static string ReadTextFile(string sFileName)
    8.     {
    9.         //Debug.Log("Reading " + sFileName);
    10.  
    11.         //Check to see if the filename specified exists, if not try adding '.txt', otherwise fail
    12.         string sFileNameFound = "";
    13.         if (File.Exists(sFileName))
    14.         {
    15.             //Debug.Log("Reading '" + sFileName + "'.");
    16.             sFileNameFound = sFileName; //file found
    17.         }
    18.         else if (File.Exists(sFileName + ".txt"))
    19.         {
    20.             sFileNameFound = sFileName + ".txt";
    21.         }
    22.         else
    23.         {
    24.             Debug.Log("Could not find file '" + sFileName + "'.");
    25.             return null;
    26.         }
    27.  
    28.         StreamReader sr;
    29.         try
    30.         {
    31.             sr = new StreamReader(sFileNameFound);
    32.         }
    33.         catch (System.Exception e)
    34.         {
    35.             Debug.LogWarning("Something went wrong with read.  " + e.Message);
    36.             return null;
    37.         }
    38.  
    39.         string fileContents = sr.ReadToEnd();
    40.         sr.Close();
    41.  
    42.         return fileContents;
    43.     }
    44.  
    45.     public static void WriteTextFile(string sFilePathAndName, string sTextContents)
    46.     {
    47.         StreamWriter sw = new StreamWriter(sFilePathAndName);
    48.         sw.WriteLine(sTextContents);
    49.         sw.Flush();
    50.         sw.Close();
    51.     }
    52. }
     

    Attached Files:

    jalapen0 likes this.
  2. znoey

    znoey

    Joined:
    Oct 27, 2011
    Posts:
    174
    the idea is solid and useful, except incrementing when building. If you use svn, it would be awesome to parse the .svn files for a version #. Also, why make a version.txt? There's a bundle version and bundle version code attached to andriod and iOS builds anyway that you could be updating in the PlayerEditor (or something like that?)
    Code (csharp):
    1.  
    2.         PlayerSettings.bundleVersion = "1.0.22";
     
    Last edited: Jul 24, 2012
  3. Brian-Stone

    Brian-Stone

    Joined:
    Jun 9, 2012
    Posts:
    222
    If you're using C#, can't you use the assembly versioning system? I don't have Unity for Android, so I really don't know if this ports. But I don't know why it wouldn't.

    Code (csharp):
    1. [assembly: System.Reflection.AssemblyVersion("1.0.*.*")]
    2. class MyClass
    3. {
    4.     .... blah blah blah ....
    The assembly builder generates a timestamp for each assembly object. You don't have a lot of choice over the format, but you can, at least, prepend a fixed (manually entered) version number followed by the automatically generated timestamp. In the format string, the last two numbers can be replaced by asterisks. The first asterix will be replaced by the number of days since Feburary 1st, 2000. The second asterix will be replaced with the number of seconds from 12:00AM divided by 2. For example:

    You can access the version info of the executable at runtime through the Assembly namespace.

    Code (csharp):
    1.  
    2. Debug.Log(System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString());
    3.  
    Pretty simple. Here's the full MSDN doc....

    http://msdn.microsoft.com/en-us/library/system.reflection.assemblyversionattribute(v=vs.71).aspx
     
    Last edited: Jul 25, 2012
  4. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    This sounds useful indeed.

    I think it's good that you're using your own versioning number instead of using an iOS/Android one, as it'll keep your build numbers consistent across platforms.

    However, as it's a text file, how does it work if multiple people are working on the project?
     
  5. QuantumRyan

    QuantumRyan

    Joined:
    Aug 30, 2011
    Posts:
    11
    Awesome, thanks all!

    I didn't know about BundleVersion or the assembly versioning system, I'll give them a look. I want something that will work on stand alone and web builds too, but I imagine they could.

    The good thing about the text file is that I have control of it, and I can increment the minor version number when I want.
     
  6. QuantumRyan

    QuantumRyan

    Joined:
    Aug 30, 2011
    Posts:
    11
    I simplified my code for posting here for a single developer approach, but my actual code is made for working with multiple people. My situation puts me in charge of the published builds generally so I'm the master in charge of the version #, and others are more artists and level designers who have little to no impact on major code changes. We're using SVN.

    So for me, I don't check in the 'version.txt' file in the project folder, but the 'version.txt' file in the resources folder is in source control, and its what is referenced by other code. I've removed the else statement so that in the absence of 'version.txt' in the project folder, nothing happens. Thinking about it now, the whole VersionIncrementor.cs file could be excluded from source control and no one but me would have automagic updating.

    For a short time I was using something like this, but I didn't really like it and decided to use two text files instead.
    Code (csharp):
    1.  
    2.      string programmerName = PlayerPrefs.GetString("name", "none");
    3.      if(programmerName != "masterofthecode")
    4.          return;
    5.  
     
  7. omelchor

    omelchor

    Joined:
    Jun 15, 2011
    Posts:
    20
    Thx man, very helpful
     
  8. ina

    ina

    Joined:
    Nov 15, 2010
    Posts:
    1,085

    : The name `PlayerSettings' does not exist in the current context
     
  9. znoey

    znoey

    Joined:
    Oct 27, 2011
    Posts:
    174
    It must be an editor script so you'll need a using UnityEditor at the top.
     
  10. Ox_

    Ox_

    Joined:
    Jun 9, 2013
    Posts:
    93
  11. dval

    dval

    Joined:
    Jul 25, 2012
    Posts:
    24
    This is Awesome.
    Thank you. I often feel like learning .net is like trying to memorize Britannica. This is one of those gems.

    ...and it only took me 3 years to find...
     
  12. col000r

    col000r

    Joined:
    Mar 27, 2008
    Posts:
    699
    Hey, thanks for that script! I made it non-automatic (put it into the menu, so the version number only goes up every time I click "Increase Bundle Version"), made it change the actual Bundle Version and tweaked it to my liking. Thought I'd share it just in case anyone wants it:

    Code (CSharp):
    1.     [MenuItem("Build/Increase Bundle Version", false, 800)]
    2.     private static void BundleVersionPP() {
    3.  
    4.         int incrementUpAt = 9; //if this is set to 9, then 1.0.9 will become 1.1.0
    5.  
    6.         string versionText = PlayerSettings.bundleVersion;
    7.         if ( string.IsNullOrEmpty( versionText ) ) {
    8.             versionText = "0.0.1";
    9.         } else {
    10.             versionText = versionText.Trim(); //clean up whitespace if necessary
    11.             string[] lines = versionText.Split('.');
    12.            
    13.             int majorVersion = 0;
    14.             int minorVersion = 0;
    15.             int subMinorVersion = 0;
    16.  
    17.             if( lines.Length > 0 ) majorVersion = int.Parse( lines[0] );
    18.             if( lines.Length > 1 ) minorVersion = int.Parse( lines[1] );
    19.             if( lines.Length > 2 ) subMinorVersion = int.Parse( lines[2] );
    20.  
    21.             subMinorVersion++;
    22.             if( subMinorVersion > incrementUpAt ) {
    23.                 minorVersion++;
    24.                 subMinorVersion = 0;
    25.             }
    26.             if( minorVersion > incrementUpAt ) {
    27.                 majorVersion++;
    28.                 minorVersion = 0;
    29.             }
    30.  
    31.             versionText = majorVersion.ToString("0") + "." + minorVersion.ToString("0") + "." +    subMinorVersion.ToString("0");
    32.            
    33.         }
    34.         Debug.Log( "Version Incremented to " + versionText );
    35.         PlayerSettings.bundleVersion = versionText;
    36.     }
     
    abelevtsov and MatthewLFraser like this.
  13. FrancescoForno

    FrancescoForno

    Joined:
    Jan 16, 2016
    Posts:
    6
    Thanks for the scripts! I reworked the code in order to have an automatic increment on every build and menu items for manually incrementing the major and minor versions.

    Edit: I forgot to mention that this script is tailored for Android builds and Major.Minor.Build versioning scheme. Happy coding!

    Code (CSharp):
    1. // Version Incrementor Script for Unity by Francesco Forno (Fornetto Games)
    2. // Inspired by http://forum.unity3d.com/threads/automatic-version-increment-script.144917/
    3.  
    4. using UnityEditor;
    5. using UnityEditor.Callbacks;
    6. using UnityEngine;
    7.  
    8. [InitializeOnLoad]
    9. public class VersionIncrementor
    10. {
    11.     [PostProcessBuildAttribute(1)]
    12.     public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
    13.     {
    14.         Debug.Log("Build v" + PlayerSettings.bundleVersion + " (" + PlayerSettings.Android.bundleVersionCode + ")");
    15.         IncreaseBuild();
    16.     }
    17.  
    18.     static void IncrementVersion(int majorIncr, int minorIncr, int buildIncr)
    19.     {
    20.         string[] lines = PlayerSettings.bundleVersion.Split('.');
    21.  
    22.         int MajorVersion = int.Parse(lines[0]) + majorIncr;
    23.         int MinorVersion = int.Parse(lines[1]) + minorIncr;
    24.         int Build = int.Parse(lines[2]) + buildIncr;
    25.  
    26.         PlayerSettings.bundleVersion = MajorVersion.ToString("0") + "." +
    27.                                         MinorVersion.ToString("0") + "." +
    28.                                         Build.ToString("0");
    29.         PlayerSettings.Android.bundleVersionCode = MajorVersion * 10000 + MinorVersion * 1000 + Build;
    30.     }
    31.  
    32.     [MenuItem("Build/Increase Minor Version")]
    33.     private static void IncreaseMinor()
    34.     {
    35.         IncrementVersion(0, 1, 0);
    36.     }
    37.  
    38.     [MenuItem("Build/Increase Major Version")]
    39.     private static void IncreaseMajor()
    40.     {
    41.         IncrementVersion(1, 0, 0);
    42.     }
    43.  
    44.     private static void IncreaseBuild()
    45.     {
    46.         IncrementVersion(0, 0, 1);
    47.     }
    48. }
     
    Last edited: Feb 3, 2016
  14. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    My Procedural Asset Framework (https://www.assetstore.unity3d.com/en/#!/content/52447) has an AppDetails script which gives you automatic build numbering (as an int), as well as a build time stamp (as a DateTime). It also gives you runtime access to the product name and company name you specify in the player settings.
     
  15. pdwitte

    pdwitte

    Joined:
    Feb 3, 2016
    Posts:
    17
    Last edited: Nov 8, 2016
  16. McDev02

    McDev02

    Joined:
    Nov 22, 2010
    Posts:
    664
    Thanks that is great, I edited your script to make use of a ScriptableObject. Haven't tested it a lot but works so far. It uses the ResourceSingleton class that I used a lot. I edited it here so that it works out of the box.

    The logic changed so that each time you increase a version then the sub-versions are set to zero.

    Code (CSharp):
    1.  
    2. // Inspired by http://forum.unity3d.com/threads/automatic-version-increment-script.144917/
    3.  
    4. using UnityEngine;
    5. using System.IO;
    6. using UnityEditor;
    7. using UnityEditor.Callbacks;
    8. using System;
    9.  
    10. [InitializeOnLoad]
    11. public class VersionIncrementor : ResourceSingleton<VersionIncrementor>
    12. {
    13.    public int MajorVersion;
    14.    public int MinorVersion = 1;
    15.    public int BuildVersion;
    16.    public string CurrentVersion;
    17.  
    18.    [PostProcessBuild(1)]
    19.    public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
    20.    {
    21.        Debug.Log("Build v" + Instance.CurrentVersion);
    22.        IncreaseBuild();
    23.    }
    24.  
    25.    void IncrementVersion(int majorIncr, int minorIncr, int buildIncr)
    26.    {
    27.        MajorVersion += majorIncr;
    28.        MinorVersion += minorIncr;
    29.        BuildVersion += buildIncr;
    30.  
    31.        UpdateVersionNumber();
    32.    }
    33.  
    34.  
    35.    [MenuItem("Build/Create Version File")]
    36.    private static void Create()
    37.    {
    38.        Instance.Make();
    39.    }
    40.  
    41.    [MenuItem("Build/Increase Major Version")]
    42.    private static void IncreaseMajor()
    43.    {
    44.        Instance.MajorVersion++;
    45.        Instance.MinorVersion = 0;
    46.        Instance.BuildVersion = 0;
    47.        Instance.UpdateVersionNumber();
    48.    }
    49.    [MenuItem("Build/Increase Minor Version")]
    50.    private static void IncreaseMinor()
    51.    {
    52.        Instance.MinorVersion++;
    53.        Instance.BuildVersion = 0;
    54.        Instance.UpdateVersionNumber();
    55.    }
    56.  
    57.    private static void IncreaseBuild()
    58.    {
    59.        Instance.BuildVersion++;
    60.        Instance.UpdateVersionNumber();
    61.    }
    62.  
    63.    void UpdateVersionNumber()
    64.    {
    65.        //Make your custom version layout here.
    66.        CurrentVersion = MajorVersion.ToString("0") + "." + MinorVersion.ToString("00") + "." + BuildVersion.ToString("000");
    67.  
    68.        PlayerSettings.Android.bundleVersionCode = MajorVersion * 10000 + MinorVersion * 1000 + BuildVersion;
    69.        PlayerSettings.bundleVersion = CurrentVersion;
    70.    }
    71. }
    72.  
    73. public abstract class ResourceSingleton<T> : ScriptableObject
    74.        where T : ScriptableObject
    75. {
    76.    private static T m_Instance;
    77.    const string AssetPath = "Assets/Resources";
    78.  
    79.    public static T Instance
    80.    {
    81.        get
    82.        {
    83.            if (ReferenceEquals(m_Instance, null))
    84.            {
    85.                m_Instance = Resources.Load<T>(AssetPath + typeof(T).Name);
    86. #if UNITY_EDITOR
    87.                if (m_Instance == null)
    88.                {
    89.                    //Debug.LogError("ResourceSingleton Error: Fail load at " + "Singletons/" + typeof(T).Name);
    90.                    CreateAsset();
    91.                }
    92.                else
    93.                {
    94.                    //Debug.Log("ResourceSingleton Loaded: " + typeof (T).Name);
    95.                }
    96. #endif
    97.                var inst = m_Instance as ResourceSingleton<T>;
    98.                if (inst != null)
    99.                {
    100.                    inst.OnInstanceLoaded();
    101.                }
    102.            }
    103.            return m_Instance;
    104.        }
    105.    }
    106.  
    107.    public void Make() { }
    108.    static void CreateAsset()
    109.    {
    110.        m_Instance = ScriptableObject.CreateInstance<T>();
    111.        string path = Path.Combine(AssetPath, typeof(T).ToString() + ".asset");
    112.        path = AssetDatabase.GenerateUniqueAssetPath(path);
    113.        AssetDatabase.CreateAsset(m_Instance, path);
    114.  
    115.        AssetDatabase.SaveAssets();
    116.        AssetDatabase.Refresh();
    117.        EditorUtility.FocusProjectWindow();
    118.        Selection.activeObject = m_Instance;
    119.    }
    120.  
    121.    protected virtual void OnInstanceLoaded()
    122.    {
    123.    }
    124. }
    125.  
     
    Last edited: Mar 5, 2017
    lucasmontec likes this.
  17. Arshd

    Arshd

    Joined:
    Jan 24, 2015
    Posts:
    3
    Not adding much, I like this version the most and wanted to make sure it run smoothly for any one like me.

    You need to put this Script in an Editor Folder and it only works for Android but I'm sure somehow it can work for PC as well.

    Code (CSharp):
    1. // Minor adjustments by Arshd
    2. // Version Incrementor Script for Unity by Francesco Forno (Fornetto Games)
    3. // Inspired by http://forum.unity3d.com/threads/automatic-version-increment-script.144917/
    4.  
    5. using UnityEditor;
    6. using UnityEditor.Callbacks;
    7. using UnityEngine;
    8.  
    9. [InitializeOnLoad]
    10. public class VersionIncrementor
    11. {
    12.     [PostProcessBuild(1)]
    13.     public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
    14.     {
    15. #if UNITY_ANDROID
    16.         Debug.Log("Build v" + PlayerSettings.bundleVersion + " (" + PlayerSettings.Android.bundleVersionCode + ")");
    17.         IncreaseBuild();
    18. #endif
    19.     }
    20.  
    21.     static void IncrementVersion(int majorIncr, int minorIncr, int buildIncr)
    22.     {
    23.         string[] lines = PlayerSettings.bundleVersion.Split('.');
    24.  
    25.         int MajorVersion = int.Parse(lines[0]) + majorIncr;
    26.         int MinorVersion = int.Parse(lines[1]) + minorIncr;
    27.         int Build = 0;
    28.         if (lines.Length > 2)
    29.         {
    30.             Build = int.Parse(lines[2]) + buildIncr;
    31.         }
    32.  
    33.         PlayerSettings.bundleVersion = MajorVersion.ToString("0") + "." +
    34.                                         MinorVersion.ToString("0") + "." +
    35.                                         Build.ToString("0");
    36.         PlayerSettings.Android.bundleVersionCode = MajorVersion * 10000 + MinorVersion * 1000 + Build;
    37.     }
    38.  
    39.     [MenuItem("Build/Increase Minor Version")]
    40.     private static void IncreaseMinor()
    41.     {
    42.         IncrementVersion(0, 1, 0);
    43.     }
    44.  
    45.     [MenuItem("Build/Increase Major Version")]
    46.     private static void IncreaseMajor()
    47.     {
    48.         IncrementVersion(1, 0, 0);
    49.     }
    50.  
    51.     private static void IncreaseBuild()
    52.     {
    53.         IncrementVersion(0, 0, 1);
    54.     }
    55. }
     
    Last edited: May 21, 2017
    sia-dark likes this.
  18. tsny

    tsny

    Joined:
    Jan 27, 2018
    Posts:
    2
    Code (CSharp):
    1. // Minor adjustments by Arshd and then tsny
    2. // Version Incrementor Script for Unity by Francesco Forno (Fornetto Games)
    3. // Inspired by http://forum.unity3d.com/threads/automatic-version-increment-script.144917/
    4.  
    5. using System.IO;
    6. using UnityEditor;
    7. using UnityEditor.Build;
    8.  
    9. [InitializeOnLoad]
    10. public class VersionIncrementor : IPreprocessBuild
    11. {
    12.     public int callbackOrder
    13.     {
    14.         get
    15.         {
    16.             return 1;
    17.         }
    18.     }
    19.  
    20.     [MenuItem("Build/Build Current")]
    21.     public static void BuildCurrent()
    22.     {
    23.         IncreaseBuild();
    24.         BuildPlayerWindow.ShowBuildPlayerWindow();
    25.     }
    26.  
    27.     static void IncrementVersion(int majorIncr, int minorIncr, int buildIncr)
    28.     {
    29.         string[] lines = PlayerSettings.bundleVersion.Split('.');
    30.  
    31.         int MajorVersion = int.Parse(lines[0]) + majorIncr;
    32.         int MinorVersion = int.Parse(lines[1]) + minorIncr;
    33.         int Build = 0;
    34.         if (lines.Length > 2)
    35.         {
    36.             Build = int.Parse(lines[2]) + buildIncr;
    37.         }
    38.  
    39.         PlayerSettings.bundleVersion = MajorVersion.ToString("0") + "." +
    40.                                         MinorVersion.ToString("0") + "." +
    41.                                         Build.ToString("0");
    42.  
    43.         var buildVersionPath = @"buildversion.txt";
    44.  
    45.         File.WriteAllText(buildVersionPath, PlayerSettings.bundleVersion);
    46.     }
    47.  
    48.     public static string GetLocalVersion()
    49.     {
    50.         return PlayerSettings.bundleVersion.ToString();
    51.     }
    52.  
    53.     [MenuItem("Build/Increase Minor Version")]
    54.     private static void IncreaseMinor()
    55.     {
    56.         IncrementVersion(0, 1, 0);
    57.     }
    58.  
    59.     [MenuItem("Build/Increase Major Version")]
    60.     private static void IncreaseMajor()
    61.     {
    62.         IncrementVersion(1, 0, 0);
    63.     }
    64.  
    65.     [MenuItem("Build/Increase Current Build Version")]
    66.     private static void IncreaseBuild()
    67.     {
    68.         IncrementVersion(0, 0, 1);
    69.     }
    70.  
    71.     public void OnPreprocessBuild(BuildTarget target, string path)
    72.     {
    73.         IncreaseBuild();
    74.     }
    75. }
    This is my implementation changed a bit from Arshd.
    This should increment your version before every build automatically.
     
    just_gos and Arshd like this.
  19. RKar

    RKar

    Joined:
    Mar 6, 2019
    Posts:
    22
    Code (CSharp):
    1. // Minor adjustments by Arshd and then tsny and finaly RKar
    2. // Version Incrementor Script for Unity by Francesco Forno (Fornetto Games)
    3. // Inspired by http://forum.unity3d.com/threads/automatic-version-increment-script.144917/
    4.  
    5. #if UNITY_EDITOR
    6. using UnityEditor;
    7. using UnityEditor.Build;
    8.  
    9. [InitializeOnLoad]
    10. class VersionIncrementor: IPreprocessBuild
    11. {
    12.     [MenuItem("Build/Increase Current Build Version")]
    13.     private static void IncreaseBuild()
    14.     {
    15.         IncrementVersion(new int[] { 0, 0, 1 });
    16.     }
    17.  
    18.     [MenuItem("Build/Increase Minor Version")]
    19.     private static void IncreaseMinor()
    20.     {
    21.         IncrementVersion(new int[] { 0, 1, 0 });
    22.     }
    23.  
    24.     [MenuItem("Build/Increase Major Version")]
    25.     private static void IncreaseMajor()
    26.     {
    27.         IncrementVersion(new int[] { 1, 0, 0 });
    28.     }
    29.  
    30.     static void IncrementVersion(int[] versionIncr)
    31.     {
    32.         string[] lines = PlayerSettings.bundleVersion.Split('.');
    33.  
    34.         for (int i = lines.Length - 1; i >= 0; i--)
    35.         {
    36.             bool isNumber = int.TryParse(lines[i], out int numberValue);
    37.  
    38.             if (isNumber && versionIncr.Length - 1 >= i)
    39.             {
    40.                 if (i > 0 && versionIncr[i] + numberValue > 9)
    41.                 {
    42.                     versionIncr[i - 1]++;
    43.  
    44.                     versionIncr[i] = 0;
    45.                 }
    46.                 else
    47.                 {
    48.                     versionIncr[i] += numberValue;
    49.                 }
    50.             }
    51.         }
    52.  
    53.         PlayerSettings.bundleVersion = versionIncr[0] + "." + versionIncr[1] + "." + versionIncr[2];
    54.     }
    55.  
    56.     public static string GetLocalVersion()
    57.     {
    58.         return PlayerSettings.bundleVersion.ToString();
    59.     }
    60.  
    61.     public void OnPreprocessBuild(BuildTarget target, string path)
    62.     {
    63.         IncreaseBuild();
    64.     }
    65.  
    66.     public int callbackOrder { get { return 0; } }
    67. }
    68. #endif
    69.  
    I added protection against an incorrect version string.
     
    Last edited: Mar 6, 2019
    Aurigan and Arshd like this.
  20. giggioz

    giggioz

    Joined:
    May 11, 2017
    Posts:
    52
    When I build sometimes I need to increment the version and sometimes I don't (and sometimes I forget to do it!)

    My implementation shows a dialog window during the build process and I can choose what to do.

    The code related to the increment is pretty rough, but you get the idea.

    Code (CSharp):
    1. public void OnPreprocessBuild(BuildReport report)
    2.     {
    3.  
    4.         bool shouldIncrement = EditorUtility.DisplayDialog("Incrementer", "Applying increment? Current: v" + PlayerSettings.bundleVersion, "Yes", "No");
    5.  
    6.         if (shouldIncrement)
    7.         {
    8.             string[] numbers = PlayerSettings.bundleVersion.Split('.');
    9.             string major = numbers[0];
    10.             int minor = Convert.ToInt32(numbers[1]);
    11.             minor++;
    12.             PlayerSettings.bundleVersion = major+"."+minor;
    13.         }
    14. }
     
    AnKOu, sduval, kreso and 2 others like this.
  21. IggyZuk

    IggyZuk

    Joined:
    Jan 17, 2015
    Posts:
    43
    In case you also want to automatically increase Android & iOS version codes.

    Code (CSharp):
    1. #if UNITY_EDITOR
    2.  
    3. using UnityEditor;
    4. using UnityEditor.Build;
    5. using UnityEditor.Build.Reporting;
    6.  
    7. [InitializeOnLoad]
    8. class VersionIncrementor : IPreprocessBuildWithReport
    9. {
    10.     public int callbackOrder => 0;
    11.  
    12.     [MenuItem("Tools/Build/Increase Both Versions &v")]
    13.     static void IncreaseBothVersions()
    14.     {
    15.         IncreaseBuild();
    16.         IncreasePlatformVersion();
    17.     }
    18.  
    19.     [MenuItem("Tools/Build/Increase Current Build Version")]
    20.     static void IncreaseBuild()
    21.     {
    22.         IncrementVersion(new[] {0, 0, 1});
    23.     }
    24.  
    25.     [MenuItem("Tools/Build/Increase Minor Version")]
    26.     static void IncreaseMinor()
    27.     {
    28.         IncrementVersion(new[] {0, 1, 0});
    29.     }
    30.  
    31.     [MenuItem("Tools/Build/Increase Major Version")]
    32.     static void IncreaseMajor()
    33.     {
    34.         IncrementVersion(new[] {1, 0, 0});
    35.     }
    36.  
    37.     [MenuItem("Tools/Build/Increase Platform Version")]
    38.     static void IncreasePlatformVersion()
    39.     {
    40.         PlayerSettings.Android.bundleVersionCode += 1;
    41.         PlayerSettings.iOS.buildNumber = (int.Parse(PlayerSettings.iOS.buildNumber) + 1).ToString();
    42.     }
    43.  
    44.     static void IncrementVersion(int[] version)
    45.     {
    46.         string[] lines = PlayerSettings.bundleVersion.Split('.');
    47.  
    48.         for (int i = lines.Length - 1; i >= 0; i--)
    49.         {
    50.             bool isNumber = int.TryParse(lines[i], out int numberValue);
    51.  
    52.             if (isNumber && version.Length - 1 >= i)
    53.             {
    54.                 if (i > 0 && version[i] + numberValue > 9)
    55.                 {
    56.                     version[i - 1]++;
    57.  
    58.                     version[i] = 0;
    59.                 }
    60.                 else
    61.                 {
    62.                     version[i] += numberValue;
    63.                 }
    64.             }
    65.         }
    66.  
    67.         PlayerSettings.bundleVersion = $"{version[0]}.{version[1]}.{version[2]}";
    68.     }
    69.  
    70.     public void OnPreprocessBuild(BuildReport report)
    71.     {
    72.         bool shouldIncrement = EditorUtility.DisplayDialog(
    73.             "Increment Version?",
    74.             $"Current: {PlayerSettings.bundleVersion}",
    75.             "Yes",
    76.             "No"
    77.         );
    78.  
    79.         if (shouldIncrement) IncreaseBothVersions();
    80.     }
    81. }
    82.  
    83. #endif
     
    Last edited: Aug 18, 2020
    mcbauer, Recluse, xaldin-76 and 2 others like this.
  22. Lapsapnow

    Lapsapnow

    Joined:
    Jul 4, 2019
    Posts:
    51
    I'm quite sad that all of these are Android and iOS dependent methods.

    For anyone looking for a PC version. Make use of a ScriptableObject. As the data stored in them is persistent.
    Something along the lines of OnProcessBuild, getScriptableObject, buildValue += 1;
     
    Streamfall and Ziplock9000 like this.
  23. dredhorse5

    dredhorse5

    Joined:
    Jul 18, 2020
    Posts:
    1
    Three years later)
    I modified the last version, here's what I changed:
    • Patсh, Minor and Major versions are not related. that is, if 0.0.1 is added to version 0.0.9, it will be 0.0.10, not 0.1.0.
    • This is done so that you can add 3 options to unity-pop-up, namely: "Patch(0.0.X)", "Minor(0.X.0)", "Major(X,0,0)". each of these buttons increases the version of X.
    • Now, when the high version is upgraded, the smaller versions are reset, that is: it was 0.0.5, after the Minor update it will be 0.1.0. The last element is reset.
    • If you receive an error during the build, build version will be rolled to last
    Code (CSharp):
    1. #if UNITY_EDITOR
    2. using UnityEditor;
    3. using UnityEditor.Build;
    4. using UnityEditor.Build.Reporting;
    5. using UnityEngine;
    6.  
    7. // Modified by dredhorse5
    8.  
    9. [InitializeOnLoad]
    10. class VersionIncrementor : IPreprocessBuildWithReport, IPostprocessBuildWithReport
    11. {
    12.     public int callbackOrder => 0;
    13.  
    14.     private static string lastVersion;
    15.  
    16.     [MenuItem("Tools/Build/Increase Both Versions &v")]
    17.     static void IncreaseBothVersions()
    18.     {
    19.         IncreaseBuild();
    20.         IncreasePlatformVersion();
    21.     }
    22.     [MenuItem("Tools/Build/Increase Current Build Version")]
    23.     static void IncreaseBuild()
    24.     {
    25.         IncrementVersion(new[] {0, 0, 1});
    26.     }
    27.     [MenuItem("Tools/Build/Increase Minor Version")]
    28.     static void IncreaseMinor()
    29.     {
    30.         IncrementVersion(new[] {0, 1, 0});
    31.     }
    32.     [MenuItem("Tools/Build/Increase Major Version")]
    33.     static void IncreaseMajor()
    34.     {
    35.         IncrementVersion(new[] {1, 0, 0});
    36.     }
    37.     [MenuItem("Tools/Build/Increase Platform Version")]
    38.     static void IncreasePlatformVersion()
    39.     {
    40.         PlayerSettings.Android.bundleVersionCode += 1;
    41.         PlayerSettings.iOS.buildNumber = (int.Parse(PlayerSettings.iOS.buildNumber) + 1).ToString();
    42.     }
    43.     static void IncrementVersion(int[] version)
    44.     {
    45.         var rawVer = version.Clone() as int[];
    46.         string[] lines = PlayerSettings.bundleVersion.Split('.');
    47.         for (int i = lines.Length - 1; i >= 0; i--)
    48.         {
    49.             bool isNumber = int.TryParse(lines[i], out int numberValue);
    50.             if (isNumber && version.Length - 1 >= i)
    51.                 version[i] += numberValue;
    52.         }
    53.  
    54.         // Clears the lowest versions by higher
    55.         bool toZero = false;
    56.         for (int i = 0; i < rawVer.Length; i++)
    57.         {
    58.             if (toZero)
    59.                 version[i] = 0;
    60.             else if (rawVer[i] == 1)
    61.                 toZero = true;
    62.         }
    63.            
    64.         lastVersion= PlayerSettings.bundleVersion;
    65.         PlayerSettings.bundleVersion = $"{version[0]}.{version[1]}.{version[2]}";
    66.     }
    67.     public void OnPreprocessBuild(BuildReport report)
    68.     {
    69.         int shouldIncrement = EditorUtility.DisplayDialogComplex(
    70.             "Increment Version",
    71.             $"Current: {PlayerSettings.bundleVersion}",
    72.             "Patch (0.0.X)",
    73.             "Major(X.0.0)",
    74.             "Minor(0.X.0)"
    75.         );
    76.  
    77.         switch (shouldIncrement)
    78.         {
    79.             case 0: IncreaseBuild(); break;
    80.             case 1: IncreaseMajor(); break;
    81.             case 2: IncreaseMinor(); break;
    82.         }
    83.  
    84.         IncreasePlatformVersion();
    85.         Application.logMessageReceived += OnBuildError;
    86.     }
    87.     private void OnBuildError(string condition, string stacktrace, LogType type)
    88.     {
    89.         if (type == LogType.Error)
    90.         {
    91.             Application.logMessageReceived -= OnBuildError;
    92.             Debug.LogError($"Version rolled from {PlayerSettings.bundleVersion} to {lastVersion} due to build error");
    93.             PlayerSettings.bundleVersion = lastVersion;
    94.         }
    95.     }
    96.     public void OnPostprocessBuild(BuildReport report)
    97.     {
    98.         Application.logMessageReceived -= OnBuildError;
    99.     }
    100. }
    101. #endif
    I hope it will be useful to you)
     
    Last edited: Sep 26, 2023
    zb737472783 and Sehee26 like this.