Unity not recompiling script?

I have a singleton pattern GameManager script in my program that is set to DDOL. In its definition are numerous variables used throughout the game that need to persist between scenes. One such variable contains our client game revision which we validate vs a server.

This is the top of the GameManager Script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    [HideInInspector] public string playerName;
    [HideInInspector] public string gameRev = "3.84";
…
    private static GameManager _instance;
    public static GameManager Instance
    {
        get
        {
            if (_instance == null) _instance = FindObjectOfType<GameManager>();
            return _instance;
        }
    }

    private void Awake()
    {
        if (Instance != this)
        {
            Destroy(this.gameObject);
        }
        else
        {
            DontDestroyOnLoad(this.gameObject);
        }
     }
}

Thus this variable is accessed from outside this script via GameManager.Instance.gameRev

The strange behavior we are noticing is that when we change the string literal, the old value is retained.

For example: We updated the “3.84” in the code above from the previous value of “3.82”. We save, and wait for the Unity editor to note the change and allow us to run our game. The value of GameManager.Instance.gameRev is still evaluating to “3.82”. Namely: print(GameManager.Instance.gameRev); produces 3.82 in the Console.

I’ve done a search of the code and this variable is not being referenced anywhere else in the code where it could be changed.

Indeed as additional debugging, I added to the Awake event of GameManager, print(GameManager.Instance.gameRev); and it is still evaluating to 3.82, a value that no longer exists anywhere in our code, and for which this routine HAD to recompile as the print statement was executed.

Any ideas about what I could be missing here?

Incidentally…CHANGING the name of the variable gameRev allows the code to begin working again for a time. I used gameRev2 and it executes as intended showing the proper change…for a time. Then at some point in the future, a change to the string again causes the old value to be retained, and the game runs incorrectly until the variable name is changed again.

HideInInspector doesn’t mean that 3.82 isn’t serialized into the scene file, and Unity never overwrites existing serialized values with their new defaults.

For something like this, I’d recommend a get property:

public string gameRev => "3.84";
//this is shorthand for
public string gameRev {
get {
return "3.84";
}
}

Hi. I don’t mind it getting serialized into the scene,. What i do mind is when I change the literal, Unity not noting that it needs to re-serialize it.

Could you explain the statement, “Unity never overwrites existing serialized values with their new defaults.” Does this mean public variables in a class cannot be altered? That doesn’t seem to make sense either. If we change the public variables value, do we need to save the scene again?

Should I be using the [NonSerilaized] on these variables?

It means that the default value in the script is just that - the default. If you create new objects and attach the script, it’ll have the new default value. But once a value is saved, Unity won’t use the default value to override it.

You can use NonSerialized and it should work as you expect, but in this case (I’m assuming that gameRev won’t be changed during runtime), my recommendation is the code posted in the first comment.

1 Like

Thanks a lot Ray. I know now that to have public variables that behave as I am accustomed I will use the NonSerialized tag.