namespace Zinnia.Tracking.CameraRig { using System; using UnityEngine; using UnityEngine.Events; using UnityEngine.XR; using Zinnia.Extension; using Zinnia.Process; public class DominantControllerObserver : MonoBehaviour, IProcessable { /// /// Defines the event with the . /// [Serializable] public class UnityEvent : UnityEvent { } #region Reference Settings [Header("Controller Settings")] [Tooltip("The details about the left controller.")] [SerializeField] private DeviceDetailsRecord leftController; /// /// The details about the left controller. /// public DeviceDetailsRecord LeftController { get { return leftController; } set { leftController = value; } } [Tooltip("The details about the right controller.")] [SerializeField] private DeviceDetailsRecord rightController; /// /// The details about the right controller. /// public DeviceDetailsRecord RightController { get { return rightController; } set { rightController = value; } } #endregion #region Device Events /// /// Emitted as the dominant controller is changing. /// [Header("Device Events")] public UnityEvent IsChanging = new UnityEvent(); #endregion /// /// The current dominant controller node. /// public virtual XRNode DominantController => GetDominantController() == null ? XRNode.Head : LastKnownDominantControllerDetails.XRNodeType; /// /// The current dominant controller. /// public virtual DeviceDetailsRecord DominantControllerDetails => GetDominantController(); /// /// The last known dominant controller without doing a fresh query. /// public virtual DeviceDetailsRecord LastKnownDominantControllerDetails { get; protected set; } /// /// Clears . /// public virtual void ClearLeftController() { if (!this.IsValidState()) { return; } LeftController = default; } /// /// Clears . /// public virtual void ClearRightController() { if (!this.IsValidState()) { return; } RightController = default; } /// /// Processes the state of the dominant controller. /// public virtual void Process() { GetDominantController(); } /// /// Gets the dominant controller. /// /// The dominant controller. protected virtual DeviceDetailsRecord GetDominantController() { DeviceDetailsRecord controller = null; if (!IsDeviceDetailsRecordConnected(RightController) && IsDeviceDetailsRecordConnected(LeftController)) { controller = LeftController; } else if (IsDeviceDetailsRecordConnected(RightController) && !IsDeviceDetailsRecordConnected(LeftController)) { controller = RightController; } else if (IsDeviceDetailsRecordConnected(RightController) && IsDeviceDetailsRecordConnected(LeftController)) { controller = LeftController.Priority < RightController.Priority ? LeftController : RightController; } if (LastKnownDominantControllerDetails != controller) { IsChanging?.Invoke(controller); } LastKnownDominantControllerDetails = controller; return controller; } /// /// Determines whether the given device record is set and connected. /// /// The record to check. /// Whether the given record is connected. protected virtual bool IsDeviceDetailsRecordConnected(DeviceDetailsRecord record) { return record != null && record.IsConnected; } } }