using System;
using System.Collections.Generic;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.XR;
using UnityEngine.XR.Interaction.Toolkit.Inputs.Simulation.Hands;
#if XR_HANDS_1_1_OR_NEWER
using UnityEngine.XR.Hands;
#endif
namespace UnityEngine.XR.Interaction.Toolkit.Inputs.Simulation
{
public partial class XRDeviceSimulator
{
///
/// A hand expression that can be simulated by performing an input action.
///
[Serializable]
[Obsolete("XRDeviceSimulator.SimulatedHandExpression has been deprecated in XRI 3.1.0. Update the XR Device Simulator sample in Package Manager or use the unnested version of SimulatedHandExpression instead.")]
public class SimulatedHandExpression : ISerializationCallbackReceiver
{
[SerializeField]
[Tooltip("The unique name for the hand expression.")]
[Delayed]
string m_Name;
///
/// The name of the hand expression to simulate when the input action is performed.
///
public string name => m_ExpressionName.ToString();
[SerializeField]
[Tooltip("The input action to trigger the hand expression.")]
InputActionReference m_ToggleAction;
///
/// The input action reference to trigger this simulated hand expression.
///
public InputActionReference toggleAction => m_ToggleAction;
[SerializeField]
[Tooltip("The captured hand expression to simulate when the input action is performed.")]
HandExpressionCapture m_Capture;
///
/// The captured expression to simulate when the input action is performed.
///
internal HandExpressionCapture capture
{
get => m_Capture;
set => m_Capture = value;
}
HandExpressionName m_ExpressionName;
///
/// The name of the hand expression to simulate when the input action is performed.
/// Use this for a faster name identifier than comparing by name.
///
internal HandExpressionName expressionName
{
get => m_ExpressionName;
set => m_ExpressionName = value;
}
///
/// Sprite icon for the simulated hand expression.
///
public Sprite icon => m_Capture.icon;
Action m_Performed;
///
/// Event that is called when the input action for the simulated hand expression is performed.
///
///
/// Wraps the performed action of the in order to add a reference
/// to this class in the callback method signature.
///
public event Action performed
{
add
{
m_Performed += value;
if (!m_Subscribed)
{
m_Subscribed = true;
m_ToggleAction.action.performed += OnActionPerformed;
}
}
remove
{
m_Performed -= value;
if (m_Performed == null)
{
m_Subscribed = false;
m_ToggleAction.action.performed -= OnActionPerformed;
}
}
}
bool m_Subscribed;
///
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
m_Name = m_ExpressionName.ToString();
}
///
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
m_ExpressionName = new HandExpressionName(m_Name);
}
void OnActionPerformed(InputAction.CallbackContext context)
{
m_Performed?.Invoke(this, context);
}
}
///
/// The device mode of the left and right device.
///
///
[Obsolete("DeviceMode has been deprecated in XRI 3.1.0 due to being moved out XR Device Simulator. Use DeviceMode in the SimulatedDeviceLifecycleManager instead.")]
public enum DeviceMode
{
///
/// Motion controller mode.
///
Controller,
///
/// Tracked hand mode.
///
Hand,
}
[SerializeField]
[Obsolete("m_RestingHandExpressionCapture has been deprecated in XRI 3.1.0 and moved to SimulatedHandExpressionManager.")]
HandExpressionCapture m_RestingHandExpressionCapture;
[SerializeField]
[Tooltip("The list of hand expressions to simulate.")]
[Obsolete("m_SimulatedHandExpressions has been deprecated in XRI 3.1.0 and moved to SimulatedHandExpressionManager.")]
List m_SimulatedHandExpressions = new List();
///
/// The list of simulated hand expressions for the device simulator.
///
[Obsolete("simulatedHandExpressions has been deprecated in XRI 3.1.0. Update the XR Device Simulator sample in Package Manager or use simulatedHandExpressions in the SimulatedHandExpressionManager instead.")]
public List simulatedHandExpressions => m_SimulatedHandExpressions;
///
/// This boolean value indicates whether we remove other devices in this session so that they don't conflict with the .
/// A value (default) means we remove all other devices except the generated by the .
/// A value means we do not remove any other devices.
///
[Obsolete("removeOtherHMDDevices has been deprecated in XRI 3.1.0. Use removeOtherHMDDevices in the SimulatedDeviceLifecycleManager instead.")]
public bool removeOtherHMDDevices
{
get => m_DeviceLifecycleManager != null ? m_DeviceLifecycleManager.removeOtherHMDDevices : default;
set
{
if (m_DeviceLifecycleManager != null)
m_DeviceLifecycleManager.removeOtherHMDDevices = value;
else
_ = value;
}
}
///
/// Whether to create a simulated Hand Tracking Subsystem and provider on startup. Requires the XR Hands package.
///
[Obsolete("handTrackingCapability has been deprecated in XRI 3.1.0. Use handTrackingCapability in the SimulatedDeviceLifecycleManager instead.")]
public bool handTrackingCapability
{
get => m_DeviceLifecycleManager != null ? m_DeviceLifecycleManager.handTrackingCapability : default;
set
{
if (m_DeviceLifecycleManager != null)
m_DeviceLifecycleManager.handTrackingCapability = value;
else
_ = value;
}
}
///
/// Whether the simulator is in controller mode or tracked hand mode.
///
///
[Obsolete("deviceMode has been deprecated in XRI 3.1.0 due to being moved out XR Device Simulator. Use deviceMode in the SimulatedDeviceLifecycleManager instead.")]
public DeviceMode deviceMode => m_DeviceLifecycleManager != null ? (DeviceMode)m_DeviceLifecycleManager.deviceMode : default;
///
/// Add simulated XR devices to the Input System.
///
[Obsolete("AddDevices has been deprecated in XRI 3.1.0 and will be removed in a future release. It has instead been moved to the SimulatedDeviceLifecycleManager.", false)]
protected virtual void AddDevices()
{
if (m_DeviceLifecycleManager != null)
m_DeviceLifecycleManager.AddDevices();
else
Debug.LogError("No Simulated Device Lifecycle Manager has been found so AddDevices() will not be called.", this);
}
///
/// Remove simulated XR devices from the Input System.
///
[Obsolete("RemoveDevices has been deprecated in XRI 3.1.0 and will be removed in a future release. It has instead been moved to the SimulatedDeviceLifecycleManager.", false)]
protected virtual void RemoveDevices()
{
if (m_DeviceLifecycleManager != null)
m_DeviceLifecycleManager.RemoveDevices();
else
Debug.LogError("No Simulated Device Lifecycle Manager has been found so RemoveDevices() will not be called.", this);
}
[Obsolete("InitializeHandExpressions has been deprecated in XRI 3.1.0 and moved to SimulatedHandExpressionManager.")]
void InitializeHandExpressions()
{
#if XR_HANDS_1_1_OR_NEWER
if (m_DeviceLifecycleManager == null || m_DeviceLifecycleManager.simHandSubsystem == null || m_RestingHandExpressionCapture == null)
return;
// Pass the hand expression captures to the simulated hand subsystem
m_DeviceLifecycleManager.simHandSubsystem.SetCapturedExpression(HandExpressionName.Default, m_RestingHandExpressionCapture);
for (var index = 0; index < m_SimulatedHandExpressions.Count; ++index)
{
var simulatedExpression = m_SimulatedHandExpressions[index];
if (simulatedExpression.capture != null)
m_DeviceLifecycleManager.simHandSubsystem.SetCapturedExpression(simulatedExpression.expressionName, simulatedExpression.capture);
else
Debug.LogError($"Missing Capture reference for Simulated Hand Expression: {simulatedExpression.expressionName}", this);
}
#endif
}
#if XR_HANDS_1_1_OR_NEWER
[Obsolete("SubscribeHandExpressionActionsDeprecated has been deprecated in XRI 3.1.0 and replaced with SubscribeHandExpressionActions.")]
void SubscribeHandExpressionActionsDeprecated()
{
foreach (var simulatedExpression in m_SimulatedHandExpressions)
{
simulatedExpression.performed += OnHandExpressionPerformedDeprecated;
}
}
[Obsolete("UnsubscribeHandExpressionActionsDeprecated has been deprecated in XRI 3.1.0 and replaced with UnsubscribeHandExpressionActions.")]
void UnsubscribeHandExpressionActionsDeprecated()
{
foreach (var simulatedExpression in m_SimulatedHandExpressions)
{
simulatedExpression.performed -= OnHandExpressionPerformedDeprecated;
}
}
[Obsolete("OnHandExpressionPerformedDeprecated has been deprecated in XRI 3.1.0 and replaced with OnHandExpressionPerformed.")]
void OnHandExpressionPerformedDeprecated(SimulatedHandExpression simulatedExpression, InputAction.CallbackContext context)
{
ToggleHandExpressionDeprecated(simulatedExpression);
}
#endif
[Obsolete("ToggleHandExpressionDeprecated has been deprecated in XRI 3.1.0 and replaced with ToggleHandExpression.")]
void ToggleHandExpressionDeprecated(SimulatedHandExpression simulatedExpression)
{
#if XR_HANDS_1_1_OR_NEWER
if (m_DeviceLifecycleManager == null || m_DeviceLifecycleManager.simHandSubsystem == null)
return;
// When toggling off, change back to the default resting hand. Otherwise, change to the expression pressed.
if (manipulatingLeftHand)
{
m_LeftHandState.expressionName = m_LeftHandState.expressionName == simulatedExpression.expressionName
? HandExpressionName.Default
: simulatedExpression.expressionName;
m_DeviceLifecycleManager.simHandSubsystem.SetHandExpression(Handedness.Left, m_LeftHandState.expressionName);
}
if (manipulatingRightHand)
{
m_RightHandState.expressionName = m_RightHandState.expressionName == simulatedExpression.expressionName
? HandExpressionName.Default
: simulatedExpression.expressionName;
m_DeviceLifecycleManager.simHandSubsystem.SetHandExpression(Handedness.Right, m_RightHandState.expressionName);
}
#endif
}
}
}