Difference between inline constructor with [SerializeField] above it, and calling a constructor from Reset()

Am I allowed to call constructor on the same line when I declare the variable, and it has [SerializeField] attribute above it? Or should I call constructor for a [serializeField]-variable once, from, say, Reset() ?

I intend to then modify the contents of character_stats through an Inspector panel, during Editor.


Example:

public class MyMonoB : Monobehaviour {

    [SerializeField]
    protected CharacterStats character_stats = new CharacterStats();   <------------------this

}

[Serializable]
public class CharacterStats {

      public List<int> myList = new List<int>();

      public CharacterStats(){
               myList.Add(69);
      }
}

What if I instead do :

 public class MyMonoB : Monobehaviour {
    
    [SerializeField]
    protected CharacterStats character_stats; //don't initialize here

    void Reset(){
            //initialize here instead:
            character_stats = new CharacterStats();  <------------------this
    }
}

Note that when you have a serializable class, calling the constructor manually makes not too much sense. It’s only used the first time Unity encounters your serialized variable “character_stats”. From now on the infotmation stored inside your “CharacterStats” class is serialized along with the “MyMonoB” instance.

When ever the instance is now loaded, Unity will first create your MyMonoB class using the default constructor and then deserialize the class. If you add a field-initializer it will create an instance of your CharacterStats class when the MyMonoB class is created.

However when MyMonoB is deserialized the content of “character_stats” will be overwritten during the deserialization process. So from the serialization point of view it’s pointless to use a field initializer. It just adds unnecessary overhead. However it’s the Unity editor and the serialization system that will automatically create an instance of your serialized field inside the editor during edit time. When you create a MyMonoB component with AddComponent at runtime, no CharacterStats instance will be created.

So it highly depends on your usecase. If you only need that CharacterStats class to be serialized, don’t use a field initializer.

Note: calling the default constructor inside Reset is completely pointless ^^. Reset is only called once when the object is created inside the editor. It’s not called at runtime. It’s also called when you click “Reset” in the inspector. However when you click Reset Unity will automatically dump all serialized data and recreated the CharacterStats instance with the default constructor.

The best way is usually to simply ensure you have an instance in Awake.

public class MyMonoB : Monobehaviour
{
    [SerializeField]
    protected CharacterStats character_stats;
    void Awake()
    {
        if (character_stats == null)
            character_stats = new CharacterStats();
    }
}

So here you will use the serialized version it available, but if the class is created dynamically with AddComponent at runtime you will create an instance.

Note that using Instantiate to clone an object / prefab will work on the serialized data. So instantiating a prefab will also automatically create and deserialize your CharacterStats instance.

To me this will have almost the same behaviour. The only difference being that putting it in Reset will reset it when you click on Reset from the pulldown menu in the inspector.