- Home /
Strange Unity state machine behaviour: OnEnable - OnDisable before awake???
Hello everybody,
It seems that Unity has a really strange behavior when it start a game. I've made an elementary scene with only one camera. I've add to this camera a simple component to track the gameobject state changed:
using UnityEngine;
[ExecuteInEditMode]
public class StateTester: MonoBehaviour
{
public StateTester(){
Debug.LogWarning("StateTester - Constructor", this);
}
void Awake(){
Debug.LogWarning("StateTester - Awake", this);
}
void OnEnable(){
Debug.LogWarning("StateTester - OnEnable", this);
}
void OnDisable(){
Debug.LogWarning("StateTester - OnDisable", this);
}
void OnDestroy()
{
Debug.LogWarning("StateTester - OnDestroy", this);
}
// Use this for initialization
void Start () {
Debug.LogWarning("StateTester - Start", this);
}
}
When I start the scene here is the console output:
StateTester - OnDisable
StateTester - Constructor
StateTester - OnEnable
StateTester - OnDisable
StateTester - OnDestroy
StateTester - Constructor
StateTester - Awake
StateTester - OnEnable
StateTester - Start
So it seems that Unity creates twice each object when starting a scene and the first time call only OnEnable and OnDisable without Awake!!
It is a problem for me because some of my object does not work properly if OnEnable is called without Awake.
Is it the normal behaviour or is it something that will be corrected? (Do I have to change my design or wait the next Unity update?)
EDIT: More over, after the first construction all the fields are keeping there values (even the one set in Private). This is also a strange behavior IMO.
Answer by Bunny83 · Jul 21, 2011 at 11:29 PM
That is the normal behaviour of ExecuteInEditMode!!!
The object is already created in the editor. It just gets serialized before you enter playmode. Unity serializes the whole scene and save it temporarily. After that you're entering the actual "runtime".
You should notice the same thing when you stop the game. The object gets recreated after you're back in editmode and Unity deserializes everything from the saved copy.
Thanks for your answer! But - why OnEnable is called for the serialisation ? - why only in ExecuteInEdit$$anonymous$$ode? - why without calling Awake first? - why this important behaviour is not described in the documentation?
OnEnable is probably bound to the enabled property. When the object gets recreated it is set to true and therefore OnEnable is invoked.
Actually ExecuteInEdit$$anonymous$$ode is a feature that enables you to have some kind of animation like particle emitters or other effects run in the editor so you can see the same effect as you would in game. It's not meant to execute complex logic in the editor. If you want to extend the editor (custom inspector, logic editor, ...) you should write an editor script. Pure editor scripts can't run in game. They aren't even part of the game.
There should be a clear seperation between runtime and creationtime. Both work on the same data of course but they are two different things.
If you use ExecuteInEdit$$anonymous$$ode you should always make sure you distinguish between editmode and playmode. Application.isPlaying can be used to deter$$anonymous$$e if you are in playmode.
Also keep in $$anonymous$$d that if you use the UnityEditor namespace in such runtime scripts you need to surround the code with #if UNITY_EDITOR #endif
or you won't be able to create a build.
Thank you very much for your comment The problem I have with the editor script is that they are only active when the related gameobject is selected (I use CustomEditor). And I need to run some logic even on object that are not selected. I already use Application.isPlaying and UNITY_EDITOR.