UNITY3D: CREATING A DYNAMIC MAIN MENU

It's been some time that I posted a Unity3d Byte, and I thought it's high time to post one, so here's one very useful Byte where in we will learn how to create a screen size/resolution dependent or perhaps a Dynamic Unity GUI based Menu (I used the Unity GUI based Menu simply because, there are, obviously other ways to create a Menu)

To get started with this Byte, create a New Project and a New Scene, or perhaps just a new scene if you want to incorporate this into your existing game.
(Note that we won't make our menu look aesthetic as that is not the essence of this Byte)

Create a New Folder under the Assets folder and name it as Skins. Within this folder create a new Skin by right clicking on Skins->Create->GUI Skin and name it as whatever you like. I am naming mine as Skin.


Create a New Folder for our scripts as well and name it Scripts. Within this folder add a C# script by right clicking on Scripts->Create->C# Script and name it as MainMenuScript. Attach this script to the Main Camera.

Next we will add some code to this script. Double click on the script to open it.

First of all we will add some variables to our script


public GUISkin myskin;   //custom GUIskin reference
public string gameLevel; //level to open on clicking Play button
public string creditsLevel;  //level to load on click of Credits button    
float virtualWidth = 960.0f; //width of the device you're using
float virtualHeight = 540.0f; //height of the device
public float fontSize = 27; //preferred fontsize for this screen size
public int value = 20;  //factor value for changing fontsize if needed

In the Start function we will check if the screen size on which the game is being played is different from the one which it was designed for. If so, we will calculate the new font size for that particular screen size.

private void Start(){
 //check if the size on which game is being played is different
      if (virtualWidth != Screen.width || virtualHeight != Screen.height) {
       //set the new screen sizes if different
  virtualWidth = Screen.width;
            virtualHeight = Screen.height;
  //screen size dependent font size calculation
            fontSize = Mathf.Min(Screen.width, Screen.height) / value;
      }
}


In the OnGUI function, we will set the GUI skin to the new skin i.e., custom skin, which was created earlier. Further, we will set the font size of the Button and Box to the newly calculated value, if the screen size is different or the desired font size, if not.

Of course we will create the GUI box, buttons which the menu will be comprised of.

private void OnGUI()
{
 GUI.skin=myskin;   //use the custom GUISkin
      myskin.button.fontSize = (int)fontSize; //set the fontsize of the button 
 myskin.box.fontSize = (int)fontSize; //set the font size of box
 
 //create a menu
 GUI.Box(new Rect(Screen.width/8, 10, 3*Screen.width/4, 3*Screen.height/4), "MAIN MENU"); //a box to hold all the buttons
                
      if (GUI.Button(new Rect(Screen.width/8, Screen.height/8+10, 3*Screen.width/4, Screen.height/8), "PLAY")){
                        Application.LoadLevel(gameLevel); //open the game scene
                }
                
      if (GUI.Button(new Rect(Screen.width/8, 2*Screen.height/8+10, 3*Screen.width/4, Screen.height/8), "CREDITS")){
                        Application.LoadLevel(optionsLevel); // open the credits scene
                }
                
      if (GUI.Button(new Rect(Screen.width/8, 3*Screen.height/8+10, 3*Screen.width/4, Screen.height/8), "EXIT")){
                        Application.Quit(); // exit the game
                }
        }

After we have assigned the new font size, we have written some code which creates a GUI Box which is basically what it means, a box which contains some GUI elements inside it. In our case, Buttons.

If you see this line of code,

GUI.Box(new Rect(Screen.width/8, 10, 3*Screen.width/4, 3*Screen.height/4), "MAIN MENU");

we have created a new Rect object with starting point as Screen.width/8 and 10 units from the top left. Screen.width/8 is the horizontal distance from the left of the screen and 10 is the vertical distance from the top.

The next two parameters, 3*Screen.width/4 and 3*Screen.height/4, are the width and height of the box respectively.
By using the Screen.width and Screen.height, instead of numbers, we are making the size and positions dependent on the Screen size, so as to make it dynamic or Screen Size dependent.

The last parameter, "MAIN MENU", is the heading of this box.

The parameters of the GUI Buttons are made screen size dependent by following the same procedure mentioned above.

The complete MainMenuScript will look something like:

using UnityEngine;
using System.Collections;

public class MainMenuScript : MonoBehaviour 
{

      public GUISkin myskin;   //custom GUIskin reference
      public string gameLevel; //level to open on clicking Play button
      public string creditsLevel;  //level to load on click of Credits button    
      float virtualWidth = 960.0f; //width of the device you're using
      float virtualHeight = 540.0f; //height of the device
      public float fontSize = 27; //preferred fontsize for this screen size
      public int value = 20;  //factor value for changing fontsize if needed

      private void Start(){
   //check if the size on which game is being played is different
          if (virtualWidth != Screen.width || virtualHeight != Screen.height) {
         //set the new screen sizes if different
          virtualWidth = Screen.width;
                 virtualHeight = Screen.height;
   //screen size dependent font size calculation
                 fontSize = Mathf.Min(Screen.width, Screen.height) / value;
      }

      private void OnGUI()
      {
   GUI.skin=myskin;   //use the custom GUISkin
          myskin.button.fontSize = (int)fontSize; //set the fontsize of the button 
   myskin.box.fontSize = (int)fontSize; //set the font size of box
 
   //create a menu
   GUI.Box(new Rect(Screen.width/8, 10, 3*Screen.width/4, 3*Screen.height/4), "MAIN MENU"); //a box to hold all the buttons
                
          if (GUI.Button(new Rect(Screen.width/8, Screen.height/8+10, 3*Screen.width/4, Screen.height/8), "PLAY")){
                        Application.LoadLevel(gameLevel); //open the game scene
          }
                
          if (GUI.Button(new Rect(Screen.width/8, 2*Screen.height/8+10, 3*Screen.width/4, Screen.height/8), "CREDITS")){
                        Application.LoadLevel(optionsLevel); // open the credits scene
          }
                
          if (GUI.Button(new Rect(Screen.width/8, 3*Screen.height/8+10, 3*Screen.width/4, Screen.height/8), "EXIT")){
                        Application.Quit(); // exit the game
          }
        }

}

}

You need to fill some values expected by the script in the Inspector of the Main Camera. Once you add the values expected, your Main Camera Inspector will look something like:



It's time to test our dynamic Main Menu then, click on the Play button or press ctrl+P on windows or cmd+P on the mac to test this beast.

Try changing the Game aspect from Free Aspect to to other values and see the dynamic Main Menu in action.

Free Aspect Main Menu

WVGA Portrait(480x800) Main Menu

See you around.
Share on Google+

About Sujit Horakeri

Sujit Horakeri is a game freak just like any other next door guy you would come across. He is a Web Developer by Profession, Game Developer by Choice.
Connect with him on:
    Blogger
    Facebook

0 comments:

Post a Comment