How to deactivate an NGUI panel, but not hiding it.

I am trying to deactivate/activate a panel but keep it visible. All in NGUI.
So basically I have a pop up menu that appears in from of the main menu. The pop-up menu has it’s own buttons that have to be active, and I don’t want them to interfere with the main menu buttons, which have to remain visible but inactive.

I can go and iterate trough all the buttons in the panel and set them inactive, but I can have other elements in the main menu like scroll bars, sliders etc. So is there an universal way of setting the entire panel active/inactive but still leaving it visible?

There’s a couple of ways to do it:

  1. If you want any widget in NGUI to
    stop reacting to events, just take
    out that widget’s collider.
  2. If your buttons have a UIButton
    script attached to them, you can use
    the isEnabled property which
    enables/disables the button (by
    enabling/disabling the collider, and
    updating the button’s color
    accordingly)
  3. You can use a boolean acceptInput
    in your panel (or main menu or
    whatever) - when you’re handling
    your main menu button events (or any
    thing that you want to make inactve)
    check to make sure acceptInput is
    true. When you show up the
    popuplist, you set acceptInput to
    false.

Going with the first option (for example) you could make a function that would deactivate everything in your panel, except for one thing (in this case your popup list). Something like (just an idea, I don’t know about your setup):

void ActivateAllExcept(bool activate, string _except)
{
   // this will get you all the colliders of all widgets under your panel - recursively
   var colliders = myPanel.GetComponentsInChildren<Collider>();
   foreach (var col in colliders)
      if (col.gameObject.name != _except) // for this to work, names should be unique. I just used the name as an example, use whatever unique identifier you want...
           col.enabled = activate;
}

In your case you would pass in false to activate.

By the way somebody (a user named Carsten`) in the Unity chat room gave me another solution. Placing a collider on top of the others that I want to block, so basically the entire screen, under the window that I want to keep active. I though maybe it will help somebody who is looking for a solution of a simllar problem.

I’m currently working with Unity 4.3 and NGUI 3.0.5, and put the collider in top of other colliders stopped to work for me. I’m not sure what has changed from previous versions. The collider blocks the colliders behind but also the buttons on top of the pop up collider stopped to work as well.

Updating @vexe’s answer, I created an extension method to accomplish this.
Just put the following snippet anywhere in your project, and it will extend the GameObject class to include an ‘EnableColliders()’ method available to all GameObjects.

I didn’t see where Symyon mentioned he wanted some controls still enabled, so I removed that option. His pop-up menu is a different NGUI panel I assume (like my situation, I wanted a ‘pause’ menu displayed over my game when the user clicks a button, with options like ‘Resume’ and ‘Exit’, but my other game inputs kept firing also.)

public static class ExtensionMethods {
	public static void EnableColliders(this GameObject go, bool state) {
		foreach (var collider in go.GetComponentsInChildren<Collider>()) {
			collider.enabled = state;
		}
	}
}

In my menu code (using my custom State Machine), I enable / disable input for GameObject ‘uiHud’ like this:

public void StateLostFocus() {
	GuiManager.uiHud.EnableColliders(false);
}

public void StateGainFocus() {
	GuiManager.uiHud.EnableColliders(true);
}