Forum Discussion

🚨 This forum is archived and read-only. To submit a forum post, please visit our new Developer Forum. 🚨
Anonymous's avatar
Anonymous
10 years ago

Raycasting 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 seems to work.
I can look around just fine just not activate anything.

Is there something I'm missing?

6 Replies

Replies have been turned off for this discussion
  • It should work.

    I created this test app that shows raycasting working in VR. It also has a stereo crosshair.

    Unfortunately, the free look script is unfinished and has gimbal lock so try not to look straight up or down.

    Cheers, and have a nice weekend.
  • 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)



    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;
    }
    }
    }
  • Anonymous's avatar
    Anonymous
    Awesome, thanks so much.

    I'll test out both these solutions!
  • I've written up a detailed blog post on how to do look based UI in Unity 5 (both button and gaze-time to click are supported).

    Cyber, I also incorporated the technique used in your crosshair script to maintain crosshair size for any distance.

    http://talesfromtherift.com/vr-gaze-input/

    Let me know any feedback.