Friday, April 10, 2015

Unity Learnings on 5.x uGUI changes.

Recently I picked up a set of Unity tutorials via one of Joystiq's bargain offer packs.  My plan was to use the Easter break to power through and get as much of the new Unity under my belt as I could to see if with Unity 5.x it was now something I could use in my games.  The first tut I started was "Learn to Build Mobile Games Using Unity3D".

I quickly ran into the issue that there were a number of minor and irritating differences between 5.x and the tutorial materials for the  - I don't blame the Udemy tutorial folks for this.  As soon as you make a tutorial its out of date, and good material always has value even if a couple of the specifics have changed.

So, here in this blog post I'm going to cover what I have learned out of this exercise.  I figure this will be useful for folks who are looking to understand uGUI, or for those trying to see what has changed since the early 4.x days, or even just those interested in Unity.

My goal was to finish the tutorial - feature for feature - and to figure out for myself how to do the things that were different.  Specifically this meant understanding how to get the two text labels at the top of this single screen game working properly.

This is the Goal - Make These Labels Work

The first step is to add in two Text labels to the scene, using the right-click menu in the project view, and selecting Text from the UI menu.

Adding a UI Text Label

Do this twice and you'll have two text label.  Once they're in the scene name them appropriately so you can later distinguish which is which.  I've called mine Score Label and Ball Count Label.

UI Text Elements in Project View after Naming

Once you're done adding your project view will look like this, and notice that for free, you got a Canvas element which is the parent of both labels.  You can leave the Canvas element as it is for now - its basically a holder that shims between the 2D world of the GUI system and the 3D world of the game.

If you check out your game view now you'll notice something else weird - or maybe you will, it depends on the screen to pixels for your game.  What I have is a very large Canvas element depicted by the rectangle going off up to the right of the game scene.  If I zoom aallll the way out so I can see the whole of that rectangle, my game scene is a tiny thing in the bottom left corner.

Huge Canvas and Tiny Game!

Basically what's going on - and Unity may have fixed this by the time you read this, or your screen resolution may mean you don't have this issue - is that because the default Canvas is an overlay it's sizing translates to hundreds of units wide by high, where as your scene is probably one's and two's in size.  How to get around this?  The easiest way is to change your Unity editor window setup so that  your Game view is visible at the same time as the Scene view.  Just drag the tab with your Game view in it to some place in the layout where you can have it open easily.  I put mine side by side with the Assets window that doesn't get used all that much.

Now you can go ahead and use the Game view to see what is happening with your UI, and the Scene view continues to show the game layout of objects.  If you zoomed out to see the Canvas, zoom back in to your game play and just try to ignore the funny Canvas rectangle.

To handle updating the score and ball count values on my labels I just made two very simple MonoBehaviour scripts in C#.  This is the ScoreLabelController.cs script, just simply added to the Assets folder:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class ScoreLabelController : MonoBehaviour
{
 Text scoreLabel;

 public ScoreKeeper scoreKeeper;

 // Use this for initialization
 void Start ()
 {
  scoreLabel = GetComponent();
 }
 
 // Update is called once per frame
 void Update ()
 {
  int score = scoreKeeper.CurrentScoreValue;
  scoreLabel.text = "Score: " + score.ToString();
 }
}

And this is the BallCountLabelController.cs script, again created by right-click in the Assets folder:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class BallCountLabelController : MonoBehaviour
{
 Text ballCountLabel;
 public BallSpawnController ballSpawnController;

 // Use this for initialization
 void Start ()
 {
  ballCountLabel = GetComponent();
 }
 
 // Update is called once per frame
 void Update ()
 {
  int ballCount = ballSpawnController.ballCount;
  ballCountLabel.text = ballCount.ToString();
 }
}

Note that you need to include the extra using statement to get access to the Unity UI API.

Now you have a Unity editor setup that is sane, and some scripts to drive them its possible to go ahead and hook up your labels.  Its good to have a nice font for them.  Luckily I had earlier been working through Kirill Muzykov's excellent Unity GUI Tutorial on Ray Wenderlich's site and picked up a couple of fonts made available there.  The font in the image above is the Titan-One-Regular font.

Also I wanted to follow the tutorial and pick up the orange color from one of the assets, so I selected it and added the colour as a preset.

Getting a Color from a Pre-fab to use as a Preset
Here's the process for setting up the Ball Count label with the font and colour.

If you've come here without having done the Udemy course, a little background: the game is about spawning balls that fall down, and you have a limited supply of balls.  The game object that spawns the balls is just a Quad with a texture in 3D space that has the words "Touch Here".  On that Quad is a script called BallSpawnControlller, which has the value of the number of balls I wanted to display.

In Unity if you have a slot available for a script object and you drop a game object in there, like the Quad above, Unity is clever enough to find the script off the dropped object.

  First you'll need to position it correctly.  As the Canvas corresponds to the screen of the device that the game will run on - it can obviously change!!  It will depend on who is playing your game and what device they have, so you want to position it relative to the screen - not in absolutes.

1) So choose as I did here the top-left anchor preset to position it relative to the top left corner.

Setting up the Ball Count Label
2) Now you can change the X and Y values to get the label positioned right, by looking at the Game window.

3) If you have a nice font to drop into your assets, select it here.

4) Select the color you want to use for the label.  Here I chose my preset.

5) Drag-n-drop the BallCountLabelController scripts from the Assets folder onto the labels inspector window to add it, and then drag the object hosting the ball count script class into the slot, so as to get access to it at run-time.

The process is similar for the other label which handles the game score.

Setting up the Score Label
1) Again setup the anchors by choosing a preset.

2) Set up your X and Y rect positioning.

3) Finally drop in the game object to allow your label controller script to access the game data it needs to display.

OK, well that's it - hope its helpful!