2

I am new to unity and VR. I have been using google cardboard SDK to create VR apps in unity and am stuck at gazetimer. I want to trigger an action only if the user looks at any object for 3secs but have not been able to do so. Please help

sKhan
  • 9,694
  • 16
  • 55
  • 53
sayal adhikari
  • 116
  • 2
  • 9
  • generally use Invoke and InvokeRepeating for timers in Unity. go to forum.unity3d or gamedev for general discussions on technique. – Fattie Feb 18 '16 at 15:20

2 Answers2

1

Please see a similar question and answer here Use Gaze Input duration to select UI text in Google Cardboard

In summary, create a script to time the gaze, by cumulatively adding Time.deltaTime on each frame when the object is gazed at. When gaze time hits a pre-specified duration, trigger the button's OnClick event.

On the object, activate the script's gaze timing functions using event triggers Pointer Enter and Pointer Exit. See screenshot:

Timed gaze button Event Triggers

Community
  • 1
  • 1
Eugene Sia
  • 41
  • 4
-1

VR Camera usually contains a main camera and eye cameras (right and left). Since Main camera's center point will always be the center of the eyes of the user's point of view, you could use Raycast from its transform.position to its transform.forward and check whether it hits your object. Then simply add a timer which will call the action after it reaches the duration you have set.

For example:

using UnityEngine;
using System;

[RequireComponent(typeof(Collider))]
public class LookableObject : MonoBehaviour {

    [SerializeField]
    Transform cam; // This is the main camera.
    // You can alternately use Camera.main if you've tagged it as MainCamera

    [SerializeField]
    float gazeDuration; // How long it should be gazed to trigger the action

    public Action OnGazeAction; // Your object's action after being gazed

    Collider gazeArea; // Your object's collider

    float timer; // Gaze timer

    public void Start () {
        gazeArea = GetComponent<Collider> ();
    }

    public void Update () {
        RaycastHit hit;

        if (Physics.Raycast (cam.position, cam.forward, out hit, 1000f)) {
            if (hit.collider == gazeArea) {

                timer += Time.deltaTime;

                if (timer >= gazeDuration) {
                    if (OnGazeAction != null)
                        OnGazeAction ();
                }

            } else {
                timer = 0f;
            }
        } else {
            timer = 0f;
        }
    }
}

Hope you get the idea.

dkrprasetya
  • 114
  • 5
  • 1
    this is a terrible approach. if you have 100 objects in the scene they will do 100 raycasts per frame. You can at least attach Physics Raycaster to the main camera and do hit checking every frame. But this is exactly what Cardboard SDK's GazeInputModule does. I came here because I need to tweak GazeInputModule so that it sends OnPointerXXX commands to objects after timed gaze. No luck so far... – Nika Kasradze Sep 25 '16 at 14:07
  • @NikaKasradze This was just an example of using raycast. I would suggest to attach the raycast only on one script on your camera, then call the delegate from the hit object, therefore only 1 raycast per frame. But yes I think my sample seems a bit misleading here... will update my answer later. – dkrprasetya Sep 29 '16 at 05:07