(HoloLens) A simple way to respond to user gaze input on UI elements

In this article we are going to:

  • Create a line in Unity to animate
  • Create the animations needed in Unity
  • Hook up the animations with a parameter via Unity
  • Make the animations run when events are passed via C#-scripts

Start

Example

Let’s take an example; a screen with 4 buttons. So, to make this animated line we first need an object with an Image Component. Remove any Source Image that might be given to the property and choose a color for the line. Then in the RectTransform of the object, stretch it either to the length or the height. Choose the width of the line. Once that’s done, find out what the size is of the button and use that to decide where the line should begin and end in its animation. In my case the length is 300 and I want the line to start in the middle so I enter 150 in both the top and bottom gaps between the line and the anchors of the button so the line isn’t visible.

Animation

Animations

For the animations, I made use of the animation system of Unity to create an extremely simple animation for both the expansion and retraction of the line. To do this open the Animation(!) window (Top-left bar -> Window -> Animation). Once there click on the line in the hierarchy and click Create on the Animation Screen. Fill in a name for the new animation and click Save. Add the Size Delta property of the RectTransform to the clip through the Add Property button. You should see two key frames appear on the beginning and the end of the animation. Add your starting value in the first frame and your end value in the second one. In my case, I fill these number in the y field but if you stretched the line along the x-axis fill in the numbers in x.

After you created the first animation, create the second animation with reversed values and save them both. Click the files in your Assets folders in Unity and uncheck Loop Time. In the place where the animations where saved there should be an Animation Controller as well. When you open this, it opens the Animator(!) screen. Here you should see the two animations as States. Set the animation that retracts the line as default state and create transitions between the two animations (right-click state -> Make Transition -> left-click other state). Do this back and forth. So, the animator should look like this:

Animator

Animator

Next, click on the arrow between the states and expand the settings text. Change the Exit Time, Transition Duration and Transition Offset to 0. Do this for both arrows. To the left of this screen you should see a screen with an empty list of parameters. There click on the small “+” and add a bool. In the arrows, add the bool as condition where one is true and the other is false.

Scripts

The button is all set, now you need to add the scripts used to detect when a user is gazing at the button. The GazeManager (HoloToolkit) class offers an event that tells you when the focused object changes. You can catch this event and send a message to the object so you don’t need to set up specific parameters in the editor. Here is an example of how to catch the event:

public class EventManager : MonoBehaviour {
void Start () 
    {
        GazeManager.Instance.FocusedObjectChanged += OnStatusChanged;
	}

    void OnStatusChanged(GameObject oldObject, GameObject newObject)
    {
        if (oldObject != null && oldObject.GetComponent<HoloButton>() != null)
        {
            oldObject.SendMessage("OnHoverExit");
        }
        if (newObject != null && newObject.GetComponent<HoloButton>() != null)
        {
            newObject.SendMessage("OnHoverEnter");
        }
    }
}

The HoloButton class is a custom class to define a button and handle button events:

public class HoloButton : MonoBehaviour {
private Animator Barrier;

	void Start () {
	}

    void OnHoverEnter()
    {
        if (Barrier == null)
        {
            Barrier = GetComponentInChildren<Animator>();
        }
        if (Barrier != null)
        {
            Barrier.SetBool("OnHover",true);
        }
    }

    void OnHoverExit()
    {
        if (Barrier == null)
        {
            Barrier = GetComponentInChildren<Animator>();
        }
        if (Barrier != null)
        {
            Barrier.SetBool("OnHover", false);
        }
    }

In my case, the bool I defined in the animator is called OnHover but you should change this to your bool name. When you link the HoloButton class to every button and the EventManager to the base Canvas, the buttons react to your cursor hover with an expanding and line. Don’t forget to save this line as a prefab to be able to use this anywhere. You can simply resize and rotate the line to make it fit in any object you want. Cheers!

Comments