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

Assets/WaveVR/Extra: scripts GazeInputModule.cs and GOEventTrigger.cs

Assets/WaveVR/Scripts: script WaveVR_Reticle.cs

Assets/Samples: sample Gaze_Test

Assets/WaveVR/Prefabs: prefabs WaveVR and ReticlePointer

Sample (incomplete)

  1. Open the scene Gaze_Test in sample:
_images/gaze01.png
  1. ReticlePointer is a prefab in the folder Assets/WaveVR/Prefabs used to generate a reticle in the center of your view (point state as below):
_images/gaze05.png
  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. 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.

To complete sample

In order to teach step by step, the sample Gaze_Test is incomplete.

Following steps below to complete this sample:

  1. Drag prefab WaveVR to scene
_images/gaze06.png
  1. Drag the head object of WaveVR to Head field of GazeInputModule
_images/gaze02.png
  1. Add component Physics Raycaster to head
_images/gaze08.png
  1. Expand the Camera settings and change the Target Eye to None (Main Display)
Note: if developer don’t find this option, ignore this step.
_images/gaze09.png
  1. Drag prefab ReticlePointer under head
_images/gaze10.png

Now this sample is completed. In Editor mode (just play the scene), developer can use left Alt + mouse to control the view.

The cube will be transported when the reticle is hovering 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.

The Head field of GazeInputModule can be specified but developer should notice:

  1. The Head GameObject should have Physics Raycaster
  2. The Target Eye of Camera of Head GameObject should be set to None (Main Display)

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);
    }
}