Hey everyone! I’m not sure if this tutorial will be helpful to anyone (and I probably did a million things wrong) but I couldn’t find a tutorial like this already made. Hopefully it will help at least some of you in one way or another!
In this tutorial I’ll be walking you through the steps of creating your very own custom GUI/menu elements for use in Unity3D.
Before we get started, here are the things you will need to follow along:
Photoshop/Paint.NET/Gimp/Other image editing software
Unity3D
Creativity
A quick introduction into Unity GUI Skins
GUI stands for Graphical User Interface. Think healthbars, score, maps etc.
When writing GUI scripts for Unity3D, the default skin is used unless told otherwise. The default skin looks like this:
The cool thing is that you can make all the elements look completely custom! To do that you will need to create a NEW GUISkin.
Creating a New GUISkin
To create a new GUISkin it’s quite simple. All you have to do is go to either the Assets Menu:
OR the project tab:
Click “GUISkin” and you will see a new icon in your project tab called “New GUISkin”.
Rename it accordibg to it’s purpose. For example, I will rename mine to “Menu GUISkin”
So let’s move on to actually creating the images that will be used for our GUI skin!
First let’s create a Folder To Hold our GUISkin Images
This is pretty straightforward. I named my one “Menu GUISkin Resources”
I would also recommend creating another folder called “GUI Components” and placing EVERYTHING to do with your GUI inside that. Just for organisation purposes!!
Now Let’s take a Look at our GUISkin
Clicking on our Menu GUISkin will display this in the inspector window:
(Ignore the Fonts folder and GUITestScript for now!)
These are all the components that make up a GUISkin in Unity. You have options for all the elements such as buttons, boxes, labels and scroll bars!
If you expand any element, you will see a whole heap of options which you can change. However, there is no point in us changing it right now because we don’t actually have anything setup to preview it!
I wrote out a code that you can simply copy paste into a new JavaScript:
var MenuSkin : GUISkin;
var toggleTxt : boolean;
var toolbarInt : int = 0;
var toolbarStrings : String[] = ["Toolbar1", "Toolbar2", "Toolbar3"];
var selGridInt : int = 0;
var selStrings : String[] = ["Grid 1", "Grid 2", "Grid 3", "Grid 4"];
var hSliderValue : float = 0.0;
var hSbarValue : float;
function OnGUI() {
GUI.skin = MenuSkin;
GUI.BeginGroup(new Rect(Screen.width/2-150,Screen.height/2-150,300,300));
GUI.Box(Rect(0,0,300,300),"This is the title of a box");
GUI.Button(Rect(0,25,100,20),"I am a button");
GUI.Label (Rect (0, 50, 100, 20), "I'm a Label!");
toggleTxt = GUI.Toggle(Rect(0, 75, 200, 30), toggleTxt, "I am a Toggle button");
toolbarInt = GUI.Toolbar (Rect (0, 110, 250, 25), toolbarInt, toolbarStrings);
selGridInt = GUI.SelectionGrid (Rect (0, 160, 200, 40), selGridInt, selStrings, 2);
hSliderValue = GUI.HorizontalSlider (Rect (0, 210, 100, 30), hSliderValue, 0.0, 1.0);
hSbarValue = GUI.HorizontalScrollbar (Rect (0, 230, 100, 30), hSbarValue, 1.0, 0.0, 10.0);
GUI.EndGroup ();
}
And seriously, unless you are familiar with GUIScripting, just ignore trying to figure out that code for now! I will be writing a GUIScript tutorial in the future to help with that
Ok so attach the new javascript to your MainCamera, and drag the Menu GUISkin into the MenuGUISkin variable of the Main Camera.
Click play now and you’ll see that the skin is the same as the default skin right now. Obviously we don’t want that so, starting from the top we’ll create our very own GUISkin!
Font
This is the global font for the entire Skin. Each component has their own font element as well, but if the majority of your skin uses a particular theme, it is best to set the Font up top as that Font! The individual Font options will override the global one. Think of it this way, if the button/box/etc has not got an individually defined font, then use the globaly defined font. If it has an individually defined font, use that font for this element.
Importing fonts is pretty straightforward! You just need to put in any .ttf OR .otf formatted fonts into your project tab in Unity!
You can actually drag these straight from your fonts file of your computer:
And now you can click the little circle with a dot next to Font in the GUISkin and assign any font you want!
To quickly preview these fonts, you can actually press PLAY for the game and as you change fonts it will update in the game view! Handy right?
So that’s how you change the font that the Skin uses, but what if your font is too big? Or you want it italicised, or bold?
Well you may have noticed already, but when you imported your font, it actually came in with adjustable properties which you can access by simply clicking on the font and looking in the inspector window:
More information about fonts here!
Ok so moving on we’ll be having a look at boxes, and we’ll actually be using PhotoShop to create our own here!
Boxes
You’re going to want to pull PhotoShop or similar(Paint.NET, Gimp etc) out for this part!
Ok so let’s have a look at our box component:
It has many different dropdowns, but don’t be daunted! They’re mainly for the different states of the box and you actually are not required to create an image for each one.
For example, normal refers to the state of the box when nothing is happening to it. It hasn’t been pressed, the mouse isn’t over it and it’s simply in a state of normality.
Let’s create a box background image for it’s normal state first!
Ok so a good way to go about this is the live update method:
- Open up Photoshop
- Create new image
- Save as BoxNormal into the “Menu GUISkin Resorces” folder we previously made
- Click the dropdown arrow for Normal under the box category and assign your newly saved image to it’s background texture
- Put photoshop on half the screen, and unity on the other
- Push “Maximise on play” and PLAY on Unity
- Start drawing your background on PhotoShop
Your setup should look similar to this:
Now what you need to do to see how it looks on Unity is save, then click the unity window. This way you can quickly check out how it’s going to look on unity!
For the box example Im going to create a basic box style.
After drawing out a nice border for my box I ran into the first issue:
What the heck is going on? Unity is drawing out the inside fuzzy!
Well you see, Unity stretches the inside out so as the size of a box is dynamic. A good texture will be drawn so as it works at any size. This doesn’t mean we can’t have borders though! It simply means we have to tell unity that there is a border in our texture. We also have to tell Unity how many pixels the border is. To do that you go here:
I measured my border distance to be 7 pixels from each side. Putting in a couple more pixels gave the desired result.
have a look at the fixed side compared to the non fixed sides:
Here I set the left border and top border to 9.
Looks a lot better right?
But hang on! If Unity stretches the texture, why have we drawn such a big texture? It’s pointless and will only increase loading times even if ever so slightly. A better way to draw this would be:
Another good thing about making the texture smaller is that now I can input the border size of 7pixels and it will be fine. I acyually don’t know why this is admittedly
What we can now do is fill in the middle of the texture and even between the border lines to give us a solid style:
I used random colours here just so you can clearly see what affects what.
Alright so say we want somewhere to place our box title. How would we do that?
It’s actually pretty straightforward. You just increase the height of your texture and input the new border distance from the top:
Messing around in PhotoShop and with the Unity settings you’ll be able to come up with all sorts of results!
For this style, what I did was I made the centre transparent. To do this I just created the middle section on a different PhotoShop layer and adjusted it’s opacity value.
I also used layer styles to bevel my box in certain places.
The border sizes are the distance form the edges of the canvas to the green centre piece!
Another thing I did was I imported two custom fonts, set one as the default generic font at the top, and the other as the Box font. I also played with the content offset options to position my box title exactly where I want it!
There is a problem however. Our problem is that the buttons and other stuff we have inside our box is not bound by it’s border! To fix this, first go into the GUIScript I gave you earlier and paste this over it:
var MenuSkin : GUISkin;
var toggleTxt : boolean;
var toolbarInt : int = 0;
var toolbarStrings : String[] = ["Toolbar1", "Toolbar2", "Toolbar3"];
var selGridInt : int = 0;
var selStrings : String[] = ["Grid 1", "Grid 2", "Grid 3", "Grid 4"];
var hSliderValue : float = 0.0;
var hSbarValue : float;
function OnGUI() {
GUI.skin = MenuSkin;
GUI.Box(Rect(Screen.width/2-140,Screen.height/2-140,300,300),"This is the title of a box");
GUI.BeginGroup(new Rect(Screen.width/2-140,Screen.height/2-140,300,300));
GUI.Button(Rect(0,25,100,20),"I am a button");
GUI.Label (Rect (0, 50, 100, 20), "I'm a Label!");
toggleTxt = GUI.Toggle(Rect(0, 75, 200, 30), toggleTxt, "I am a Toggle button");
toolbarInt = GUI.Toolbar (Rect (0, 110, 250, 25), toolbarInt, toolbarStrings);
selGridInt = GUI.SelectionGrid (Rect (0, 170, 200, 40), selGridInt, selStrings, 2);
hSliderValue = GUI.HorizontalSlider (Rect (0, 210, 100, 30), hSliderValue, 0.0, 1.0);
hSbarValue = GUI.HorizontalScrollbar (Rect (0, 230, 100, 30), hSbarValue, 1.0, 0.0, 10.0);
GUI.EndGroup ();
}
Ok now look for the dropdown under box that says “Overflow”:
I set my sides to 15 pixels overflow each. What this means is that where the box physically starts is 15pixels away from where it visually starts. This will ensure that we dont have to calculate the distance for each button or whatnot inside the box.
So now this is what we end up with:
Awesome!
This is getting a bit long so Ill make PART TWO in another thread ^^