namespace VRTK.Prefabs.CameraRig.TrackedAlias { using UnityEngine; using UnityEngine.Events; using System.Collections.Generic; using Malimbe.XmlDocumentationAttribute; using Malimbe.PropertySerializationAttribute; using Malimbe.MemberChangeMethod; using Zinnia.Data.Attribute; using Zinnia.Tracking.Follow; using Zinnia.Tracking.Velocity; using Zinnia.Tracking.CameraRig; using Zinnia.Tracking.CameraRig.Collection; /// /// The public interface into the Tracked Alias Prefab. /// public class TrackedAliasFacade : MonoBehaviour { #region Tracked Alias Settings /// /// The associated CameraRigs to track. /// [Serialized] [field: Header("Tracked Alias Settings"), DocumentedByXml] public LinkedAliasAssociationCollectionObservableList CameraRigs { get; set; } #endregion #region Tracking Begun Events /// /// Emitted when the headset starts tracking for the first time. /// [Header("Tracking Begun Events")] public UnityEvent HeadsetTrackingBegun = new UnityEvent(); /// /// Emitted when the left controller starts tracking for the first time. /// public UnityEvent LeftControllerTrackingBegun = new UnityEvent(); /// /// Emitted when the right controller starts tracking for the first time. /// public UnityEvent RightControllerTrackingBegun = new UnityEvent(); #endregion #region Reference Settings /// /// The linked Internal Setup. /// [Serialized] [field: Header("Reference Settings"), DocumentedByXml, Restricted] public TrackedAliasConfigurator Configuration { get; protected set; } #endregion /// /// Retrieves the active PlayArea that the TrackedAlias is using. /// public GameObject ActivePlayArea => GetFirstActiveGameObject(PlayAreas); /// /// Retrieves the active Headset that the TrackedAlias is using. /// public GameObject ActiveHeadset => GetFirstActiveGameObject(Headsets); /// /// Retrieves the active Headset Camera that the TrackedAlias is using. /// public Camera ActiveHeadsetCamera => GetFirstActiveCamera(HeadsetCameras); /// /// Retrieves the active Headset Velocity Tracker that the TrackedAlias is using. /// public VelocityTracker ActiveHeadsetVelocity => GetFirstActiveVelocityTracker(HeadsetVelocityTrackers); /// /// Retrieves the active Left Controller that the TrackedAlias is using. /// public GameObject ActiveLeftController => GetFirstActiveGameObject(LeftControllers); /// /// Retrieves the active Left Controller Velocity Tracker that the TrackedAlias is using. /// public VelocityTracker ActiveLeftControllerVelocity => GetFirstActiveVelocityTracker(LeftControllerVelocityTrackers); /// /// Retrieves the active Right Controller that the TrackedAlias is using. /// public GameObject ActiveRightController => GetFirstActiveGameObject(RightControllers); /// /// Retrieves the active Right Controller Velocity Tracker that the TrackedAlias is using. /// public VelocityTracker ActiveRightControllerVelocity => GetFirstActiveVelocityTracker(RightControllerVelocityTrackers); /// /// Retrieves all of the linked CameraRig PlayAreas. /// public IEnumerable PlayAreas { get { if (CameraRigs == null) { yield break; } foreach (LinkedAliasAssociationCollection cameraRig in CameraRigs.NonSubscribableElements) { if (cameraRig == null) { continue; } GameObject playArea = cameraRig.PlayArea; if (playArea != null) { yield return playArea; } } } } /// /// Retrieves all of the linked CameraRig Headsets. /// public IEnumerable Headsets { get { if (CameraRigs == null) { yield break; } foreach (LinkedAliasAssociationCollection cameraRig in CameraRigs.NonSubscribableElements) { if (cameraRig == null) { continue; } GameObject headset = cameraRig.Headset; if (headset != null) { yield return headset; } } } } /// /// Retrieves all of the linked CameraRig Headset Cameras. /// public IEnumerable HeadsetCameras { get { if (CameraRigs == null) { yield break; } foreach (LinkedAliasAssociationCollection cameraRig in CameraRigs.NonSubscribableElements) { if (cameraRig == null) { continue; } Camera headsetCamera = cameraRig.HeadsetCamera; if (headsetCamera != null) { yield return headsetCamera; } } } } /// /// Retrieves all of the linked CameraRig Headset Velocity Trackers. /// public IEnumerable HeadsetVelocityTrackers { get { if (CameraRigs == null) { yield break; } foreach (LinkedAliasAssociationCollection cameraRig in CameraRigs.NonSubscribableElements) { if (cameraRig == null) { continue; } VelocityTracker headsetVelocityTracker = cameraRig.HeadsetVelocityTracker; if (headsetVelocityTracker != null) { yield return headsetVelocityTracker; } } } } /// /// Retrieves all of the linked CameraRig Left Controllers. /// public IEnumerable LeftControllers { get { if (CameraRigs == null) { yield break; } foreach (LinkedAliasAssociationCollection cameraRig in CameraRigs.NonSubscribableElements) { if (cameraRig == null) { continue; } GameObject leftController = cameraRig.LeftController; if (leftController != null) { yield return leftController; } } } } /// /// Retrieves all of the linked CameraRig Right Controllers. /// public IEnumerable RightControllers { get { if (CameraRigs == null) { yield break; } foreach (LinkedAliasAssociationCollection cameraRig in CameraRigs.NonSubscribableElements) { if (cameraRig == null) { continue; } GameObject rightController = cameraRig.RightController; if (rightController != null) { yield return rightController; } } } } /// /// Retrieves all of the linked CameraRig Left Controller Velocity Trackers. /// public IEnumerable LeftControllerVelocityTrackers { get { if (CameraRigs == null) { yield break; } foreach (LinkedAliasAssociationCollection cameraRig in CameraRigs.NonSubscribableElements) { if (cameraRig == null) { continue; } VelocityTracker leftControllerVelocityTracker = cameraRig.LeftControllerVelocityTracker; if (leftControllerVelocityTracker != null) { yield return leftControllerVelocityTracker; } } } } /// /// Retrieves all of the linked CameraRig Right Controller Velocity Trackers. /// public IEnumerable RightControllerVelocityTrackers { get { if (CameraRigs == null) { yield break; } foreach (LinkedAliasAssociationCollection cameraRig in CameraRigs.NonSubscribableElements) { if (cameraRig == null) { continue; } VelocityTracker rightControllerVelocityTracker = cameraRig.RightControllerVelocityTracker; if (rightControllerVelocityTracker != null) { yield return rightControllerVelocityTracker; } } } } /// /// The alias follower for the PlayArea. /// public ObjectFollower PlayAreaAlias => Configuration.PlayArea; /// /// The alias follower for the Headset. /// public ObjectFollower HeadsetAlias => Configuration.Headset; /// /// The alias follower for the LeftController. /// public ObjectFollower LeftControllerAlias => Configuration.LeftController; /// /// The alias follower for the RightController. /// public ObjectFollower RightControllerAlias => Configuration.RightController; protected virtual void OnEnable() { SubscribeToCameraRigsEvents(); } protected virtual void OnDisable() { UnsubscribeFromCameraRigsEvents(); } /// /// Subscribes to the events on the current collection. /// protected virtual void SubscribeToCameraRigsEvents() { if (CameraRigs == null) { return; } CameraRigs.Added.AddListener(OnCameraRigAdded); CameraRigs.Removed.AddListener(OnCameraRigRemoved); } /// /// Unsubscribes from the events on the current collection. /// protected virtual void UnsubscribeFromCameraRigsEvents() { if (CameraRigs == null) { return; } CameraRigs.Added.RemoveListener(OnCameraRigAdded); CameraRigs.Removed.RemoveListener(OnCameraRigRemoved); } /// /// Occurs when an item is added to the collection. /// /// The added element. protected virtual void OnCameraRigAdded(LinkedAliasAssociationCollection cameraRig) { RefreshCameraRigsConfiguration(); } /// /// Occurs when an item is removed from the collection. /// /// The removed element. protected virtual void OnCameraRigRemoved(LinkedAliasAssociationCollection cameraRig) { RefreshCameraRigsConfiguration(); } /// /// Refreshes any changes made to the collection. /// protected virtual void RefreshCameraRigsConfiguration() { Configuration.SetUpCameraRigsConfiguration(); } /// /// Gets the first active found in the given collection. /// /// The collection to look for the first active in. /// The found first active element in the collection. protected virtual GameObject GetFirstActiveGameObject(IEnumerable collection) { foreach (GameObject element in collection) { if (element.gameObject.activeInHierarchy) { return element; } } return null; } /// /// Gets the first active found in the given collection. /// /// The collection to look for the first active in. /// The found first active element in the collection. protected virtual Camera GetFirstActiveCamera(IEnumerable collection) { foreach (Camera element in collection) { if (element.gameObject.activeInHierarchy) { return element; } } return null; } /// /// Gets the first active found in the given collection. /// /// The collection to look for the first active in. /// The found first active element in the collection. protected virtual VelocityTracker GetFirstActiveVelocityTracker(IEnumerable collection) { foreach (VelocityTracker element in collection) { if (element.gameObject.activeInHierarchy) { return element; } } return null; } /// /// Called before has been changed. /// [CalledBeforeChangeOf(nameof(CameraRigs))] protected virtual void OnBeforeCameraRigsChange() { UnsubscribeFromCameraRigsEvents(); } /// /// Called after has been changed. /// [CalledAfterChangeOf(nameof(CameraRigs))] protected virtual void OnAfterCameraRigsChange() { SubscribeToCameraRigsEvents(); RefreshCameraRigsConfiguration(); } } }