I was looking for a way to have a build number in Unity so that:
- I want a “build” number to be dense, at least as dense as commits
- it should auto increment on run
- it should auto increment from whatever scene you are launching your game
- it should be possible to decide to show it or not in every scene
- it should totally take care of itself – so when I get feedback on a new build I can always ask the tester which build is she using, and I don’t go “damn it I forgot to increase the build number!!”
The idea is simply to have an editor script that changes a prefab (so that you can place it in every scene, but has a global state) each time you run. Here is my code, which you can fit to your needs (this also does the life-saving “save scene before run” which you may pick too):
// Author: Pietro Polsinelli - http://designAGame.eu // Twitter https://twitter.com/ppolsinelli // All free as in free beer using TMPro; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.SceneManagement; namespace OL { [InitializeOnLoad] public class AutoSaveOnRun { static AutoSaveOnRun() { //Thanks https://twitter.com/andrewlukasik for the "+=" fix. EditorApplication.playmodeStateChanged += () => { if (EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPlaying) { GameObject build = AssetDatabase.LoadAssetAtPath("Assets/__Scripts/Tools/Components/Build/Build.prefab", typeof(GameObject)) as GameObject; if (build != null) { TextMeshProUGUI bn = build.GetComponent<TextMeshProUGUI>(); if (string.IsNullOrEmpty(bn.text)) bn.text = "1"; else { bn.text = (int.Parse(bn.text)+1).ToString(); } } EditorSceneManager.SaveScene(SceneManager.GetActiveScene()); AssetDatabase.SaveAssets(); } }; } } }
P.S. More approaches
In order to change the build on compile and not on save, I now use this code in the (also very useful) stop-play-on-compile class:
// Copyright Cape Guy Ltd. 2015. http://capeguy.co.uk. // Provided under the terms of the MIT license - // http://opensource.org/licenses/MIT. Cape Guy accepts // no responsibility for any damages, financial or otherwise, // incurred as a result of using this code. // Modified by Pietro Polsinelli. 2017. https://twitter.com/ppolsinelli public class ExitPlayModeOnScriptCompile { static bool increasedBuildForThisCompile; // Static initialiser called by Unity Editor whenever scripts are loaded (editor or play mode) static ExitPlayModeOnScriptCompile() { Unused(_instance); _instance = new ExitPlayModeOnScriptCompile(); } ExitPlayModeOnScriptCompile() { EditorApplication.update += OnEditorUpdate; } ~ExitPlayModeOnScriptCompile() { EditorApplication.update -= OnEditorUpdate; // Silence the unused variable warning with an if. _instance = null; } // Called each time the editor updates. static void OnEditorUpdate() { if (EditorApplication.isCompiling && !increasedBuildForThisCompile) { increasedBuildForThisCompile = true; GameObject build = AssetDatabase.LoadAssetAtPath("Assets/__Scripts/Tools/Components/Build/Build.prefab", typeof(GameObject)) as GameObject; if (build != null) { TextMeshProUGUI bn = build.GetComponent<TextMeshProUGUI>(); if (string.IsNullOrEmpty(bn.text)) bn.text = "1"; else { bn.text = (int.Parse(bn.text) + 1).ToString(); } } } if (!EditorApplication.isCompiling) { increasedBuildForThisCompile = false; } if (EditorApplication.isPlaying && EditorApplication.isCompiling) { Debug.Log("Exiting play mode due to script compilation."); EditorApplication.isPlaying = false; } } // Used to silence the 'is assigned by its value is never used' warning for _instance. static void Unused<T>(T unusedVariable) { } static ExitPlayModeOnScriptCompile _instance = null; } }
Yet another approach is to identify the build number with a platform build (I don’t use that because I want density): https://gist.github.com/andrew-raphael-lukasik/36a30f0955d7cdc758e394dc4e7266bf.
Follow me on Twitter where I post about game design, game development, Unity3d 2D, HTML5, applied / serious games.