Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Question] Best way to add in a menu system

Discussion in 'Scripting' started by Timelog, Mar 5, 2015.

  1. Timelog

    Timelog

    Joined:
    Nov 22, 2014
    Posts:
    528
    Hey guys,

    Generally I try too figure out things myself, and don't ask for help fast, but in this case I'd like some input from the established forumers here :)

    I am currently refactoring a whole bunch of code for a game I am making, due to transitioning it to Unity 5 and streamlining the code (getting rid of public fields, adding properties where needed etc.), and I am planning on overhauling the menu system, as that is a big mess at the moment. However I have a question about that.

    Currently my main menu, level select menu and how to play menu are all separate scenes. And I have the pause menu as an overlay that gets activated and deactivated on the gameplay screen, so they are all there own little entity. I was watching a tutorial series from 3d Buzz the other day, where they show a menu system where one manager goes about activating and deactivating the different menus (apart from the pause menu) and all the screens are in the same scene.

    I am wondering what the best way is, to go about using and scripting menus. Is it better to just make each menu it's own scene, or is it better to use a manager system where the screens are all in one scene, and the manager handles activating and deactivating the scenes on demand?

    There are a few requirements:
    1. Out of each screen other then the main menu screen you need to be able to go to the main menu.
    2. From the pause screen you need to be able to go to both the main menu, and the level select screen.
    3. Preferably the Pause screen is part of the menu system, if that is a preferred method.

    To give an idea about what the menus will look like I have an image of the main menu here:


    For the level select the idea is that the background level changes depending on the button you hover over (level 1 button shows level 1, level 2 shows level 2 etc.), and the how to play menu shows a paged tutorial with two button and numbers at the bottom, and the current item in the center.
     
  2. knr_

    knr_

    Joined:
    Nov 17, 2012
    Posts:
    258
    Hi Timelog,

    Are you using the old Unity GUI system (coding in OnGUI()) or the new UI system?

    If you are using the new UI system it follows a different paradigm (obviously) - and I would highly suggest putting them all into one scene (and under one game object - that will allow you to create a prefab for your UI).

    Basically, in the new UI system all UI elements are game objects with certain components or child game objects that have components on them that make them into, say, a button, or a slider.

    Since they are game objects scripts can be added onto them. This is what we do and it works out great.

    My recommendation would be to create a new canvas (see the Create -> UI -> Canvas), then add all the front end elements there. Add the scripts to the UI elements (game objects) as necessary.

    An example of how we do it (imagine the following as a bunch of game objects in the Scene's hierarchy, this is not C# code, just formatted text):

    Code (CSharp):
    1. Game
    2.    - cvsHUD
    3.    - cvsMain
    4.       - pnlContainer
    5.          -pnlLeft
    6.             - pnlLeftTop
    7.             - pnlLeftMiddle
    8.       - pnlModalWindows
    9.          - pnlModalWindowCreateGame
    10.             - btnCancel
    11.             - btnCreateGame
    12.          - pnlModalWindowPlayerItems
    As you can see there is a panel (game object) called pnlModalWindows. By default this game object's active state is set to FALSE, along with all the modal windows under it so those game objects don't get rendered (which means their UI components on them don't get rendered).

    Essentially what we do is flip the active switches in the hierarchy as necessary so that we have all our UI nicely contained in one object, which allows us to make it a prefab and, if we have it in a Resources folder call Resources.Load("blah") from code to get it and then instantiate it - regardless of what scene you are in. :)

    Basically what you mentioned about the tutorial you viewed. :) I definitely think that is the way to go.

    Given the above example, what we would do is create a script (C#) called btnCreateGame and put that script on the btnCreateGame game object in the heirarchy above. Then, we would add an event handler for on click, to call a function on the btnCreateGame script that we just added to the game object. It keeps things neat and tidy.

    cvs = Canvas UI element
    pnl = Panel UI element
    btn = Button UI element

    etc... its just the naming convention that we use.

    This would work for your pause screen because, well, if you put the pause screen under the modal windows section of this hierarchy it would be treated in the manner you desire (the pnlModalWindows panel covers the entire screen and thus captures the input before anything else can, making the windows under it "modal" windows) while at the same time being a part of game object that contains all your UI.
     
    Last edited: Mar 6, 2015
  3. Timelog

    Timelog

    Joined:
    Nov 22, 2014
    Posts:
    528
    Thanks for the input :) I now have most of the menu working, just need to create a pause menu, and a menu for when the player finishes a level, but so far I have reduced the code by over 100 lines (of a total of ~350) so the new way is at least a lot smoother.
     
    knr_ likes this.