WaveVR_Gaze

Contents

Introduction

The Gaze feature is implemented in GazeInputModule.cs.

What is Gaze?

This function is when you are looking at an object (e.g. a cube, a blob, a menu item, etc.) and the object will perform the designated action.

Gaze is a way to interact with objects in VR without using a controller.

What is Gaze’s composition?

  1. Look: The focus of your vision.
  2. Object: What you are looking at.
  3. Event: Trigger object on designated action.

We provided a sample: When gazing at a cube for 2 seconds, the cube will teleport randomly. When gazing at the scroll bar, it will scroll.

Resources

The scripts GazeInputModule.cs and GOEventTrigger.cs in Assets/WaveVR/Extra while WaveVR_Reticle.cs is located in Assets/WaveVR/Scripts

Sample Gaze_Test in Assets/Samples

How to Use

  1. Open the scene Gaze_Test in sample:
_images/gaze01.png
  1. Go to WaveVR/head/ReticlePointer. A prefab in the folder Assets/WaveVR/Prefabs is used to generate a reticle in the center of your view (point state as below):
_images/gaze05.png
  1. With Eye Right and Eye Left, both have a component Physics Raycaster. (For more details, see this)
We use Physics Raycaster to determine which object is gazed.
  1. In the Inspector of Cube, it has three important components: Box Collider, GOEventTrigger and Event Trigger.

With a collider, the 3D object can be detected by raycast.

Event Trigger is used to cause an action to happen when receiving an event.

GOEventTrigger.cs is the event handler which has actions that can be triggered by Event Trigger.

_images/gaze03.png
  1. The last object is EventSystem. There can be only one EventSystem in a scene and and it’s used to transceive events between different GameObjects.

Look in the Inspector of EventSystem. It contains the component GazeInputModule.cs that is used to generate input events.

Developer can change the value of Time To Gaze to control the gaze time (default is 2 seconds).

_images/gaze04.png

Selecting Progress Rate lets you see the percentage (count from 0% to 100%, 100% means the time of Time To Gaze option is over) on screen near the reticle pointer.

With the Progress Counter option, you can see the counter value (count backward from the value of Time To Gaze setting to zero) on screen near the reticle pointer. For each movement of the reticle pointer, the position of the percentage and counter texts will follow the position of the reticle pointer.

The developer can adjust its Z-axis position (>= 0) on screen to make it look closer to the user by the Rate Text Z Position or Counter Text Z Position option.

For Input Event, there are three event options. You can set which event will be sent when gazing.

For Head, it’s a gameobject whose camera will be used to raycast object for Gaze feature. Do not set the gameobject without camera and physics raycast. Otherwise, the Gaze feature would not work.

_images/gaze07.png

The BtnControl is an option to enable the feature which you can trigger sending event to the gazed object by button. There has three suboptions (Gaze Trigger Device , Button To Trigger , With Time Gaze) under BtnControl will be displayed after it is selected. In Editor mode, you can change it’s settings dynamically.

Gaze Trigger Deivce is used to set which device owns the trigger button.

Button To Trigger is the button which is used to trigger Gaze.

With Time Gaze means the Gaze can be triggered by both button and timer.

In Editor mode (just play the scene), developer can use left Alt + mouse to control the view and cube will be transported when the reticle is on the cube.

If Gaze Input Module is not selected and Standalone Input Module is used, the cube will be transported when the developer left clicks on it.

Script

GazeInputModule inherits PointerInputModule.

In the function CastToCenterOfScreen, it’s using raycast to detect the object at the center of the screen.

// Cast ray
pointerData.position = new Vector2 (0.5f * Screen.width, 0.5f * Screen.height);  // center of screen
eventSystem.RaycastAll(pointerData, m_RaycastResultCache);

// Get result of which ray casted
RaycastResult raycastResult = FindFirstRaycast(m_RaycastResultCache);

In the function OnTriggeGaze, sending an event to object is taken from CastToCenterOfScreen.

if (sendEvent)
{
    if (InputEvent == EGazeInputEvent.PointerClick)
    {
        ExecuteEvents.ExecuteHierarchy (currentOverGO, pointerData, ExecuteEvents.pointerClickHandler);
        pointerData.clickTime = Time.unscaledTime;
    } else if (InputEvent == EGazeInputEvent.PointerDown)
    {
        // Similar to a mouse, press and then release right after. Do not keep the pointerPressRaycast as it is not needed to control the "down" object when not gazing.
        pointerData.pressPosition = pointerData.position;
        pointerData.pointerPressRaycast = pointerData.pointerCurrentRaycast;

        var _pointerDownGO = ExecuteEvents.ExecuteHierarchy (currentOverGO, pointerData, ExecuteEvents.pointerDownHandler);
        ExecuteEvents.ExecuteHierarchy (_pointerDownGO, pointerData, ExecuteEvents.pointerUpHandler);
    } else if (InputEvent == EGazeInputEvent.PointerSubmit)
    {
        ExecuteEvents.ExecuteHierarchy (currentOverGO, pointerData, ExecuteEvents.submitHandler);
    }
}