GazeInputManager.cs 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. using System.Collections.Generic;
  2. using UnityEngine.InputSystem;
  3. namespace UnityEngine.XR.Interaction.Toolkit.Samples.StarterAssets
  4. {
  5. /// <summary>
  6. /// Manages input fallback for <see cref="XRGazeInteractor"/> when eye tracking is not available.
  7. /// </summary>
  8. public class GazeInputManager : MonoBehaviour
  9. {
  10. // This is the name of the layout that is registered by EyeGazeInteraction in the OpenXR Plugin package
  11. const string k_EyeGazeLayoutName = "EyeGaze";
  12. [SerializeField]
  13. [Tooltip("Enable fallback to head tracking if eye tracking is unavailable.")]
  14. bool m_FallbackIfEyeTrackingUnavailable = true;
  15. /// <summary>
  16. /// Enable fallback to head tracking if eye tracking is unavailable.
  17. /// </summary>
  18. public bool fallbackIfEyeTrackingUnavailable
  19. {
  20. get => m_FallbackIfEyeTrackingUnavailable;
  21. set => m_FallbackIfEyeTrackingUnavailable = value;
  22. }
  23. bool m_EyeTrackingDeviceFound;
  24. /// <summary>
  25. /// See <see cref="MonoBehaviour"/>.
  26. /// </summary>
  27. protected void Awake()
  28. {
  29. // Check if we have eye tracking support
  30. var inputDeviceList = new List<InputDevice>();
  31. InputDevices.GetDevicesWithCharacteristics(InputDeviceCharacteristics.EyeTracking, inputDeviceList);
  32. if (inputDeviceList.Count > 0)
  33. {
  34. Debug.Log("Eye tracking device found!", this);
  35. m_EyeTrackingDeviceFound = true;
  36. return;
  37. }
  38. foreach (var device in InputSystem.InputSystem.devices)
  39. {
  40. if (device.layout == k_EyeGazeLayoutName)
  41. {
  42. Debug.Log("Eye gaze device found!", this);
  43. m_EyeTrackingDeviceFound = true;
  44. return;
  45. }
  46. }
  47. Debug.LogWarning($"Could not find a device that supports eye tracking on Awake. {this} has subscribed to device connected events and will activate the GameObject when an eye tracking device is connected.", this);
  48. InputDevices.deviceConnected += OnDeviceConnected;
  49. InputSystem.InputSystem.onDeviceChange += OnDeviceChange;
  50. gameObject.SetActive(m_FallbackIfEyeTrackingUnavailable);
  51. }
  52. /// <summary>
  53. /// See <see cref="MonoBehaviour"/>.
  54. /// </summary>
  55. protected void OnDestroy()
  56. {
  57. InputDevices.deviceConnected -= OnDeviceConnected;
  58. InputSystem.InputSystem.onDeviceChange -= OnDeviceChange;
  59. }
  60. void OnDeviceConnected(InputDevice inputDevice)
  61. {
  62. if (m_EyeTrackingDeviceFound || !inputDevice.characteristics.HasFlag(InputDeviceCharacteristics.EyeTracking))
  63. return;
  64. Debug.Log("Eye tracking device found!", this);
  65. m_EyeTrackingDeviceFound = true;
  66. gameObject.SetActive(true);
  67. }
  68. void OnDeviceChange(InputSystem.InputDevice device, InputDeviceChange change)
  69. {
  70. if (m_EyeTrackingDeviceFound || change != InputDeviceChange.Added)
  71. return;
  72. if (device.layout == k_EyeGazeLayoutName)
  73. {
  74. Debug.Log("Eye gaze device found!", this);
  75. m_EyeTrackingDeviceFound = true;
  76. gameObject.SetActive(true);
  77. }
  78. }
  79. }
  80. }