using UnityEngine;
namespace XRMultiplayer
{
///
/// This class is used to represent the Avatar IK system in both the and the Offline Player"/>.
///
public class XRAvatarIK : MonoBehaviour
{
///
/// Transform for the Network Player Head.
///
[SerializeField, Tooltip("Transform for the Network Player Head.")] Transform m_HeadTransform;
///
/// Torso Parent Transform.
///
[SerializeField, Tooltip("Torso Parent Transform.")] Transform m_TorsoParentTransform;
///
/// Root of the Head Visuals.
///
[SerializeField, Tooltip("Root of the Head Visuals.")] Transform m_HeadVisualsRoot;
///
/// Neck Transform.
///
[SerializeField, Tooltip("Neck Transform.")] Transform m_Neck;
///
/// Offset to be applied to the head height.
///
[SerializeField, Tooltip("Offset to be applied to the head height.")] float m_HeadHeightOffset = .3f;
///
/// Theshold to where body rotation appoximation is applied.
///
[Range(0, 360.0f)]
[SerializeField, Tooltip("Theshold to where body rotation appoximation is applied.")] float m_RotateThreshold = 25.0f;
///
/// Speed at which the body rotates.
///
[SerializeField, Tooltip("Speed at which the body rotates.")] float m_RotateSpeed = 3.0f;
///
/// Transform associated with this script.
///
Transform m_Transform;
///
/// Rotation destination for the Y euler value.
///
float m_DestinationY;
///
private void Start()
{
m_Transform = GetComponent();
m_DestinationY = m_HeadTransform.transform.eulerAngles.y;
}
///
private void Update()
{
// Update Head.
m_HeadVisualsRoot.position = m_HeadTransform.position;
m_HeadVisualsRoot.position -= m_HeadTransform.up * m_HeadHeightOffset;
m_Neck.rotation = m_HeadTransform.rotation;
// Update Body.
m_Transform.position = m_HeadTransform.position;
m_TorsoParentTransform.rotation = Quaternion.Slerp(m_TorsoParentTransform.rotation, Quaternion.Euler(new Vector3(0, m_DestinationY, 0)), Time.deltaTime * m_RotateSpeed);
// Rotate Body if past threshold.
if (Mathf.Abs(m_TorsoParentTransform.eulerAngles.y - m_HeadTransform.eulerAngles.y) >= m_RotateThreshold)
{
m_DestinationY = m_HeadTransform.transform.eulerAngles.y;
}
// Update scale.
m_HeadVisualsRoot.localScale = m_HeadTransform.localScale;
}
}
}