0

I am using the google VR SDK (for cardboard) in unity3d but the cardboard i have does not have buttons. Is there a way to enable gaze only mode that treats extended gaze (a few seconds) as a button click? ( i guy in a tutorial video said "you can enable gaze only mode" but did not explain anything afterwards) is this a feature built in or do i have to code the gaze interaction from scratch to accomplish this?

I have searched everywhere for the code to enable this not only the public props that appear on the editor on the different prefabs available from the demo scenes.

g.k
  • 35
  • 9

1 Answers1

1

I don't know how or if there is a built-in method for this. But you can easily build extending the button:

using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.UI;
#endif

public class DwellTimeButton : Button
{
    public float dwellTime = 0.5f;

    public override void OnPointerEnter(PointerEventData pointerEventData)
    {
        base.OnPointerEnter(pointerEventData);

        StartCoroutine (DwellTimeRoutine());
    }

    public override void OnPointerExit (PointerEventData pointerEventData)
    {
        base.OnPointerExit(pointerEventData);

        StopAllCoroutines ();
    }

    private IEnumerator DwellTimeRoutine ()
    {
        yield return new WaitForSeconds (dwellTime);

        onClick.Invoke();
    }

#if UNITY_EDITOR
    [CustomEditor (typeof (DwellTimeButton)]
    private class DwellTimeButtonEditor : ButtonEditor
    {
        SerializedProperty dwellTime;

        protected override void OnEnable()
        {
            base.OnEnable();

            dwellTime = serializedObject.FindProperty("dwellTime");
        }

        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();

            serializedObject.Update();

            EditorGUILayout.PropertyField(dwellTime);

            serializedObject.ApplyModifiedProperties();
        }
    }
#endif
}

Replace a normal Unity Button with this component and set the desired dwellTime. It will then automatically invoke the onClick event after staying focused for the dwellTime.


As alternative without having to replace the Button everywhere you can simply attach this component additionally on every button:

using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[RequireComponent(typeof(Button))]
public class DwellTimeButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
    [SerializeField] private Button button;

    public float dwellTime = 0.5f;

    private void Awake()
    {
        if (!button) button = GetComponent<Button>();
    }

    public  void OnPointerEnter(PointerEventData pointerEventData)
    {
        button.OnPointerEnter(pointerEventData);

        StartCoroutine(DwellTimeRoutine());
    }

    public  void OnPointerExit(PointerEventData pointerEventData)
    {
        button.OnPointerExit(pointerEventData);

        StopAllCoroutines();
    }

    private IEnumerator DwellTimeRoutine()
    {
        yield return new WaitForSeconds(dwellTime);

        button.onClick.Invoke();
    }
}

This does basically the same but invokes the onClick and other events of the Button component instead.


note: typed on smartphone but I hope the idea gets clear

derHugo
  • 83,094
  • 9
  • 75
  • 115
  • Thanks for the assist, I ended up doing something like this. but for your solution I mean this might work for a button, but then would i have to extend every object that needs this behavior? i might use the coroutines (i am currently using the update method) – g.k Jan 07 '20 at 08:11
  • @Vahakn You could of course instead also just implement a component you place next to a button and only invoke the `GetComponent – derHugo Jan 07 '20 at 08:46