- Home /
A weird issue in Unity related to scripts and Editor.
I have a class called PlayerData, marked as serializable, and it doesn't inherit any classes including MonoBehaviour. and it also doesn't contain any "InitializeOnLoad" things related to the Editor.
This constructor method contains a "Monobehaviour.Print("abc")" for example.
Now the issue happens, when I start the Unity, open this project, I didn't run anything, the constructor will be automatically run, because the "abc" will be automatically printed even the scene is not in running. When I see the stacktrace in Unity, it starts with this constructor, nothing else is calling it.
And, when I run the scene, this print() will be called multiple times, and some of them doesn't contain stacktraces in Unity, just a single line, which never happened before.
I don't have any other scripts which contains Editor or Editor related script.
What happened? I know it's related to the project, because it doesn't happen on other projects wich have the similar structure. I just want to know where to look into it.
I'm using Unity 5.0.2f1, this issue happened on both Windows and MacOS.
Answer by Baste · Jun 01, 2015 at 04:19 PM
This happens because you have some serialized object which has a field of the PlayerData type.
Unity serialized and deserializes data A LOT. When you enter play mode, Unity serializes (saves to disk) the enitre scene you're in, starts the runtime, and then recreates everything from the serialized data - ie. deserializes it.
As a part of that process, the object has to get constructed. When it's constructed, the constructor is called and you see your print message.
Things that can cause Unity to serialize or deserialize data, and in the process call constructors, is for example:
going into play mode
exiting play mode
opening a scene in the editor
saving the scene/project
selecting an object in the editor, and viewing it in the inspector
a lot more!
Check out this blog post to read more informaiton about serialization, and the issues that might crop up.
To fix this, you might want to ditch the constructor, and move that code to some "Initialize()" function. Then you call that on Awake from whatever MonoBehaviour that contains this object. In general, [Serializeable] objects should follow the same rules that goes from MonoBehaviours - don't use constructors. This if the reason for that.
As an alternative, you could wrap all the stuff in the constructor you don't want to be happening on play in
if(Application.isPlaying) {
Monobehaviour.print("abc");
... //other runtime-only code
}
That should take care of the messages, but the constructor will still be called.
Also, note that MonoBehaviour.print is the same thing as Debug.Log. MonoBehaviour.print exists so you can write
print("hello world");
instead of:
Debug.Log("hello world");
inside of a MonoBehaviour. If you're outside a MB, I think Debug.Log looks nicer.
Your answer
Follow this Question
Related Questions
On scene load function 0 Answers
Connecting oracle with unity tutorial, Steps or a way? 1 Answer
Get callback when assets loading or deserialization finished? 1 Answer
Reorderable list of UnityEvents 2 Answers
SRP URP Changing values of a material being shared by many objects in the Editor 0 Answers