using System;
using UnityEngine.Assertions;
using UnityEngine.XR.Interaction.Toolkit.Inputs;
using UnityEngine.XR.Interaction.Toolkit.Locomotion;
namespace UnityEngine.XR.Interaction.Toolkit
{
///
/// Locomotion provider that allows the user to smoothly rotate their rig continuously over time.
///
///
///
[Obsolete("The ContinuousMoveProviderBase has been deprecated in XRI 3.0.0 and will be removed in a future version of XRI. Please use ContinuousTurnProvider instead.", false)]
public abstract class ContinuousTurnProviderBase : LocomotionProvider
{
[SerializeField]
[Tooltip("The number of degrees/second clockwise to rotate when turning clockwise.")]
float m_TurnSpeed = 60f;
///
/// The number of degrees/second clockwise to rotate when turning clockwise.
///
public float turnSpeed
{
get => m_TurnSpeed;
set => m_TurnSpeed = value;
}
bool m_IsTurningXROrigin;
///
/// See .
///
protected void Update()
{
m_IsTurningXROrigin = false;
// Use the input amount to scale the turn speed.
var input = ReadInput();
var turnAmount = GetTurnAmount(input);
TurnRig(turnAmount);
switch (locomotionPhase)
{
case LocomotionPhase.Idle:
case LocomotionPhase.Started:
if (m_IsTurningXROrigin)
locomotionPhase = LocomotionPhase.Moving;
break;
case LocomotionPhase.Moving:
if (!m_IsTurningXROrigin)
locomotionPhase = LocomotionPhase.Done;
break;
case LocomotionPhase.Done:
locomotionPhase = m_IsTurningXROrigin ? LocomotionPhase.Moving : LocomotionPhase.Idle;
break;
default:
Assert.IsTrue(false, $"Unhandled {nameof(LocomotionPhase)}={locomotionPhase}");
break;
}
}
///
/// Reads the current value of the turn input.
///
/// Returns the input vector, such as from a thumbstick.
protected abstract Vector2 ReadInput();
///
/// Determines the turn amount in degrees for the given vector.
///
/// Input vector, such as from a thumbstick.
/// Returns the turn amount in degrees for the given vector.
protected virtual float GetTurnAmount(Vector2 input)
{
if (input == Vector2.zero)
return 0f;
var cardinal = CardinalUtility.GetNearestCardinal(input);
switch (cardinal)
{
case Cardinal.North:
case Cardinal.South:
break;
case Cardinal.East:
case Cardinal.West:
return input.magnitude * (Mathf.Sign(input.x) * m_TurnSpeed * Time.deltaTime);
default:
Assert.IsTrue(false, $"Unhandled {nameof(Cardinal)}={cardinal}");
break;
}
return 0f;
}
///
/// Rotates the rig by degrees.
///
/// The amount of rotation in degrees.
protected void TurnRig(float turnAmount)
{
if (Mathf.Approximately(turnAmount, 0f))
return;
if (CanBeginLocomotion() && BeginLocomotion())
{
var xrOrigin = system.xrOrigin;
if (xrOrigin != null)
{
m_IsTurningXROrigin = true;
xrOrigin.RotateAroundCameraUsingOriginUp(turnAmount);
}
EndLocomotion();
}
}
}
}