- Home /
OnDisable() getting called from Destroy()
So apparently OnDisable also gets called when an object is destroyed. I need an OnDisable equivalent that only gets called when the object is disabled, not necessarily destroyed. OR I need a way to check if the object is destroyed from OnDisable. OR I need a Destroy equivalent that doesn't call OnDisable.
Can we get teh exact destroy call at least? maybe the OnDisable function?
Destroy(myObject);
which on myObject calls:
void OnDisable()
{
//Some disable logic.
}
I just don't want my disable logic to get called when the object is destroyed.
What's the standard way to call disable logic that ISN'T called when the object is destroyed? If there isn't anything, I'll just have to extend monobehaviour with my own SetActive() equivalent that Destroy() won't automatically call.
I don't know if there is a stadard way, but if you're eager to carry on while waiting for an answer and need a working solution:
Create a private bool that is set to true by default and is set to false before the Destroy call (I'm guessing you might have already implemented this)
//code
privateBoolParam = false;
Destroy(myObject);
//code
void OnDisable()
{
if(privateBoolParam){
//Some disable logic.
}
}
Wish I could help more, but that's all I got for now.
On another note, it makes sense for OnDisable() to be called, in case it contains some code that affects other objects, and it's being destroyed must update relevant objects.
Oops, I was tired, reversed the logic!
Answer by DanSuperGP · Jan 22, 2015 at 01:00 AM
As far as I know, there's no way to prevent this from happening, nor is there a built in way to check if the OnDisable is being triggered by the object being destroyed.
Answer by eelstork · Mar 29, 2015 at 04:57 PM
To a limited extent, we can tell whether OnDisabled is being messaged as a side effect of a game object being destroyed. Ideally, however, a parameter indicating the reason a component is being disabled/enabled (game object is being destroyed, or deactivated, or the component itself is being disabled) would be helpful.
In the meantime...
Inside OnDisable, check the value of this.enabled:
this.enabled is true when the game object is about to be destroyed (unless the component owned by said game object was previously disabled via enabled=false).
this.enabled is false when the object is being disabled but not about to get destroyed.
In general, checking the state of the enabled flag upon receiving OnDisable is not sufficient to determine whether a game object is about to be destroyed. For example, the same situation (OnDisable is messaged and this.enabled returns true) will occur when the game object is directly or indirectly deactivated.
Note: OnDisable is called before OnDestroy.
So I have just tested this and you are correct but only if the script is being deactivated rather than the GameObject. If the game object is deactivated OnDisable will be called but this.enabled can be true.
@halfbiscuit This question is about game objects being destroyed, not deactivated so it looks to me that you are testing something else... What you write is coherent ( does NOT contradict what I found! ) but it seems to me that we're another step back if anything since upon receiving OnDisable we cannot tell whether the object is being destroyed or deactivated... Although, it may be that OnDestroy is messaged before a script receives OnDisable...
Sorry I wasn't very clear, I was referring specifically to this line:
this.enabled is false when the object is being disabled but not about to get destroyed.
This is correct but I could see how some one looking at the comment would think that Object.gameObject.SetActive(false) and Object.enabled = false would both cause the OnDisable to have the same this.enabled value when they don't.
You really need to take the time to check the APIs you are referring to. By which I mean open the doc to ensure the properties are listed there. What is Object.enabled? Doesn't exist! You possibly mean Component.enabled... Never $$anonymous$$d, I will update my answer when I find the time to retest all this.
Well yes obviously I meant component but I thought you did too when you mentioned 'object' in your comment since technically all components derive from Object.
Answer by playsidepaul · Apr 04, 2017 at 04:36 AM
Found a way around this when the app is quitting, still not sure about scene changing tho.
OnApplicationQuit() is called in the execution order before all the OnDisable()s, so setting a flag in there allows the OnDisable() to have a bit more awareness of if it's being called normally, or from the app shutting down:
bool quitting = false;
void OnDisable ()
{
if (quitting)
return;
// Do stuff as usual
}
void OnApplicationQuit ()
{
quitting = true;
}
Answer by p0ck3t5 · Dec 12, 2015 at 12:02 AM
Necro'ing with another potential solution:
Create a "wrapper" function/method that handles destruction of game objects, and call that instead of Destroy(). One could also do this when setting enabled to false.
Pass the game object in as a parameter, then set flags or properties on the object, or perhaps change the object's tag (personal preference in most cases, although some methods are better than others in more situations) to tell you what is happening to the object, then call Destroy() (or set object.enabled to false) in the "wrapper" function - then simply check in your OnDisable() logic for the flags you set in the wrapper to determine the proper course of action in OnDisable().
Aside: an amazing amount of functionality can be added to your systems this way, although you fairly quickly stop coding in "Unity Style" and begin coding your own way, using your wrapper library you create as you go. This is not necessarily a bad thing!
I ended up doing a similar solution. I extended $$anonymous$$onoBehaviour and made methods OnDestroyOnly() and OnDisableOnly().
Answer by reddtoric · Aug 11, 2019 at 11:37 PM
Also this.isActiveAndEnabled
if this.enabled
does not work for you
Your answer
Follow this Question
Related Questions
Cancelling Destroy(gameObject, time); 3 Answers
[C#] Calling Destroy() in a custom class destructor 3 Answers
Cannot destroy GameObject while it is being activated or deactivated. 1 Answer
If destroyed? how to check if destroyed? 1 Answer
using Contains(gameObject) to find and destroy a gameObject from a list 2 Answers