Search Unity

Friday Treat - GUI Menu System (C#)

Discussion in 'Scripting' started by codepunk, May 2, 2009.

  1. codepunk

    codepunk

    Joined:
    Dec 10, 2008
    Posts:
    68
    I've read and taken some scripts here and there so I thought that since I'm in a good mood today, I'd give something back. The behavior below is a real simple menu system for Unity (I use it for my iPhone project).

    The system is based around delegates in C#. Simply put, I have a single delegate defined which gets called by my OnGUI method. By simply assigning different methods to that delegate, I can easily switch menus on the fly without any if statements, loading new levels or whatever else people do.

    Code (csharp):
    1. private delegate void GUIMethod();
    2. private GUIMethod currentGUIMethod;
    You can see where I first define the delegate. Any methods that you define must therefore match that signature. I then create a member variable of that delegate type. My OnGUI method is simply:
    Code (csharp):
    1. public void OnGUI ()
    2. {
    3.     this.currentGUIMethod();
    4. }
    Here's the full code. Note that I don't have all the pieces in but those missing pieces are not essential to this.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class MainMenu : MonoBehaviour
    5. {
    6.     public GUISkin guiSkin;
    7.  
    8.     private delegate void GUIMethod();
    9.     private GUIMethod currentGUIMethod;
    10.    
    11.     // Use this for initialization
    12.     void Start ()
    13.     {
    14.         this.currentGUIMethod = MainMenuGUI;
    15.     }
    16.    
    17.     public void MainMenuGUI()
    18.     {
    19.         GUI.skin = this.guiSkin;
    20.        
    21.         GUI.BeginGroup (new Rect (80, 70, Screen.width - 200, Screen.height - 80));
    22.         {
    23.             GUI.Box (new Rect (0,0,Screen.width - 200,Screen.height - 80), "SuperBall Factory", GUI.skin.GetStyle("box"));
    24.            
    25.             // First button
    26.             if (GUI.Button (new Rect (10,25,Screen.width - 220,40), "New Story", GUI.skin.GetStyle("button")))
    27.             {
    28.                 Application.LoadLevel ("Sort");
    29.             }
    30.            
    31.             if (GUI.Button (new Rect (10,75,Screen.width - 220,40), "Free Play", GUI.skin.GetStyle("button")))
    32.             {
    33.                 // go to next menu
    34.                 this.currentGUIMethod = FreeplayMenuGUI;
    35.             }            
    36.         }
    37.         GUI.EndGroup();
    38.     }
    39.    
    40.     public void FreeplayMenuGUI()
    41.     {
    42.         GUI.skin = this.guiSkin;
    43.        
    44.         GUI.BeginGroup (new Rect (80, 70, Screen.width - 200, Screen.height - 80));
    45.         {
    46.         GUI.Box (new Rect (0,0,Screen.width - 200,Screen.height - 80), "SuperBall Factory", GUI.skin.GetStyle("box"));
    47.            
    48.             if (GUI.Button (new Rect (10,25,Screen.width - 220,40), "Superball Sorter", GUI.skin.GetStyle("button")))
    49.             {
    50.                 Application.LoadLevel ("Sort");
    51.             }
    52.            
    53.             if (GUI.Button (new Rect (10,75,Screen.width - 220,40), "Superball Saver", GUI.skin.GetStyle("button")))
    54.             {
    55.                 Application.LoadLevel ("Deflect");
    56.             }
    57.            
    58.             if (GUI.Button (new Rect (10,125,Screen.width - 220,40), "Superball Catcher", GUI.skin.GetStyle("button")))
    59.             {
    60.                 Application.LoadLevel ("CatchBox");
    61.             }
    62.         }
    63.         GUI.EndGroup();
    64.     }
    65.    
    66.     // Update is called once per frame
    67.     public void OnGUI ()
    68.     {
    69.         this.currentGUIMethod();
    70.     }
    71. }
    72.  
    If anyone thinks this is wiki worthy, I'll throw it up there (haven't checked to see if there is anything else similar.
     
  2. codepunk

    codepunk

    Joined:
    Dec 10, 2008
    Posts:
    68
    I should also note, this is a pretty game specific menu (my game that is) behavior. It really should be made more generic. I just wanted to demonstrate the delegate behavior.

    I also have another system that I'll post soon but its much more complicated. It consists of instantiating dynamic C# objects based on a text file coupled with a sequential set of something I've been calling Actions thereby doing something like a script language within a script language.
     
  3. KITT

    KITT

    Joined:
    Jul 17, 2009
    Posts:
    221
    Thanks for that , very helpful indeed.
     
  4. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Definately put it up on the wiki with some simple instructions as to what gameobject to add the script to, etc. This way it doesn't disappear into the anals of thread history like so many things do.
     
  5. codepunk

    codepunk

    Joined:
    Dec 10, 2008
    Posts:
    68
  6. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Awesome job and I know people will truely appreciate it.
     
  7. bobber205

    bobber205

    Joined:
    May 12, 2009
    Posts:
    139
    This is an excellent use of delegates. Exactly what they were designed for! :)
     
  8. diabloroxx

    diabloroxx

    Joined:
    Jan 20, 2010
    Posts:
    71
    Nice way to handle the UI. Need to get rid of the 1000 bool variables and the if-else conditions I now have in my game.
     
  9. simone007

    simone007

    Joined:
    Oct 30, 2008
    Posts:
    221
    Very nice implementation, thank you for sharing
     
  10. kookyoo

    kookyoo

    Joined:
    Apr 19, 2010
    Posts:
    53
    Old post but very nice explanation. Thanks a lot !