using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.XR.Interaction.Toolkit.Samples.StarterAssets;
namespace UnityEngine.XR.Content.Interaction
{
///
/// Use this class as a central manager to configure locomotion control schemes and configuration preferences.
///
public class LocomotionManager : MonoBehaviour
{
const ContinuousMoveProviderBase.GravityApplicationMode k_DefaultGravityApplicationMode =
ContinuousMoveProviderBase.GravityApplicationMode.AttemptingMove;
const ConstrainedMoveProvider.GravityApplicationMode k_DefaultGravityMode =
ConstrainedMoveProvider.GravityApplicationMode.AttemptingMove;
///
/// Sets which movement control scheme to use.
///
///
///
public enum LocomotionType
{
///
/// Use smooth (continuous) movement control scheme.
///
MoveAndStrafe,
///
/// Use teleport movement control scheme.
///
TeleportAndTurn,
}
///
/// Sets which turn style of locomotion to use.
///
///
///
public enum TurnStyle
{
///
/// Use snap turning to rotate the direction you are facing by snapping by a specified angle.
///
Snap,
///
/// Use continuous turning to smoothly rotate the direction you are facing by a specified speed.
///
Smooth,
}
[SerializeField]
[Tooltip("Stores the locomotion provider for smooth (continuous) movement.")]
DynamicMoveProvider m_DynamicMoveProvider;
///
/// Stores the locomotion provider for smooth (continuous) movement.
///
///
public DynamicMoveProvider dynamicMoveProvider
{
get => m_DynamicMoveProvider;
set => m_DynamicMoveProvider = value;
}
[SerializeField]
[Tooltip("Stores the locomotion provider for smooth (continuous) turning.")]
ContinuousTurnProviderBase m_SmoothTurnProvider;
///
/// Stores the locomotion provider for smooth (continuous) turning.
///
///
public ContinuousTurnProviderBase smoothTurnProvider
{
get => m_SmoothTurnProvider;
set => m_SmoothTurnProvider = value;
}
[SerializeField]
[Tooltip("Stores the locomotion provider for snap turning.")]
SnapTurnProviderBase m_SnapTurnProvider;
///
/// Stores the locomotion provider for snap turning.
///
///
public SnapTurnProviderBase snapTurnProvider
{
get => m_SnapTurnProvider;
set => m_SnapTurnProvider = value;
}
[SerializeField]
[Tooltip("Stores the locomotion provider for two-handed grab movement.")]
TwoHandedGrabMoveProvider m_TwoHandedGrabMoveProvider;
///
/// Stores the locomotion provider for two-handed grab movement.
///
///
public TwoHandedGrabMoveProvider twoHandedGrabMoveProvider
{
get => m_TwoHandedGrabMoveProvider;
set => m_TwoHandedGrabMoveProvider = value;
}
[SerializeField]
[Tooltip("Reference to the manager that mediates the left-hand controllers.")]
ActionBasedControllerManager m_LeftHandManager;
[SerializeField]
[Tooltip("Reference to the manager that mediates the right-hand controllers.")]
ActionBasedControllerManager m_RightHandManager;
[SerializeField]
[Tooltip("Controls which movement control scheme to use for the left hand.")]
LocomotionType m_LeftHandLocomotionType;
///
/// Controls which movement control scheme to use for the left hand.
///
///
public LocomotionType leftHandLocomotionType
{
get => m_LeftHandLocomotionType;
set
{
SetMoveScheme(value, true);
m_LeftHandLocomotionType = value;
}
}
[SerializeField]
[Tooltip("Controls which movement control scheme to use for the right hand.")]
LocomotionType m_RightHandLocomotionType;
///
/// Controls which movement control scheme to use for the left hand.
///
///
public LocomotionType rightHandLocomotionType
{
get => m_RightHandLocomotionType;
set
{
SetMoveScheme(value, false);
m_RightHandLocomotionType = value;
}
}
[SerializeField]
[Tooltip("Controls which turn style of locomotion to use for the left hand.")]
TurnStyle m_LeftHandTurnStyle;
///
/// Controls which turn style of locomotion to use for the left hand.
///
///
public TurnStyle leftHandTurnStyle
{
get => m_LeftHandTurnStyle;
set
{
SetTurnStyle(value, true);
m_LeftHandTurnStyle = value;
}
}
[SerializeField]
[Tooltip("Controls which turn style of locomotion to use for the right hand.")]
TurnStyle m_RightHandTurnStyle;
///
/// Controls which turn style of locomotion to use for the left hand.
///
///
public TurnStyle rightHandTurnStyle
{
get => m_RightHandTurnStyle;
set
{
SetTurnStyle(value, false);
m_RightHandTurnStyle = value;
}
}
[SerializeField]
[Tooltip("Whether to enable the comfort mode that applies the tunneling vignette effect to smooth movement and turn.")]
bool m_EnableComfortMode;
public bool enableComfortMode
{
get => m_EnableComfortMode;
set
{
m_EnableComfortMode = value;
if (m_ComfortMode != null)
m_ComfortMode.SetActive(m_EnableComfortMode);
}
}
[SerializeField]
[Tooltip("Stores the GameObject for the comfort mode.")]
GameObject m_ComfortMode;
[SerializeField]
[Tooltip("Whether gravity affects continuous and grab movement when flying is disabled.")]
bool m_UseGravity;
///
/// Whether gravity affects continuous and grab movement when flying is disabled.
///
public bool useGravity
{
get => m_UseGravity;
set
{
m_UseGravity = value;
m_DynamicMoveProvider.useGravity = value;
m_TwoHandedGrabMoveProvider.useGravity = value;
m_TwoHandedGrabMoveProvider.leftGrabMoveProvider.useGravity = value;
m_TwoHandedGrabMoveProvider.rightGrabMoveProvider.useGravity = value;
if (value)
{
m_DynamicMoveProvider.gravityApplicationMode = k_DefaultGravityApplicationMode;
m_TwoHandedGrabMoveProvider.gravityMode = k_DefaultGravityMode;
m_TwoHandedGrabMoveProvider.leftGrabMoveProvider.gravityMode = k_DefaultGravityMode;
m_TwoHandedGrabMoveProvider.rightGrabMoveProvider.gravityMode = k_DefaultGravityMode;
}
}
}
[SerializeField]
[Tooltip("Whether to enable flying for continuous and grab movement. This overrides the use of gravity.")]
bool m_EnableFly;
///
/// Whether to enable flying for continuous and grab movement. This overrides the use of gravity.
///
public bool enableFly
{
get => m_EnableFly;
set
{
m_EnableFly = value;
m_DynamicMoveProvider.enableFly = value;
m_TwoHandedGrabMoveProvider.enableFreeYMovement = value;
m_TwoHandedGrabMoveProvider.leftGrabMoveProvider.enableFreeYMovement = value;
m_TwoHandedGrabMoveProvider.rightGrabMoveProvider.enableFreeYMovement = value;
}
}
[SerializeField]
[Tooltip("Whether to enable grab movement.")]
bool m_EnableGrabMovement;
///
/// Whether to enable grab movement.
///
public bool enableGrabMovement
{
get => m_EnableGrabMovement;
set
{
m_EnableGrabMovement = value;
m_TwoHandedGrabMoveProvider.enabled = value;
m_TwoHandedGrabMoveProvider.leftGrabMoveProvider.enabled = value;
m_TwoHandedGrabMoveProvider.rightGrabMoveProvider.enabled = value;
}
}
void OnEnable()
{
SetMoveScheme(m_LeftHandLocomotionType, true);
SetMoveScheme(m_RightHandLocomotionType, false);
SetTurnStyle(m_LeftHandTurnStyle, true);
SetTurnStyle(m_RightHandTurnStyle, false);
if (m_ComfortMode != null)
m_ComfortMode.SetActive(m_EnableComfortMode);
m_DynamicMoveProvider.useGravity = m_UseGravity;
m_TwoHandedGrabMoveProvider.useGravity = m_UseGravity;
m_TwoHandedGrabMoveProvider.leftGrabMoveProvider.useGravity = m_UseGravity;
m_TwoHandedGrabMoveProvider.rightGrabMoveProvider.useGravity = m_UseGravity;
if (m_UseGravity)
{
m_DynamicMoveProvider.gravityApplicationMode = k_DefaultGravityApplicationMode;
m_TwoHandedGrabMoveProvider.gravityMode = k_DefaultGravityMode;
m_TwoHandedGrabMoveProvider.leftGrabMoveProvider.gravityMode = k_DefaultGravityMode;
m_TwoHandedGrabMoveProvider.rightGrabMoveProvider.gravityMode = k_DefaultGravityMode;
}
m_DynamicMoveProvider.enableFly = m_EnableFly;
m_TwoHandedGrabMoveProvider.enableFreeYMovement = m_EnableFly;
m_TwoHandedGrabMoveProvider.leftGrabMoveProvider.enableFreeYMovement = m_EnableFly;
m_TwoHandedGrabMoveProvider.rightGrabMoveProvider.enableFreeYMovement = m_EnableFly;
m_TwoHandedGrabMoveProvider.enabled = m_EnableGrabMovement;
m_TwoHandedGrabMoveProvider.leftGrabMoveProvider.enabled = m_EnableGrabMovement;
m_TwoHandedGrabMoveProvider.rightGrabMoveProvider.enabled = m_EnableGrabMovement;
}
void SetMoveScheme(LocomotionType scheme, bool leftHand)
{
var targetHand = leftHand ? m_LeftHandManager : m_RightHandManager;
targetHand.smoothMotionEnabled = (scheme == LocomotionType.MoveAndStrafe);
}
void SetTurnStyle(TurnStyle style, bool leftHand)
{
var targetHand = leftHand ? m_LeftHandManager : m_RightHandManager;
targetHand.smoothTurnEnabled = (style == TurnStyle.Smooth);
}
}
}