So, I'm currently learning both about Unity for the first time as well as the 'new' 2D UI system, but I'm having a hard time figuring out how to make windows, modals/dialogs, main menus etc. which are not only functioning, but also modular, reusable and written following proper coding standards. Most how to's, blogs, Q&As or tutorials I find only cover the most basic parts of UI development (e.g. how to drag a button from the toolbar to the scene window in 2 hours).
So basically, I'd like to have a main menu which meets those (very common) requirements:
- A button which 'starts' the game (e.g. by simply loading another scene)
- A button which 'quits' the game, but also opens up a confirmation dialog before
- A button which opens up an options dialog, which again is composed of multiple parts (audio, video...)
- and finally, it should be possible to go back to the previous screen using a 'back key/button', for example
Escape
What I started with is a canvas which I called GameMenu
. This canvas has several nested canvases, such as
- MainMenu
- OptionsMenu
- OptionsMenuAudioPart
- OptionsMenuVideoPart
- CancelMenuModal
Then I created a menu script which works as some sort of state machine:
public class MenuScript : MonoBehavior {
private GameObject _currentStateObject;
private GameObject _previousStateObject;
public void SetState(GameObject newStateObject) {
if(newStateObject == null || newStateObject)
return;
if(CurrentStateObject != null)
CurrentStateObject.SetActive(false);
_previousStateObject = _currentStateObject;
CurrentStateObject = newStateObject;
CurrentStateObject.SetActive(true);
}
}
Every button has now an event trigger attached which calls the SetState(...)
method on MenuScript
.
However, I've got the following problems:
- How do I pass multiple parameters to methods invoked by event triggers? As soon as I add another parameter to
SetState(...)
, for examplebool isModal = false
to tell the method that it shouldn't disable the previous state, then it disappears from the event trigger action selection menu. - How to I register key press events within the event triggers? It's easy by script (
Input.GetKey(...)
etc.), but I didn't find one on the event type selection. - How do I make e.g. event triggers conditionally? So that certain events cannot be called when certain states are active?
I know I can solve all those problems within the script and make a fully functional main menu which does exactly what I want, but then...
- I cannot use it for something else
- I don't use the new Unity UI system, which makes me wonder what's the purpose of it
- I got to reference all involed game objects (the canvases, buttons etc.) in script, which makes it not really 'extendable' anymore as this means for every changed requirement, I have to alter the script (e.g. a new state, menu, button etc)
The main goal in the end is a script which I can use for all kinds of UIs without writing the same logic over and over again just because it's another scene, game state etc.