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