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;
}
}
}