Unity: Dense Auto Increment Your Build Number Across Scenes

I was looking for a way to have a build number in Unity so that:

  1. I want a “build” number to be dense, at least as dense as commits
  2. it should auto increment on run
  3. it should auto increment from whatever scene you are launching your game
  4. it should be possible to decide to show it or not in every scene
  5. 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 &amp;&amp; !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&lt;TextMeshProUGUI&gt;();
                    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 &amp;&amp; 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&lt;T&gt;(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.

 

Social Share Toolbar

A post on videogame writing tools and user interface techniques

I just published a post on Gamasutra Videogame Dialogues: Writing Tools And Design Ideas, written with the voltairesque Daniele Giardini. We write about our current experiments with writing tools and dialogue user interface design. Hope you’ll find something useful there!

Social Share Toolbar

Character Trait Model: How Unhappy Is Unhappy

Modelling character traits can be tricky: an example problem has been presented by Jon Ingold in this GDC talk. I discuss the problem below and present a sample model that solves it. I provide an implementation in a C# class.

For character trait one may think of say the character happiness, or a relationship-with-X trait.

The problem is presented from minute 36 of the talk: the first idea that comes to mind in modelling a character trait is by using a number. Greater the number, better the state of the trait. This doesn’t work very well.

How Unhappy is Unhappy

From Jon Ingold GDC talk.

Then Ingold quickly jumps to a proposed solution, which consists in tracking two numbers, positive and negative experiences:

Unhappy vector

From Jon Ingold GDC talk.

Apart from the fact that changes are modelled more appropriately using two variables, what was exactly the problem with using one number?

Here is how I understood the problem: suppose you want to model the happiness of a character in a gameplay. You say that the variable HappinessLevel determines HappinessState according to these values:

HappinessLevel >= 5 = VERY_HAPPY
0 < HappinessLevel < 5 = HAPPY
-5 < HappinessLevel <= 0 = SAD
HappinessLevel <= -5 = SUICIDAL

The character goes through many episodes in two different game-plays: in one the character has 2 positive episodes, and 8 negative ones, and so goes SUICIDAL: 80% of the episodes were negative.

In another gameplay, the character has 20 positive episodes and 25 negative ones. Character is still SUICIDAL, but actually only  55% of episodes were negative! Something clearly does not work :-(

Taking the hint from the talk above, I’ve implemented a generic class model for Character Trait that considers the whole set of the episodes. The set of states and their level can be injected; moreover you can have a “decay %” so that for each new episode, all previous ones have a decay, so older the episode less relevant it gets :-) (by default decay is 1 so its turned off).

You find the class and a test (for Unity) in this zip. It can clearly be refined ad infinitum in function of specific needs, e.g. having episodes that are both positive and negative and so on.

A couple tests:

First test no decay test 1 output
Second test with decay Log with decay

Thanks to Daniele Giardini for campaigning for LINQ removal from the code.

Follow me on Twitter where I post about game design, game development, Unity3d 2D, HTML5, applied / serious games.

Social Share Toolbar

Tips For The Pragmatic Unity Developer

In the video below I’ve presented several productivity tips / hacks for the great Unity3d developer, that cultivates his / her essential qualities (impatience laziness hubris):

 

Sources & References

The three most essential plugins are DOTween, Text Mesh Pro and Console Pro.

Jet Brains IDE for C# preview here.

The “auto-save on play” script is here, The “no more hot reload script” is here, both by the same cool guy.

The scene object enable and disable script is this:

public class TheScene : MonoBehaviour
    {
        public GameObject[] activateOnStartup, deactivateOnStartup;
        
        void Start()
        {
            foreach (GameObject go in activateOnStartup)
            {
                go.SetActive(true);
                if (go.GetComponent<CanvasGroup>() != null)
                    go.GetComponent<CanvasGroup>().alpha = 1;
            }
            foreach (GameObject go in deactivateOnStartup)
            {
                go.SetActive(false);
                if (go.GetComponent<CanvasGroup>() != null)
                    go.GetComponent<CanvasGroup>().alpha = 0;
            }
        }
    }

Follow me on Twitter where I post about game design, game development, Unity3d 2D, HTML5, applied / serious games.

Social Share Toolbar

Unity3d: Giving runtime prefab instances meaningful names

This is a short note about a minor issue you may meet in Unity3d when you are creating scene objects in code, say from prefabs.

In my case I am creating a soccer field borders on the base of a grid that may resize, so I want to create everything in code.

Unity3d object instance with meaningless nameI am as always giving meaningful names to variables (and you should too) and so it would be nice to get the instance to be named as the variable, without duplications and without – oh horror – writing the instance name as string, breaking code esthetic and refactorings. In the pic on the side you see what you get by default – not cool.

Actually in the rich and hackable C# universe as managed in current Unity3d this is possible: just this way:

image

Thanks to this post here. I used it this way:

image

imagegetting good names on the instances Sorriso

 

Note that this relies on unspecified behaviour and while it does work in Microsoft’s current C# and VB compilers, and in Mono’s C# compiler, there’s no guarantee that this won’t stop working in future versions. See the discussions here:

Getting names of local variables (and parameters) at run-time through lambda expressions

Finding the Variable Name passed to a Function in C#

Update: It seems like this might no longer be an issue from C# 6, which will introduce the nameof operator to address such scenarios.

If you have suggestions on how to automate getting good instance names at runtime (maybe with cleaner / lesser code) let me know!

Follow me on Twitter where I post about game design, game development, Unity3d 2D, HTML5, serious games.

Social Share Toolbar

Game Development with Unity 2D – Part 0

Before we start our tutorial, lets look at others. Here are Part 1, Part 2, Part 3, Part 4, Part 5.

Some cool Unity 2D (4.3+) tutorials

Unity now includes specific tools for building 2D games. This makes it an even more attractive environment where to begin game development. While the Unity fellows are trying hard to make things as easy as possible, the 2D tools are not entirely trivial to use – game development is intrinsically complex. [Read more…]

Social Share Toolbar