using System; using Unity.XR.CoreUtils; using UnityEngine.XR.Interaction.Toolkit.Locomotion; using UnityEngine.XR.Interaction.Toolkit.Utilities; namespace UnityEngine.XR.Interaction.Toolkit { /// /// (Deprecated) Controls a height and center position based on the camera's (HMD) /// position upon locomotion events of a (typically the continuous movement provider). /// /// /// is deprecated. Instead set /// to on the instance of in the scene, and then, if at runtime, /// re-enable the Body Transformer to make the locomotion system drive the . /// [AddComponentMenu("XR/Locomotion/Legacy/Character Controller Driver", 11)] [HelpURL(XRHelpURLConstants.k_CharacterControllerDriver)] [Obsolete("CharacterControllerDriver is deprecated in XRI 3.0.0 and will be removed in a future release. Instead set useCharacterControllerIfExists to true on the instance of XRBodyTransformer in the scene, and then, if at runtime, re-enable the Body Transformer to make the locomotion system drive the CharacterController.", false)] public class CharacterControllerDriver : MonoBehaviour { [SerializeField] [Tooltip("The Locomotion Provider object to listen to.")] LocomotionProvider m_LocomotionProvider; /// /// (Deprecated) The object to listen to. /// public LocomotionProvider locomotionProvider { get => m_LocomotionProvider; set { Unsubscribe(m_LocomotionProvider); m_LocomotionProvider = value; Subscribe(m_LocomotionProvider); SetupCharacterController(); UpdateCharacterController(); } } [SerializeField] [Tooltip("The minimum height of the character's capsule that will be set by this behavior.")] float m_MinHeight; /// /// (Deprecated) The minimum height of the character's capsule that this behavior sets. /// /// /// public float minHeight { get => m_MinHeight; set => m_MinHeight = value; } [SerializeField] [Tooltip("The maximum height of the character's capsule that will be set by this behavior.")] float m_MaxHeight = float.PositiveInfinity; /// /// (Deprecated) The maximum height of the character's capsule that this behavior sets. /// /// /// public float maxHeight { get => m_MaxHeight; set => m_MaxHeight = value; } XROrigin m_XROrigin; /// /// (Deprecated) (Read Only) The used for driving the . /// protected XROrigin xrOrigin => m_XROrigin; /// /// (Read Only) The used for driving the . /// [Obsolete("xrRig has been deprecated. Use xrOrigin instead.", true)] protected XRRig xrRig => default; CharacterController m_CharacterController; /// /// (Deprecated) (Read Only) The that this class drives. /// protected CharacterController characterController => m_CharacterController; /// /// See . /// protected void Awake() { if (m_LocomotionProvider == null) { m_LocomotionProvider = GetComponent(); if (m_LocomotionProvider == null) { m_LocomotionProvider = ComponentLocatorUtility.FindComponent(); if (m_LocomotionProvider == null) Debug.LogWarning("Unable to drive properties of the Character Controller without the locomotion events of a Locomotion Provider." + " Set Locomotion Provider or ensure a Continuous Move Provider component is in your scene.", this); } } } /// /// See . /// protected void OnEnable() { Subscribe(m_LocomotionProvider); } /// /// See . /// protected void OnDisable() { Unsubscribe(m_LocomotionProvider); } /// /// See . /// protected void Start() { SetupCharacterController(); UpdateCharacterController(); } /// /// (Deprecated) Updates the and /// based on the camera's position. /// protected virtual void UpdateCharacterController() { if (m_XROrigin == null || m_CharacterController == null) return; var height = Mathf.Clamp(m_XROrigin.CameraInOriginSpaceHeight, m_MinHeight, m_MaxHeight); Vector3 center = m_XROrigin.CameraInOriginSpacePos; center.y = height / 2f + m_CharacterController.skinWidth; m_CharacterController.height = height; m_CharacterController.center = center; } void Subscribe(LocomotionProvider provider) { if (provider != null) { provider.beginLocomotion += OnBeginLocomotion; provider.endLocomotion += OnEndLocomotion; } } void Unsubscribe(LocomotionProvider provider) { if (provider != null) { provider.beginLocomotion -= OnBeginLocomotion; provider.endLocomotion -= OnEndLocomotion; } } void SetupCharacterController() { if (m_LocomotionProvider == null || m_LocomotionProvider.system == null) return; m_XROrigin = m_LocomotionProvider.system.xrOrigin; #pragma warning disable IDE0031 // Use null propagation -- Do not use for UnityEngine.Object types m_CharacterController = m_XROrigin != null ? m_XROrigin.Origin.GetComponent() : null; #pragma warning restore IDE0031 if (m_CharacterController == null && m_XROrigin != null) { Debug.LogError($"Could not get CharacterController on {m_XROrigin.Origin}, unable to drive properties." + $" Ensure there is a CharacterController on the \"Rig\" GameObject of {m_XROrigin}.", this); } } void OnBeginLocomotion(LocomotionSystem system) { UpdateCharacterController(); } void OnEndLocomotion(LocomotionSystem system) { UpdateCharacterController(); } } }