Author Topic: Ordering SetActive  (Read 3990 times)

m3taphysics

  • Guest
Ordering SetActive
« on: September 30, 2012, 04:40:12 PM »
I have a panel which I want to select which elements to have enabled/disabled on startup. To detect this on the panel I have a script which checks "OnEnable", this then uses

   void OnEnable() {
      Debug.Log("Score Submission Controller - On Enable");
      NGUITools.SetActive(submitButton, true);
      NGUITools.SetActive(replayButton, false);
   }

Everything unfortunately gets enabled. Im assuming the order of this isnt AFTER everything else.

In the past I have used coroutines and delayed things by a number of frames. TO ensure its disabled AFTER everything else has been enabled.

I was wondering if there is a better method to manage what should be active (or not)

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Ordering SetActive
« Reply #1 on: September 30, 2012, 06:55:08 PM »
Startup = Awake(), not OnEnable(). Start() is another good candidate.

m3taphysics

  • Guest
Re: Ordering SetActive
« Reply #2 on: October 01, 2012, 01:05:17 PM »
No those functions are only called once in a lifetime of a script. It could be re-enabled multiple times with different parameters deciding what is enabled or disabled.

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: Ordering SetActive
« Reply #3 on: October 01, 2012, 02:45:42 PM »
It's a tricky thing. If you're inside an OnEnable, it means that the gameobject has just been made active. And this means, that if it has been made active by NGUITools.SetActive, it's children will be set active AFTER you finish that OnEnable. This means, if you mess with the children of this object's active state, it will get overridden afterwards when the "big" OnEnable gets to traverse the rest of the hierarchy.

One way to get around it is to use SetActiveRecursively which starts by enabling children.

Another is to set some bools instead, and mess with the active state in Update()

You suggested Coroutines which can also be used.

You can also use Invoke with a tiny timedelay, although that feels dirty.

Alternatively, you can just use myPanel.gameObject.active = true and let the panel have a script with OnEnable that sets everything up for you with references to children and whatnot.

JRoch

  • Full Member
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 140
    • View Profile
Re: Ordering SetActive
« Reply #4 on: October 01, 2012, 03:08:38 PM »
I use Awake() to capture the instances of gameobjects to variables, and then use Start() to do SetActive functions.  That way you're sure that any given object hierarchy has handles (variables) you can use prior to being disabled.

m3taphysics

  • Guest
Re: Ordering SetActive
« Reply #5 on: October 01, 2012, 04:20:44 PM »
FYI this method seems okay, whenever you need something to happen last. Delay it by 1 frame.

  1.         public void DelaySetActive(GameObject go, bool tf, int delay = 1)
  2.         {
  3.                 StartCoroutine(_DelaySetActive(go,tf,delay));
  4.         }
  5.        
  6.         public IEnumerator _DelaySetActive(GameObject go, bool tf, int delay)
  7.         {
  8.                 for(int i = 0; i < delay; i++)
  9.                 {
  10.                         yield return 0;
  11.                 }
  12.                        
  13.                 NGUITools.SetActive(go, tf);
  14.         }