- Home /
Isolate OnDisable from OnDestroy
I want to check only if the object has been disabled or set inactive, so I can prevent it from being disabled if a certain circumstance is true. I want to ignore when it is being destroyed to prevent errors. Something like this:
function OnDisable() {
if (!beenDestroyed && myStaticVariableIsTrue) {
print ("Disabled or Set inactive");
gameObject.active = true;
}
}
Problem is: I don't have a valid `beenDestroyed` and don't know where to get one.
Main reason I want to do this (as I've explained in detail below) is because there are many scripts dealing with enabling and disabling (trough SetActiveRecursively
) with objects and only a few of those are to be "protected" in this way - coincidentally some of the top most children of them.
Preamble
Following a similar question, seems like this is how OnDisable
currently works, which is almost* (read below) useless:
function OnDisable() {
if (gameObject.active) {
print ("Disabled or Destroyed");
} else {
print ("Set inactive");
}
}
Possible Solutions
(A) OnDestroy
is only called after OnDisable
, so that doesn't help. try
and catch
simply don't work.
(B) If there's no way to grab a value for beenDestroyed
we could remove it, which will bring up 3 lines of error per object:
(1) !IsDestroying()
UnityEngine.GameObject:set_active(Boolean)
TestOnDisable:OnDisable() (at Assets/TestOnDisable.cs:9)
Assert in file: Assets/TestOnDisable.cs: 9
(2) !gameObject.IsActive()
Assert in file: C:/BuildAgent/work/b0bcff80449a48aa/Runtime/Misc/GameObjectUtility.cpp at line: 853
(3) !m_IsActive
Assert in file: C:/BuildAgent/work/b0bcff80449a48aa/Runtime/BaseClasses/GameObject.cpp at line: 72
I could ignore the many, many lines due to many objects in scene. Because they don't really matter in this case. The function is pretty much just that. But that would make it very difficult to use/read the Debug Console otherwise and I fear they might actually have some negative effect.
(C) DontDestroyOnLoad
probably might be used instead. But it would increase complexity in the code. A lot. I hate using it.
(D) And, of course, I could try and modify so many scripts to prevent disabling these specific objects to begin with... But using it this way would make much more sense programatically while keeping all the scripts much cleaner!
Appeal
Pretty please, any ideas? :-)
I don't understand what you are trying to do. It is not possible to resurrect an object once it has been destroyed, because this will lead to unstable behaviors.
No he want to activate the gameobject when the script get deactivated, but not when it's destroyed.
Anyway, such a setup is just... well... crazy. I can't imagine any setup where the Gameobject is not active and when the script got disabled you need to activate the GameObject ...
If you just want to reactivate the Gameobject when it's beeing deactivated, why have you deactivate it in the first place? You should rethink your event-chain.
Thanks for the comments! You both are bringing points I've already discussed in the question, @Bunny83. That tells me it's still not clear enough... I edited it once again. Now I can only urge for people to read it carefully first, hoping I didn't do any more big mistakes there. :)
Answer by aldonaletto · Apr 05, 2012 at 05:29 PM
I would try another approach: create your own SetActive function, and avoid disabling those that satisfy some condition - with some special tag, or with a special script attached, etc. You could write a SetActive recursive function like this:
static function SetActive(obj: GameObject, onOff: boolean){ if (!obj.GetComponent(SpecialScript)){ // only affect objects without SpecialScript obj.active = onOff; // set passed object ative/inactive for (var trf: Transform in obj.transform){ // repeat for its children SetActive(trf.gameObject, onOff); } } }If you want to activate/deactivate the children independently of the parent, just move the for loop outside the if.
Obviously, you can change the condition to whatever you want - this was just an example.
Thanks so much! You didn't even need to post the code. I still dream to have a solution to the question, but this does solve my issue. ;) - by the way, your web site on your profile is missing a http://
Thanks for the warning - ou melhor dizendo, obrigado! Já corrigi o perfil (nem tinha me tocado que o http:// faria falta!)
$$anonymous$$ind I ask you, how you apply your knowledge of Unity3D on your pixtar company? I see nothing on the website and, from it, I could never guess you're so good with any kind of program$$anonymous$$g! :P
You're right, that site is really a weird choice to be posted in my profile, since it has nothing to do with Unity - but it was the less weird I had (see www.draldo.com.br - this one has even less to do with Unity, for sure).
Pixtar produces electronic horns, an invention of $$anonymous$$e (also known in other countries as "Tarzan horn" or "novelty horn" - see my interview in Jo Soares show: http://youtu.be/iClT1Cgv$$anonymous$$k$$anonymous$$ ).
$$anonymous$$y experience in Unity came from another project started two years ago, which includes game design and control of external hardware, a kind of simulator. We're negotiating this project with a big brazilian company, and hope to replace soon the site reference in my profile to a new one related to this project.
Answer by playsidepaul · Apr 04, 2017 at 04:37 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;
}