I have a class derived from monobehaviour.
For various reasons when OnDisable() is called I need to know whether it was triggered by:
a) the GameObject it is a component of having SetActive( false ) called on it, or…
b) …whether SetActive( false ) was called on a GameObject higher up the hierarchy
is it possible to tell, and how can you do it?
N.B. I couldn’t find any questions that asked this, and since I have now solved this problem I thought I would share the information with the community by asking the question and answering it myself.
The only way you could do this is by wrapping up the function SetActive within the class itself. There, you could set a flag in the wrapper, which tells the program “I am being called from within this object”, that you would reset at the end of the OnDisable method. That way, if the flag hasn’t been set, then it is being called from elsewhere, while if it is set, then it is being called from within the current script.
There are two properties of GameObject that give information about its active state:
GameObject.activeSelf - this flag is only set by use of SetActive() on the GameObject it is a member variable of
GameObject.activeInHierarchy - this flag is also set by SetActive() on the GameObject, but also by use of SetActive() on any parent GameObject
See the GameObject documentation: Unity - Scripting API: GameObject
also see the ‘GameObject active state’ for more detail on how these flags work: Unity - Manual: Upgrading to Unity 4.0
Based on tests I did, it seems these flags are set by the Unity code before OnDisable() is called.
Given this information you can use these flags to determine which case a), or b) is true in the question:
a) both flags will be false in this case (SetActive( false ) was called on this object)
b) activeInHierarchy will be false, and activeSelf will be true (SetActive( false ) was called on an object upstream in the hierarchy)