Creating Menus for Interactive Objects for SineSpace
This wiki article describes how to create menus or 'HUDs' for interactive objects in SineSpace. This article depends heavily on previous work from Mike (CNDG), published in the SineSpace Forum HowTos, and with foundational work supported greatly by Torgon Woodget, Xulain, Trilo Byte, and the unstoppable Adam Frisby.
Let's Get Busy
There are a few conditions upon which any such HUD project would be predicated. Mainly, that the HUD interface described in this article is specifically for use with scripted objects. There are also some simple circumstances where the HUD could be wired up to certain components, or certain predefined operations. We will employ such operations to the ends of managing the HUD, but our primary focus will be the slightly more complex case of driving scripted operations. This should provide a good survey of the use of the UI for creating HUDs of various sorts. The other condition, of course, is that you have some object to which to attach your scripts and interface. For our purposes, we'll use a Unity Primitive of the type Cube. To create the cube, use the menu click path Game Object->3D Object->Cube. In this article, we'll reference all Unity Editor menu operations in this fashion.
The HUD we will develop in this article is a non-modal screen overlay with a background and a few buttons. The buttons will invoke certain functions within the accompanying script. The HUD will be invoked by clicking on the object proper, and will be dismissed with one of the buttons, styled as a classical 'Close' button.
This type of HUD is very versatile and can be adapted to a considerable set of interactive objects. It's ideal for a certain class of objects, in that it appears only as a result of manual interaction with the object, and uses no valuable screen real-estate when not in operation. I've used this type of HUD to great effect in my 'Nuklear Radio', which can be found in the SineSpace marketplace (</gratuitous self promtion>).
Setting Up the Object
The entire object is organized under an Empty Game Object, so create one in your scene, position it conveniently, and give it an appropriate name. Various components and at least one object will be involved. Firstly, lets get the object out of the way: add it as a child to the Empty Object just created in the scene, and adjust the object's relative position accordingly. For purposes of the article, the object will be the cube created earlier.
Next, add the 'Scripting Runtime Component'. This is where the Lua script lives that implements the HUD functionality.
Mike (CNDG)'s HowTo provides an excellent in-depth description of the process of creating the UI, including illustrations, so we will cover it only in the most essential way in this article.
- After selecting it, add a Canvas to the now not-so-empty game object we created at the beginning. Henceforth, we will refer to that foundational game object simply as GO.
- To the new canvas, add an Image. While we won't be doing so in the tutorial, this is where the opportunity resides to 'dress up' the UI with a background illustration. Note also that we are passing over some significant detail here in this process; there are various things which must be done to properly size and position the HUD; those are properties of the image, and potentially the canvas. For our purposes, the canvas goes untouched. You should see the Forum HowTo by Mike (CNDG) for a detailed and illustrated workflow for setting up your image in this respect. (Game Object->UI->Image)
- To the image, we will add some buttons. Specifically, three of them: 'Red Alert', 'All Clear', and 'X' (our classical close button)'. Go ahead and create three buttons. Be sure they are all children of the UI image created in the previous step. Edit the position relative to the image, and labeling of the buttons accordingly.
You should end up with something similar to this:
Your buttons should resemble this in the inspector:
Wiring up the UI
Management of the UI is accomplished with two clicks; one is the click on the object to invoke the HUD, and the other is the button used to close the HUD. While the object itself is not a button in the UI, it will be treated essentially as if it were, once we have added a Clickable Activator component. Go ahead and do that now.
Click on the GO and then in the inspector, 'Add Component'. This should work all more or less as you would expect.
A note about the general unity strategy for exposing screen overlays like this HUD: they are set up and then disabled by default. This allows them to be toggled via some stimulus. The Clickable Activator added in the previous step will provide the stimulus to enable the HUD in our application, and the 'Close' button will provide the stimulus to close it.
In the inspector, the Clickable Event for the activator should be set to 'canvas.enabled'. Before the proper click path becomes available, you will first need to slot the canvas in the clickable activator. You can set a tooltip value here as well, though it isn't required. The other necessity is the state to which 'canvas.enabled' should be set; it is indicated by the presence or absence of a check in the (unlabeled) checkbox. For the object's click event, we want this enabled status set 'on', so a check goes in the box. Make sure that the UI Canvas is slotted in the event's 'target' object, noting that yours most likely wont be called 'RadioUICanvas'. None of the other options in the clickable activator component are required.
The completed component should look about like this:
Now to the close button. Apart from a large set of parameters concerning the button's appearance, it has an 'event' setup, just like that on the clickable activator component. It should be set up identically, except in this event, the status for the canvas.enabled handler operation should be set to 'disabled', so no checkmark in the box. It too should have the UI Canvas slotted in the event's 'target' object.
It should look about like this:
Now to wire up the other two buttons, we need a script. It's important that we have a few addressable functions exposed by the script that we can tie into the events on the buttons, like we did for the object and the 'close' button. We're not going to get into too much depth about lua scripting beyond cutting and pasting a very simple script into the script window of the Scripting Runtime Component. This script will be simple enough such that it's fairly obvious what it's doing, and easily over-explained for purposes of this article ;)
If you haven't already, add a Scripting Runtime component to your original GO, by selecting the GO and using the Add Component button.
Here's the script:
function redAlert() Space.Log("Red Alert! All Hands!! Man your Battle Stations!") end function allClear() Space.Log("All clear. All Hands, At Ease.") end
The forgoing script should be copied and pasted into the Scripting Runtime component attached to the GO. You will perforce want to slot the GO into the events tied to each of the buttons. This is so that the system 'knows' to use a scripting runtime context in the event operations dropdown, and where to look for requested functions.
Now we will set up the buttons. Select the 'RedAlert' button, and find it's event block. Add an event. Note that if you set all these events 'Editor and Runtime' you will be able to experiment with this technique directly in the Unity Editor. In the new event for the button (dont forget to slot the GO!) select 'scripting.runtime' from the dropdown, and in the text field opposite the target object slot, enter 'redAlert'. Note that while this is in fact a function reference, you should not provide an empty argument list [i.e., '()']. The function label should be completely bare.
Repeat this process for the AllClear button. in the text box, enter 'allClear' instead of 'redAlert'.
Save your work ;)
If you click the preview button in the editor, you should be able to click the cube, get the menu, and issue red alerts and all clears to your heart's delight. As you may be able to tell from the simple script, these do nothing but write to the system log.
In editor mode, you will only be able to see notifications of new chats, not the chats themselves; for that you will have to switch to the console window.
This should give you a fairly good overview of making object-bound huds for SineSpace. If you have questions, feel free to hit me up on the developer channel. I'm generally around :D