Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Switching between menus under one or more conditions

Discussion in 'UGUI & TextMesh Pro' started by Nanity, Sep 14, 2014.

  1. Nanity

    Nanity

    Joined:
    Jul 6, 2012
    Posts:
    148
    In this specific case I can't use the OnClick() delegate of the button UI, because I have to check for a condition if the menu is allowed to be changed. So i have to call the functions from code:

    Code (csharp):
    1. public void changeMenu ()
    2. {
    3.   if (isMenuAllowedToChange())
    4.   {
    5.     GameObject.Find("Menu_1").SetActive(false);
    6.     GameObject.Find("Menu_2").SetActive(true);
    7.   }
    8. }
    This would be awesome beside this this is not possible, inactive GameObjects can't be found with GameObject.Find(). Therefor I will never be able to activate it without caching a reference:

    http://feedback.unity3d.com/suggestions/gameobjectfind-methods-should-

    But I do not have two menus, there are plenty more. I dont want to clutter my class header with public references to cache every single menu I want to access by code. Same goes UI elements...

    Is there any alternative to this:
    Code (csharp):
    1. public class GuiManager
    2. {
    3.   public RectTransform menu_1;
    4.   public RectTransform menu_2;
    5.   public RectTransform menu_3;
    6.   ...
    7.  
    Thanks for your help in advance, haven't been able so solve this in two weeks now :/
     
  2. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,181
    It makes sense for you UI manager to know about which UI screens are available and orchestrate the control IMO. Using GameObject.Find is very slow and not recommended.
     
  3. TroyDavis

    TroyDavis

    Joined:
    Mar 27, 2013
    Posts:
    78
    I usually create public GameObjects and then drag the menu Canvas or panel to the Variable in the editor window save a prefab and no need to use GameObject.Find.
     
  4. Aishiteru

    Aishiteru

    Joined:
    May 3, 2014
    Posts:
    31
    If you want to use the first approach I suggest adding your Menu items into a dictionary at the Awake()

    Code (csharp):
    1.  
    2. void Awake()
    3. {
    4.     menuObjects["Main menu"] = GameObject.Find("Main menu");
    5.     ...
    6. }
    7.  
    8.  
    this is much faster and efficient than using GameObject.Find

    Code (csharp):
    1.  
    2. DisableAllMenu();
    3. menuObjects["Main menu"].SetActive(true);
    4.  
     
  5. Nanity

    Nanity

    Joined:
    Jul 6, 2012
    Posts:
    148
    I'd only use GameObject.Find() to find the reference because I'm no fan of dragging and dropping all elements in the inspector. Guess I'll use a helper class to store the references, so the main ui manager doesn't get cluttered.

    From a programming perspective, I want to keep the references totally hidden in the inspector as suggested by the principles of single responsiblity, encapsulation and information hiding. I currently use the "SERIALIZABLE" attribute to keep the properties private at least.

    Had that already and I can not recommend. You have to activate all ui elements in the scene before pressing Play, so everytime you want to edit a single menu, you end up deactivating all menus to view it and then reactivating them afterwards.

    Furthermore you have to pay attention at DisableAllMenu(), this will cause serious issues with toggle groups as the first one has to be activated by default in order to be displayed.
     
  6. Aishiteru

    Aishiteru

    Joined:
    May 3, 2014
    Posts:
    31
    oh yeah, I used the drag and drop method so i don't have that issue.