- Home /
Am I using OnEnable() correctly here?
I have read that OnEnable() should really only be used to initialize the GameObject itself, and to add listeners and such, but it shouldn't be used if you need to access other GameObjects or cache references to external components. With that said, Awake() and Start() only get called once, where OnEnable() gets called everytime the GameObject gets instantiated/created/enabled and such.
Here's my code below...I used OnEnable() to self-register this GameObject to a Managers GameObject, so it needs to happen whenever the GameObject becomes available, hence why it's in OnEnable(). Is this a bad use of OnEnable(), and if yes, can someone show me a better way of doing the same thing? Thanks guys!
public GameObject menuGameObject;
public GUITexture menuGUITexture;
public static bool isPauseOn = false;
void OnEnable( )
{
menuGameObject = menuGameObject != null ? menuGameObject : gameObject.FindChild( "menu", true ); // Just in case it wasn't setup already
menuGUITexture = menuGUITexture != null ? menuGUITexture : menuGameObject.GetComponent<GUITexture>(); // Same as above
Debug.Log("Self registering this GameObject now");
Managers.HUDManager.SetHUDElement( HUDSettings.HUDType.MENU, menuGameObject, HUDSettings.ShowMenuHUD );
}
Answer by Seth-Bergman · Nov 13, 2012 at 06:19 AM
maybe what you read was referring to the fact that OnEnable can't be a coroutine.. Or, that you shouldn't use OnEnable for caching objects which only need to be cached once.. For example, move these lines to function Awake():
menuGameObject = menuGameObject != null ? menuGameObject : gameObject.FindChild( "menu", true );
menuGUITexture = menuGUITexture != null ? menuGUITexture : menuGameObject.GetComponent<GUITexture>();
once you store these references the first time, why do you need to re-store them the next time you enable the script? Just call this once in Awake, and they are stored, no need to keep re-initializing the same thing...
NOTE: when you create a new instance of an object, the Start and Awake methods DO RUN. That is, in fact, precisely WHEN they run, when they are first created.
So, all you should have in OnEnable is the one line:
Managers.HUDManager.SetHUDElement( HUDSettings.HUDType.MENU, menuGameObject, HUDSettings.ShowMenuHUD );
this is perfectly acceptable
but you may also need a corresponding line in method "OnDisable", to unregister it..
of course, this is only necessary if you are DISABLING the script or object at some point, then re-enabling it.. if you are just trying to add the object when it is first INSTANTIATED, you have no need for OnEnable at all, Awake() would do it all..
Hey Seth, thanks for the quick answer! I didn't even think about the fact that those 2 lines would get re-cached every-time OnEnable() is called...thx for the tip, makes lots of sense :)
I am not disabling the script, but the GameObject itself, so the reference cached only gets unregistered in OnApplicationQuit(), so I guess you are right, I might not need OnEnable() after all...
if you are disabling/re-enabling the GameObject (i.e.: gameObject.enabled = false)
then OnEnable $$anonymous$$AY make sense.. it runs when BOTH (script AND GameObject) become true/enabled..
the question is, does the item in question NEED to be re-initialized.. should be easy enough to figure out either way through experimentation (if you're not sure), just see if moving the line under investigation into void Start() breaks stuff :)
Ah got ya, thanks for clearing that up.
After thinking about this a little bit, I figured that no, it doesn't need to be re-initialized every time, just on setup.
Thanks for the help Seth!
Your answer
Follow this Question
Related Questions
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
loading elements on startup 2 Answers
Interpreted Scripting 1 Answer
Setting Scroll View Width GUILayout 1 Answer
Best practice for assigning class reference at runtime? 0 Answers