Is it possible to determine if OnDisable() is being called from parent.SetActive( false ) or self?

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.

2 Answers

2

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.

This would do it too, but in my use case I can just use the Unity flags :)

Ah I see, I wasn't sure whether those would work for your case, but if they do, then that's great.

Your way is more bulletproof and generic, have chosen it as the best answer :)

Your tests will probably prove to work well, my method is more general use, and is guaranteed to work as expected (using Unity's flags may produce problems if they do odd things, as you can't see the source code), but may be less readable or efficient than using Unity's flags, depending on how you use them.

Excellent, glad you sorted this out. Nice to see someone on here who is willing to continue testing and working out their own answers, rather than just waiting for someone else to do it.

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)