Forum Discussion
Anonymous
10 years agoRaycasting with integrated support?
I have a test scene where I look at a button to activate it via raycasting. This works with the standard FPS controller however when I turn on the 'Virtual Reality Supported' checkbox it no longer see...
peterept
10 years agoProtege
If you are using Unity Canvas UI, then I wrote the following gaze input module.
It's simplified to just allows you to trigger click events after gazing for N seconds.
To use:
1. Drag it onto your EventSystem object.
2. Disable any other Input Modules (eg: StandaloneInputModule & TouchInputModule) as they will fight over selections.
3. Make sure your Canvas is in world space and has a GraphicRaycaster.
4. If you have multiple cameras then make sure to drag your center camera into the canvas.
It's based on the code posted by @ccs in the topic New Unity UI + OVR Look-Based Input HOWTO.
Note: It leverages the PointerInputModule because it's tracking enter/exit hilighting UI for us.
CRITICALLY IMPORTANT: If you are using the FirstPersonController be aware that it totally breaks Canvas UI !
This is because the mouse code in it resets the camera orientation every frame during Update() for both mouse rotation horizotnal and vertical, and also head bobbing effect.
To fix it: Firstly turn off head bob property in the inspector. Then either disable the mouse code completely in FirstPersonController (comment out RotateView() call in Update()), or alternatively to keep mouse to turn your body, edit the MouseLook.cs file and comment out the 2 places it calls camera.localRotation in LookRotation() file. (Another alternative for a super quick fix is to rename Update() to be LateUpdate() so the Canvas UI raycasts run before the orientation is messed up. But it may mess up other timings in your app, so best to edit MouseLook).
(I filed bug 709519 with Unity about this. As it also can effect anything that tracks the camera)
It's simplified to just allows you to trigger click events after gazing for N seconds.
To use:
1. Drag it onto your EventSystem object.
2. Disable any other Input Modules (eg: StandaloneInputModule & TouchInputModule) as they will fight over selections.
3. Make sure your Canvas is in world space and has a GraphicRaycaster.
4. If you have multiple cameras then make sure to drag your center camera into the canvas.
It's based on the code posted by @ccs in the topic New Unity UI + OVR Look-Based Input HOWTO.
Note: It leverages the PointerInputModule because it's tracking enter/exit hilighting UI for us.
CRITICALLY IMPORTANT: If you are using the FirstPersonController be aware that it totally breaks Canvas UI !
This is because the mouse code in it resets the camera orientation every frame during Update() for both mouse rotation horizotnal and vertical, and also head bobbing effect.
To fix it: Firstly turn off head bob property in the inspector. Then either disable the mouse code completely in FirstPersonController (comment out RotateView() call in Update()), or alternatively to keep mouse to turn your body, edit the MouseLook.cs file and comment out the 2 places it calls camera.localRotation in LookRotation() file. (Another alternative for a super quick fix is to rename Update() to be LateUpdate() so the Canvas UI raycasts run before the orientation is messed up. But it may mess up other timings in your app, so best to edit MouseLook).
(I filed bug 709519 with Unity about this. As it also can effect anything that tracks the camera)
using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections.Generic;
public class GazeInputModule : PointerInputModule {
[Tooltip("Time in seconds for a gaze to click")]
public float GazeToClickTime = 2f;
private PointerEventData pointerEventData;
private GameObject currentLookAtHandler;
private float currentLookAtHandlerClickTime;
public override void Process()
{
ProcessGazeMove();
ProcessGazeClick();
}
void ProcessGazeMove()
{
if (pointerEventData == null)
{
pointerEventData = new PointerEventData(eventSystem);
}
// fake a pointer always being at the center of the screen
pointerEventData.position = new Vector2(Screen.width/2, Screen.height/2);
pointerEventData.delta = Vector2.zero;
List<RaycastResult> raycastResults = new List<RaycastResult>();
eventSystem.RaycastAll(pointerEventData, raycastResults);
pointerEventData.pointerCurrentRaycast = FindFirstRaycast(raycastResults);
ProcessMove(pointerEventData);
}
void ProcessGazeClick()
{
if (pointerEventData.pointerEnter != null)
{
// if the ui receiver has changed, reset the gaze delay timer
GameObject handler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(pointerEventData.pointerEnter);
if (currentLookAtHandler != handler)
{
currentLookAtHandler = handler;
currentLookAtHandlerClickTime = Time.realtimeSinceStartup + GazeToClickTime;
}
// if we have a handler and it's time to click, do it now
if (currentLookAtHandler != null && Time.realtimeSinceStartup > currentLookAtHandlerClickTime)
{
ExecuteEvents.ExecuteHierarchy(currentLookAtHandler, pointerEventData, ExecuteEvents.pointerClickHandler);
currentLookAtHandlerClickTime = float.MaxValue;
}
}
else
{
currentLookAtHandler = null;
}
}
}
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 10 months ago
- 7 months ago
- 7 months ago