WaveVR_ControllerInputModule

Old version (2.0.24 and before): here

Contents

Introduction

Unity has Event System which lets objects receive events from an input and take corresponding actions.

An input module is where the main logic of how you want the Event System to behave is located. They are used for:

  • Handling input
  • Managing event mechanism
  • Sending events to scene objects.

This script supports input module of multiple controllers.

Resources

Script WaveVR_ControllerInputModule is located in Assets/WaveVR/Scripts

Script WaveVR_EventHandler is located in Assets/WaveVR/Extra/EventSystem

Script GOEventTrigger is located in Assets/WaveVR/Extra

Other EventSystem scripts are located in Assets/WaveVR/Scripts/EventSystem

Sample ControllerInputModule_Test and MixedInputModule_Test are located in Assets/Samples/ControllerInputModule_Test/Scenes

Prefab ControllerLoader and InputModuleManager are located in Assets/WaveVR/Prefabs

Introduction for the Samples 1

_images/cim_scene.png
  1. EventSystem
_images/cim_eventsystem.png

EventSystem is automatically added if a Canvas is added to scene or manually added by right-clicking on the Hierarchy panel > UI > Event System.

WaveVR_ControllerInputModule is added here to replace the Unity default “Standalone Input Module”.

There are 6 variables -

  • Right Controller: Right controller GameObject. Can be empty if using ControllerLoader .
  • Right Raycast Mask: Event Mask of right controller’s PhysicsRaycaster.
  • Left Controller: Left controller GameObject. Can be empty if using ControllerLoader .
  • Left Raycast Mask: Event Mask of left controller’s PhysicsRaycaster.
  • Button To Press: Choose a button on the controller to trigger event.
  • Canvas Tag: Tag of canvas which can receive events of EventSystem.
  1. Cube
_images/cube.png

WaveVR_EventHandler is used for handling events of EventSystem.

GOEventTrigger provides some functions which can be triggered by other GameObject.

  1. GUI
  • Old version (v2.0.24 and before):
_images/leftmenucanvas.png

There are Left Menu Canvas and Right Menu Canvas beneath the GUI that both have Tag EventCanvas.

The tag is used to recognize the Canvas which can receive events of EventSystem.

The tag must be equivalent to that in Canvas Tag of WaveVR_ControllerInputModule in EventSystem.

_images/rightmenucanvas.png

When using Canvas , Graphic Raycaster will be automatically added.

Graphic Raycaster is used to receive event from EventSystem.

_images/showbutton.png

In ShowButton and HideButton of Left Menu Canvas, the Pointer Down event of Event Trigger is set.

_images/triggerbutton.png

In TriggerButton of Right Menu Canvas, the On Click of Button is set.

  • Current version:

Instead of using Tag to recognize event GUIs, WaveVR provides a new script - WaveVR_AddEventSystemGUI to mark GUI being able to receive event from EventSystem.

_images/rightmenucanvas_addeventsystemgui.png

So now develop has two ways to send event to GUI:

  • Set GUI’s Tag and write tag value to Canvas Tag field of WaveVR_ControllerInputModule
  • Add component WaveVR_AddEventSystemGUI to GUI(s).

Two ways can coexist.

  1. Controller
_images/cim_controllerloader.png _images/Link_Ximmerse_6DOF_MC_R.png

Right controller vr_controller_tank_0_8_MC_R is prefab from Assets/ControllerModel/Link/Resources/Controller

In order to detect physics object, Physics Raycaster component is added.

Physics Raycaster depends on the Camera, therefore, the Camera component is also added.

ControllerLoader is a prefab from Assets/WaveVR/Prefabs and developer can refer to this

Note: in fact, we encourage to use ControllerLoader to load controller model of different controller automatically instead of using specified controller model (eq. vr_controller_tank_0_8_MC_R).

In order to demonstrate which components are used in a controller model, so we put vr_controller_tank_0_8_MC_R in this sample.

Of course, developers can design their own controllers thus ControllerLoader is not needed in case.

If developer uses a custom controller, remember to set the controller to Right Controller or Left Controller field of WaveVR Controller Input Module.

Introduction for the Samples 2

_images/cim_mixedinputmodule_test.png

This sample demonstrate the usage of InputModuleManager and new event GUI script.

  1. Left Menu Canvas and Right Menu Canvas
_images/cim_leftmenucanvas.png _images/cim_rightmenucanvas.png

As mentioned above, instead of Tag of Canvas, WaveVR provides WaveVR_AddEventSystemGUI to mark GUI being able to receive event from EventSystem.

We demonstrate Tag in Left Menu Canvas and WaveVR_AddEventSystemGUI in Right Menu Canvas.

  1. InputModuleManager
_images/cim_inputmodulemanager.png

This is prefab from Assets/WaveVR/Prefabs.

Developer can enable gaze feature by checking Enable Gaze and enable controller input module by checking Enable Controller.

Gaze reticle will be generated automatically if Enable Gaze is checked.

Controller is loaded by ControllerLoader and set as event controller if Enable Controller is checked.

If Enable Controller is not checked, controller will still be loaded but can’t send any event.

If developer uses custom controller(s) instead of using ControllerLoader to load WaveVR default controller(s), it is necessary to drag the custom controller GameObject into field Right Controller or Left Controller and set the Physical Raycast Mask if needed.

Script

Work Flow

Before sending events, casting a ray is necessary.

We use GraphicRaycaster for GUI and PhysicsRaycaster for physics objects.

After casting a ray, event Enter will be sent to cast object and Exit to previous object.

If controller is hovering on an object, Hover event will be sent.

// 1. Get graphic raycast object.
ResetPointerEventData (_dt);
GraphicRaycast (_eventController, _event_camera);

if (GetRaycastedObject (_dt) == null)
{
    // 2. Get physic raycast object.
    PhysicsRaycaster _raycaster = _controller.GetComponent<PhysicsRaycaster> ();
    if (_raycaster == null)
        continue;

    ResetPointerEventData (_dt);
    PhysicRaycast (_eventController, _raycaster);
}

// 3. Exit previous object, enter new object.
OnTriggerEnterAndExit (_dt, _eventController.event_data);

// 4. Hover object.
GameObject _curRaycastedObject = GetRaycastedObject (_dt);
if (_curRaycastedObject != null && _curRaycastedObject == _eventController.prevRaycastedObject)
{
    OnTriggerHover (_dt, _eventController.event_data);
}

When key is released and GameObject is a Button, onClick will be invoked.

if (btnPressDown)
    _eventController.eligibleForButtonClick = true;
if (btnPressUp && _eventController.eligibleForButtonClick)
    onButtonClick (_eventController);

Change Event Camera When Graphic Raycast

We know that the Canvas of GUI has only one Event Camera for handling the UI events.

But we may have multiple controllers and they all trigger events to Canvas.

In order to make sure the Canvas can handle events from Cameras of both controllers, we need to switch the event camera before casting.

Considering that a scene has multiple Canvases, some have to receive events and others are not.

We only have to change the event cameras of Canvases those have to receive events.

A fast way is to use Tag so we provide a text field Canvas Tag in the script.

Therefore we can easily get the Canvases:

GameObject[] _tag_GUIs = GameObject.FindGameObjectsWithTag (CanvasTag);

And, we can get the new event camera from a specified controller:

Camera _event_camera = (Camera)_controller.GetComponent (typeof(Camera));

So the event camera is easily changed:

_canvas.worldCamera = event_camera;

Pointer Event Flow

Except for Enter and Exit event of Event Trigger Type , the flow of other events is:

_images/eventflow.png

Summarized:

  1. In frame of button is from briefly unpressed to pressed
  1. Send event Pointer Down
  2. Send event initializePotentialDrag (has Drag handler)
  1. In frames of button is pressed
  1. Send event beginDrag
  2. Send event Up to another object (different with current object) that has Pointer Down previously.
  3. Keep sending event Drag
  1. In frames of button is briefly from pressed to unpressed.
  1. Send event of Pointer Up
  2. Send event of Pointer Click
  3. If events of Drag have been sent before, send event Pointer Drop & endDrag

About Enter, Exit and Hover, these events are nothing about button state so not included in above flow:

  • When raycasting an object, Enter will be sent.
  • When hovering an raycasting object, Hover will be sent.
  • When leaving an raycating object, Exit will be sent.

Custom Defined Events

WaveVR defined custom EventSystem is located in Assets/WaveVR/Scripts/EventSystem

WaveVR_ExecuteEvents is used for sending events.

IWaveVR_EventSystem is used for receiving events.

Developer does not need to implement the part of sending event, it is managed in this script.

But if developer wants GameObjects with custom scripts receiving events, the scripts should inherit corresponding event interface:

public class WaveVR_EventHandler: MonoBehaviour,
    IPointerEnterHandler,
    IPointerExitHandler,
    IPointerDownHandler,
    IBeginDragHandler,
    IDragHandler,
    IEndDragHandler,
    IDropHandler,
    IPointerHoverHandler

IPointerHoverHandler is a WaveVR defined event which is not part of Event Trigger Type .