using System;
using UnityEngine.InputSystem;
using UnityEngine.XR.Interaction.Toolkit.Utilities;
using UnityEngine.XR.Interaction.Toolkit.Utilities.Internal;
namespace UnityEngine.XR.Interaction.Toolkit.Inputs.Haptics
{
///
/// Serializable haptic impulse provider that allows for specifying the output channel or device for haptic impulses.
/// Behaviors can declare a field of this type to allow them to output haptic impulses to a controller specified by
/// an input action or any other source capable of returning a group of haptic channels.
///
[Serializable]
public class XRInputHapticImpulseProvider : IXRHapticImpulseProvider
{
///
/// The mode that determines from which input source to get the haptic channels.
///
///
public enum InputSourceMode
{
///
/// Haptics are explicitly not used.
/// Set to this mode to avoid any performance cost when haptics are not needed.
///
Unused,
///
/// The output channel or device is identified by an input action defined and serialized with this behavior.
///
///
///
///
InputAction,
///
/// The output channel or device is identified by an input action defined in the project.
/// This is the default mode.
///
///
InputActionReference,
///
/// The haptic channels are sourced from an object reference that implements .
///
ObjectReference,
}
[SerializeField]
InputSourceMode m_InputSourceMode = InputSourceMode.InputActionReference;
///
/// The mode that determines from which input source to get the haptic channels.
/// By default this is set to to read from an input action
/// defined in the project.
///
///
public InputSourceMode inputSourceMode
{
get => m_InputSourceMode;
set => m_InputSourceMode = value;
}
[SerializeField]
InputAction m_InputAction;
///
/// The directly serialized embedded input action that is read to identify the output channels of a device
/// when the mode is set to .
///
public InputAction inputAction
{
get => m_InputAction;
set => m_InputAction = value;
}
[SerializeField]
InputActionReference m_InputActionReference;
///
/// The reference to an input action that is read to identify the output channels of a device
/// when the mode is set to .
///
public InputActionReference inputActionReference
{
get => m_InputActionReference;
set => m_InputActionReference = value;
}
[SerializeField]
[RequireInterface(typeof(IXRHapticImpulseProvider))]
Object m_ObjectReferenceObject;
readonly UnityObjectReferenceCache m_ObjectReference = new UnityObjectReferenceCache();
HapticControlActionManager m_HapticControlActionManager;
///
/// Initializes and returns an instance of .
///
public XRInputHapticImpulseProvider()
{
}
///
/// Initializes and returns an instance of .
///
/// The name of the directly serialized embedded input action.
/// Whether the action should start performing if already actuated when the action is enabled.
/// The initial input source mode.
public XRInputHapticImpulseProvider(string name = null, bool wantsInitialStateCheck = false, InputSourceMode inputSourceMode = InputSourceMode.InputActionReference)
{
m_InputAction = InputActionUtility.CreatePassThroughAction(name: name, wantsInitialStateCheck: wantsInitialStateCheck);
m_InputSourceMode = inputSourceMode;
}
///
/// Enable the directly serialized embedded input action if the mode is set to .
///
///
public void EnableDirectActionIfModeUsed()
{
if (m_InputSourceMode == InputSourceMode.InputAction)
m_InputAction.Enable();
}
///
/// Disable the directly serialized embedded input action if the mode is set to .
///
///
public void DisableDirectActionIfModeUsed()
{
if (m_InputSourceMode == InputSourceMode.InputAction)
m_InputAction.Disable();
}
///
/// Gets the object reference that is used as the input source to identify the output channels of a device
/// when the mode is set to .
///
/// Returns the object reference, which may be .
public IXRHapticImpulseProvider GetObjectReference()
{
return m_ObjectReference.Get(m_ObjectReferenceObject);
}
///
/// Sets the object reference that is used as the input source to identify the output channels of a device
/// when the mode is set to .
///
/// The object reference.
///
/// If the argument is to be serialized, it must be a Unity type.
///
public void SetObjectReference(IXRHapticImpulseProvider value)
{
m_ObjectReference.Set(ref m_ObjectReferenceObject, value);
}
///
public IXRHapticImpulseChannelGroup GetChannelGroup()
{
switch (m_InputSourceMode)
{
case InputSourceMode.Unused:
default:
return null;
case InputSourceMode.InputAction:
m_HapticControlActionManager ??= new HapticControlActionManager();
return m_HapticControlActionManager.GetChannelGroup(m_InputAction);
case InputSourceMode.InputActionReference:
if (m_InputActionReference != null)
{
m_HapticControlActionManager ??= new HapticControlActionManager();
return m_HapticControlActionManager.GetChannelGroup(m_InputActionReference.action);
}
return null;
case InputSourceMode.ObjectReference:
return GetObjectReference()?.GetChannelGroup();
}
}
}
}