THE ROAD RUNNER TUTORIAL 8: CREATING A CUSTOM GUI

Check out the gameplay of the finished game below:



The Unity's default GUI is very austere, it really is. To our horrible fate, our background is white and so is the default unity GUI label's font.
In this post we will create a GUI skin and try to make it look a little better.

The first thing that you need to do is create a folder named Skins just for sake of neatness. In the folder which you just created, right click and Create->GUI Skin. Name it as, say, MySkin.

Once you click on this newly created skin you will have something like:


As you can see, the default font is Arial, which as per me is not that aesthetic. You can get different fonts from various  sites which offer free fonts. The font which I am using for this post can be downloaded at link.
Extract the font to your newly created Fonts folder in the Project panel, if you have not created the folder yet, then create one. You can simply drag and drop the extracted font to your folder.

Once done with this, replace the Arial font of MySkin with this newly downloaded font. I believe you will find many fonts, but use the first one which is named KOMIKAB_.

The next thing you need to do is change the font color of the label - Normal. A dark color would be good, change the color to the values (H: 16, S: 255, Y: 255, A: 255) 
You can change the font color by clicking on the Text color band.


Also, change the font size to 35.

Create a custom background for your box background, if you want to follow along, you can download the image below


 Import this image to any folder or create a folder named Textures and add it to this folder.
Add this image to the Box->Normal->Background


Change the font size of the Box to 30.

Change the text color of the button->Normal to the same color and also change the Font Size to 30.

Leave the rest as it is. Make sure that the Background's of the Button is none



You are done with creating a Custom GUI Skin. All we need to do now is to use this in our game.

To do this, we need to make few changes to the GameControlScript 
Create a new reference to the skin
public GUISkin skin;

And use this skin by adding the below line to the beginning of OnGUI function
GUI.skin=skin; //use the skin in game over menu

The complete GameControlScript will look like:

using UnityEngine;
using System.Collections;

public class GameControlScript : MonoBehaviour {
 
 public GUISkin skin;
 float timeRemaining = 10;
 float timeExtension = 3f;
 float timeDeduction = 2f;
 float totalTimeElapsed = 0;
 float score=0f;
 public bool isGameOver = false;

 void Start(){
  Time.timeScale = 1;  // set the time scale to 1, to start the game world. This is needed if you restart the game from the game over menu
 }

 void Update () { 
  if(isGameOver)
   return;

  totalTimeElapsed += Time.deltaTime;
  score = totalTimeElapsed*100;
  timeRemaining -= Time.deltaTime;
  if(timeRemaining <= 0){
   isGameOver = true;
  }
 }
 
 public void PowerupCollected()
 {
  timeRemaining += timeExtension;
 }
 
 public void AlcoholCollected()
 {
  timeRemaining -= timeDeduction;
 }

 void OnGUI()
 {
  GUI.skin=skin; //use the skin in game over menu
  //check if game is not over, if so, display the score and the time left
  if(!isGameOver)    
  {
   GUI.Label(new Rect(10, 10, Screen.width/5, Screen.height/6),"TIME LEFT: "+((int)timeRemaining).ToString());
   GUI.Label(new Rect(Screen.width-(Screen.width/6), 10, Screen.width/6, Screen.height/6), "SCORE: "+((int)score).ToString());
  }
  //if game over, display game over menu with score
  else
  {
   Time.timeScale = 0; //set the timescale to zero so as to stop the game world
   
   //display the final score
   GUI.Box(new Rect(Screen.width/4, Screen.height/4, Screen.width/2, Screen.height/2), "GAME OVER\nYOUR SCORE: "+(int)score);
   
   //restart the game on click
   if (GUI.Button(new Rect(Screen.width/4+10, Screen.height/4+Screen.height/10+10, Screen.width/2-20, Screen.height/10), "RESTART")){
    Application.LoadLevel(Application.loadedLevel);
   }
   
   //load the main menu, which as of now has not been created
   if (GUI.Button(new Rect(Screen.width/4+10, Screen.height/4+2*Screen.height/10+10, Screen.width/2-20, Screen.height/10), "MAIN MENU")){
    Application.LoadLevel(1);
   }
   
   //exit the game
   if (GUI.Button(new Rect(Screen.width/4+10, Screen.height/4+3*Screen.height/10+10, Screen.width/2-20, Screen.height/10), "EXIT GAME")){
    Application.Quit();
   }
  }
 }
}

There is one thing left to do, adding the skin to the reference. You can do this by dragging the custom skin to the Skin field of the GameControlScript in the inspector.



Now you are all set to test this. Press the play button or ctrl+P to test the game and you will have a better looking displays of the score and time left. 



The game over menu will look like



Download the completed version of this game from the Resources page.

The Road Runner Tutorial 1: Setting Up The World
The Road Runner Tutorial 2: Setting Up The World Continued
The Road Runner Tutorial 3: Adding A Character To Our Game
The Road Runner Tutorial 4: Set The Ground Moving
The Road Runner Tutorial 5: Adding Snags and Powerups to Our Game
The Road Runner Tutorial 6: Collecting The Snags and Powerups
The Road Runner Tutorial 7: Adding Gameplay Logic
The Road Runner Tutorial 9: Creating a Pause Menu
The Road Runner Tutorial 10: Adding Countdown and Main Menu
The Road Runner Tutorial 11: Adding Sound Effects To Our Game
The Road Runner Tutorial 12: Porting The Game To Android
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

15 comments:

  1. keep giving me error CS0101: The namespace `global::' already contains a definition for `GameControlScript'
    And

    error CS1525: Unexpected symbol `timescale', expecting `)', `,', `;', `[', or `='

    ReplyDelete
    Replies
    1. The 2nd error is due to the "\\" in line 52. I should have used "//" for commenting.
      The 1st error is perhaps due to the fact that you have the script of the same name already and you have created another script of the same name.

      Delete
    2. keeps giving me this Window tries to begin rendering while something else has not finished rendering! Either you have a recursive OnGUI rendering, or previous OnGUI did not clean up properly.
      And
      rc.right != m_GfxWindow->GetWidth() || rc.bottom != m_GfxWindow->GetHeight()

      Delete
    3. I've never come across such an error. I made a quick search on that,
      I'm hearing that it's a bug if unity 4.5. Could you upload a
      screenshot of the error? or maybe any explanations of the error wud
      help

      Delete
    4. hmm go to this webpage http://tinypic.com/view.php?pic=dfadxf&s=8#.U9sykajHf5w

      the other error u solved 2 errors but these came

      Delete
    5. This comment has been removed by the author.

      Delete
    6. im such retard i copied the codes to playercontrol instead of gamecontrolscript

      Delete
  2. in my GameControlScript i cant see

    shake_intensity shake_decay and Control

    ReplyDelete
    Replies
    1. Well, you don't need to see those, I had included some extra lines of code and took the screenshot then. Its normal that you don't see those in your project..

      Delete
  3. hi.. upon running.. it gives me this error message..

    MissingComponentException: There is no 'Renderer' attached to the "GameControl" game object, but a script is trying to access it.
    You probably need to add a Renderer to the game object "GameControl". Or your script needs to check if the component is attached before using it.
    GroundControl.Update () (at Assets/Scripts/GroundControl.cs:12)

    ReplyDelete
  4. Its Giving Me 19 errors What I do Please Help????

    ReplyDelete
  5. hi sujit horakeri..

    i would like to know , with custom gui, using myskin, there i setup the font size to be 20.
    the problem is, when using :

    GUI.Label(new Rect(Screen.width/4, Screen.height/4, Screen.width/2, Screen.height/2), "\n\nSpeed");

    the size of the font fix to 20 although i change the size of the screen. The position change because of Screen.height and screen .width..what about the font size..it not change size when i play around with the screen.. it makes the font normal in pc but bigger in android phone..thank you for your time..

    ReplyDelete