I’ve actually always wondered this too.
I did a log out to a text file to make sure I’m not messing with the unity thread stuff. This is what I did:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class zTest03 : MonoBehaviour
{
public zTest03()
{
System.IO.File.AppendAllText(@"C:\zTemp\blargh.txt", string.Format("{0}: {1:hh:mm:ss.ffff}\r\n", nameof(zTest03), System.DateTime.Now));
}
public Blargh Value = new Blargh();
private void Awake()
{
System.IO.File.AppendAllText(@"C:\zTemp\blargh.txt", string.Format("{0}: {1:hh:mm:ss.ffff}\r\n", nameof(Awake), System.DateTime.Now));
}
[System.Serializable]
public class Blargh
{
public string Message;
public Blargh()
{
System.IO.File.AppendAllText(@"C:\zTemp\blargh.txt", string.Format("{0}: {1:hh:mm:ss.ffff}\r\n", nameof(Blargh), System.DateTime.Now));
}
}
}
And my results when pressing play are:
zTest03: 07:09:23.2980
Blargh: 07:09:23.3828
zTest03: 07:09:24.0943
Blargh: 07:09:24.0991
Awake: 07:09:24.1245
Now… first things first… I notice it creates the script itself twice in quick succession after another. Which is weird and likely a quark of the way Play works.
So to clear out any weirdness that the editor just happens to do when you press Play. I’m going to create a dummy scene which then loads a scene with this zTest03 in it when I press the space bar. See what happens.
And this is what I got then:
LoadSceneOnPressSpaceBar: 07:15:40.1101
zTest03: 07:15:40.1363
Blargh: 07:15:40.1405
Awake: 07:15:40.1648
And yeah… it was just some weirdness when you press Play.
And we also confirm that this class is only instantiated once and not twice.
How???
Well… I could think of 2 ways.
One is they instantiate the script (both the unity side and the C# side). Then when they loop over the fields to instantiate each member they check if an object already exists and use that instead of creating a new instance… and if it’s null it creates a new instance.
Another… maybe when they instantiate the script they directly access the heap and create the instance themselves. Note that Unity does use their own version of the mono runtime that they’ve added various tweaks to over the years. This could easily be one of them where they’ve tightly integrated their serialization engine and the memory manager.
Though… I bet it’s the first one.