WaveVR_ControllerInputModule

Important: we do NOT encourage to use this script directly.

Old version (2.1.8 and before): WaveVR_ControllerInputModule

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:
    Assets/WaveVR/Scripts/WaveVR_ControllerInputModule.cs Assets/WaveVR/Extra/EventSystem/
  • Sample:
    Assets/Samples/ControllerInputModule_Test/
  • Prefab:
    Assets/WaveVR/Prefabs/ControllerLoader Assets/WaveVR/Prefabs/InputModuleManager

Sample

There are two sample scenes MouseInputModule_Test and VRInputModule_Test in Assets/Samples/ControllerInputModule_Test/

VRInputModule_Test is introduced here.

1. InputModuleManager

_images/VRInputModule_Test.png

Prefab InputModuleManager is used to load WaveVR_ControllerInputModule

2. EventSystem

In runtime, WaveVR_ControllerInputModule is loaded by InputModuleManager and added into EventSystem like photo:

_images/cim_eventsystem.png
  • Dominant / NonDominant Controller: event controller used by WaveVR_ControllerInputModule
  • Dominant / NonDominant Event Enabled: check to enable the event of Dominant / NonDominant controller.
  • Dominant / NonDominant Raycast Mask: the layer mask of EventSystem
  • Button To Trigger: the button used to send event. Note: this button should be added in Buttons
  • Head: keep it empty to use default WaveVR head or developer can refer to Input Module Manager to set up other head.
  • Canvas Tag: the tag text used to mark Canvas(s) is able to receive events. Refer to 3. Left Menu Canvas and Right Menu Canvas
  • Fixed Beam Length: if the controller beam mode is Fixed, this field indicates the length of the controller beam.

The controller of WaveVR_ControllerInputModule is loaded by WaveVR_ControllerLoader

If developer wants to use customized controller, developer will have to

_images/Generic_MC_R.png
  • Add component WaveVR_SetAsEventSystemController to mention this controller is an Event Controller, e.g.
_images/cim_setaseventcontroller.png

3. Left Menu Canvas and Right Menu Canvas

WaveVR provides two methods for GUI being able to receive events from Unity EventSystem.

_images/cim_leftmenucanvas.png

In Left Menu Canvas, the Tag with value EventCanvas is used to mark GUI being able to receive events from EventSystem.

Note: if developer uses Tag, the value must be equivalent to Canvas Tag of WaveVR_ControllerInputModule.

_images/cim_rightmenucanvas.png

In Right Menu Canvas, the WaveVR_AddEventSystemGUI is used to mark GUI being able to receive events from EventSystem.

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

Another way is that using WaveVR_AddEventSystemGUI to mark the event Canvas.

Therefore we can easily get the Canvases:

GameObject[] _event_GUIs = WaveVR_EventSystemGUIProvider.GetEventGUIs();

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:

// 1. find Canvas by TAG
GameObject[] _tag_GUIs = GameObject.FindGameObjectsWithTag (CanvasTag);
// 2. Get Canvas from Pointer Canvas Provider
GameObject[] _event_GUIs = WaveVR_EventSystemGUIProvider.GetEventGUIs();

GameObject[] _GUIs = MergeArray (_tag_GUIs, _event_GUIs);

foreach (GameObject _GUI in _GUIs)
{
    Canvas _canvas = (Canvas)_GUI.GetComponent (typeof(Canvas));
    // Change event camera.
    _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 .

Unity Mouse Mode

WaveVR_ControllerInputModule provides two modes: VR Mode (default) and Mouse Mode.

Another sample scene MouseInputModule_Test demonstrate the Mouse Mode and uses Scripts/testeventhandler.cs to set UnityMouseMode in runtime.