Making a Game UI for Unity

One of uiink's strengths is that it enables you to easily build fully custom UI widgets. This does mean the learning curve is a little steeper than a simple "click here to drag out a new button". The goal of this tutorial is to get you familiar with Quill so that you can quickly build a UI that fits your game's unique needs.

Once you're familiar with Quill, you'll be able to import and tweak stock widgets as a shortcut. Although you may find you prefer to build your own basic widgets, as it can really give a unique feel to your game's UI.


Creating a New Quill Project

The first step is to create a new Quill project inside your Unity project. The "New Project Name" field should be your Unity project's folder.

Select the "Unity" configuration option so that it configures your new project to export your UI to Unity's StreamingAssets folder.

Quill lists all the file system operations it will perform when you click the "Create" button. It's helpful to read through them so you know how Quill is affecting your Unity project.


Templates

Templates are Quill's way of encapsulating everything that makes up an interactive widget. You can put as much or as little functionality as you want in a single template. Templates can include other templates, which we'll be doing a little later when we create a button.

There are two main components to a template, data processing and the view tree.

We'll only be briefly dipping in to data processing for this tutorial when connect up our play button.

Views are how you structure the presentation of your UI. Each view represents a space on the screen. A view can draw color, text, an image, and handle user input like a mouse click.

Views can also have other views as children. A parent view may arrange its children in a direction, or the children can position themselves inside their parent.

For this demo we're creating a main menu. We have the root "Main" view have a child view named "Box". We'll use "Box" later for arranging our title and button in the center of the screen. For now we just add a single child view to "Box" and name it "Title".

Our title view has two components, Text and Text align, which we use to display the word "Menu". Components can be added to a view using the "New Component" button, or using your keyboard's Space key.

I also added a Background component to the Main view to cover up the Unity scene we're drawing over with a solid color.

Unity Integration

Before moving on to making our button we should setup our Unity scene so we can watch our changes live. Parts of this processes may be slightly different for you depending on your edition of uiink.

Copy the Plugins and uiink folders from your uiink distribution into your Unity project's "Assets" folder. These contain the uiink runtime binaries and C# bindings.

Next we need a script to host our UI. Create a GUI.cs script (or any other name you prefer) in your Unity Assets:

using UnityEngine;
using uiink;

public class GUI : InkUnity
{
    public override void Ready(InkUnityRoot root)
    {
        var ink = Ink.Get();
    }
}

To make the script run our GUI we only need to attach it to a Unity game object. I created a new empty object, named it "GUI", and attached our script.

Pressing the play button in Unity you should see the start of your new main menu UI.


Making Reusable Widgets

Templates are useful for creating pieces of UI that can be used in multiple places. We could build a button widget directly in our Main template as a sibling to the "Title" view. But chances are we'll want more than a single button.

We can create a new template for our button using the overview tab or the Ctrl+N hotkey. After adding views and properties to make our button look the way we want, we can include it in our main template by creating a new view and setting it to be a "Template" type. Template views let you select a different template to include inline. In our case, the button template we just created.


Conditions

It's important for GUI widgets to change visually with user interaction. Conditions in Quill are what allow you to set properties to have different values when some piece of state is different. For example we can create a "Hover" condition that makes our button's background lighter what the user mouses over.

There are many builtin condition types to choose from or you can make your own that switches based on data from nodes you create.

To set conditional values on your properties, expand the property component by clicking on it and use the hamburger menu to the right of the property you want to change.


Events and Impulses

Impulses are how the GUI communicates that an action is being taken. Events, which can be created using the "New Event" button, fire an impulse when they capture a matching user input event.

We've added a pointer event to our button so that when clicked, an impulse is sent to a source node. In our GUI.cs script we can get a handle to the source node and set a callback to run whenever our impulse fires:

var ink = Ink.Get ();
var main = ink.Source ("main");
main.OnFieldChange("play", (ev) => {
    ink.InstantiateTemplate ("HUD");
});

When it does, we instantiate a new template for our in-game UI.

Next Steps

You can find the completed version of this demo in your distribution package when you purchase or try uiink. The full demo also includes an example of an inventory UI with drag and drop, aligning widgets to in-game objects, and how to use the data API.