Serializabel class not updating

I have a Serializable class and I make a public object of this class in another class like shown in the code:

[System.Serializable]
public class PlayerStats
{
	public float health;
	public float energy;
	public float _XP;

	public float maxHealth = 100;
	public float maxEnergy = 100;

	public PlayerStats()
	{
		energy = maxEnergy;
		health = maxHealth;
		_XP = 0;
		Debug.Log ("ctor");
	}
}


public class PlayerStatsManager : MonoBehaviour {


	public PlayerStats _playerStats;
}

When I change the value of any of the variables in “PlayerStats” class, it does not get reflected /changed in inspector. But when I remove the “PlayerStatsManager” from the gameobject and then add it again, then values get updated. Example: if I change “maxEnergy” to 200, it will not get changed unless I remove and add the script again on gameobject. Can someone explain why this is happening. Does this have anything to do with Serialization?

How/ when are you changing any of the variables?

Through an editor script? in edit mode, in playmode?

Or do you mean when you change this line of code

public float maxHealth = 100;

To something like this for instance:

public float maxHealth = 50;

If so, that is intended behaviour. (Or at least expected). This is because the values are serialized when you add the component. When you then change the default values of the script. You don’t change the serialized values. And obviously, when you change the serialized values in the inspector you don’t change the default values in the code. They are 2 different values. Which in a way makes sence, if you set up multiple objects where you set different values to each variable, you don’t want them to all change whenever you change the default script value.

Same applies when maxHealth would be located directly into PlayerStatsManager rather then PlayerStats btw.

I believe clicking the cog icon (to the right of the script name in the inspector) and hitting reset can also be used to reset your serialized values back to your default ones.

You have a wrong picture of how serialization works. Things you set in the constructor are irrelevant once the class got serialized. Whenever the class is deserialized it is first recreated (your constructor is called) and then the values are set to the values that has been serialized.

You might want to add a NonSerialized attribute to the variables you don’t want to be saved. Furthermore you might want to use a seperate method to actually reset your stats which you call after the deserialization has been completed. So either in Awake or Start of PlayerStatsManager.

 [System.Serializable]
 public class PlayerStats
 {
     public float health;
     public float energy;
     public float _XP;
 
     public float maxHealth = 100;
     public float maxEnergy = 100;
 
    void Reset()
    {
        energy = maxEnergy;
        health = maxHealth;
        _XP = 0;
    }
}

and in Awake:

void Awake()
{
    _playerStats.Reset();
}