VR4Medical/ICI/Library/PackageCache/com.unity.xr.interaction.toolkit@42ef3600567b/Runtime/Inputs/Haptics/XRInputHapticImpulseProvider.cs
2025-07-29 13:45:50 +03:00

188 lines
7.7 KiB
C#

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
{
/// <summary>
/// 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.
/// </summary>
[Serializable]
public class XRInputHapticImpulseProvider : IXRHapticImpulseProvider
{
/// <summary>
/// The mode that determines from which input source to get the haptic channels.
/// </summary>
/// <seealso cref="inputSourceMode"/>
public enum InputSourceMode
{
/// <summary>
/// Haptics are explicitly not used.
/// Set to this mode to avoid any performance cost when haptics are not needed.
/// </summary>
Unused,
/// <summary>
/// The output channel or device is identified by an input action defined and serialized with this behavior.
/// </summary>
/// <seealso cref="inputAction"/>
/// <seealso cref="EnableDirectActionIfModeUsed"/>
/// <seealso cref="DisableDirectActionIfModeUsed"/>
InputAction,
/// <summary>
/// The output channel or device is identified by an input action defined in the project.
/// This is the default mode.
/// </summary>
/// <seealso cref="InputActionReference"/>
InputActionReference,
/// <summary>
/// The haptic channels are sourced from an object reference that implements <see cref="IXRHapticImpulseProvider"/>.
/// </summary>
ObjectReference,
}
[SerializeField]
InputSourceMode m_InputSourceMode = InputSourceMode.InputActionReference;
/// <summary>
/// The mode that determines from which input source to get the haptic channels.
/// By default this is set to <see cref="InputSourceMode.InputActionReference"/> to read from an input action
/// defined in the project.
/// </summary>
/// <seealso cref="InputSourceMode"/>
public InputSourceMode inputSourceMode
{
get => m_InputSourceMode;
set => m_InputSourceMode = value;
}
[SerializeField]
InputAction m_InputAction;
/// <summary>
/// The directly serialized embedded input action that is read to identify the output channels of a device
/// when the mode is set to <see cref="InputSourceMode.InputAction"/>.
/// </summary>
public InputAction inputAction
{
get => m_InputAction;
set => m_InputAction = value;
}
[SerializeField]
InputActionReference m_InputActionReference;
/// <summary>
/// The reference to an input action that is read to identify the output channels of a device
/// when the mode is set to <see cref="InputSourceMode.InputActionReference"/>.
/// </summary>
public InputActionReference inputActionReference
{
get => m_InputActionReference;
set => m_InputActionReference = value;
}
[SerializeField]
[RequireInterface(typeof(IXRHapticImpulseProvider))]
Object m_ObjectReferenceObject;
readonly UnityObjectReferenceCache<IXRHapticImpulseProvider, Object> m_ObjectReference = new UnityObjectReferenceCache<IXRHapticImpulseProvider, Object>();
HapticControlActionManager m_HapticControlActionManager;
/// <summary>
/// Initializes and returns an instance of <see cref="XRInputHapticImpulseProvider"/>.
/// </summary>
public XRInputHapticImpulseProvider()
{
}
/// <summary>
/// Initializes and returns an instance of <see cref="XRInputHapticImpulseProvider"/>.
/// </summary>
/// <param name="name">The name of the directly serialized embedded input action.</param>
/// <param name="wantsInitialStateCheck">Whether the action should start performing if already actuated when the action is enabled.</param>
/// <param name="inputSourceMode">The initial input source mode.</param>
public XRInputHapticImpulseProvider(string name = null, bool wantsInitialStateCheck = false, InputSourceMode inputSourceMode = InputSourceMode.InputActionReference)
{
m_InputAction = InputActionUtility.CreatePassThroughAction(name: name, wantsInitialStateCheck: wantsInitialStateCheck);
m_InputSourceMode = inputSourceMode;
}
/// <summary>
/// Enable the directly serialized embedded input action if the mode is set to <see cref="InputSourceMode.InputAction"/>.
/// </summary>
/// <seealso cref="DisableDirectActionIfModeUsed"/>
public void EnableDirectActionIfModeUsed()
{
if (m_InputSourceMode == InputSourceMode.InputAction)
m_InputAction.Enable();
}
/// <summary>
/// Disable the directly serialized embedded input action if the mode is set to <see cref="InputSourceMode.InputAction"/>.
/// </summary>
/// <seealso cref="EnableDirectActionIfModeUsed"/>
public void DisableDirectActionIfModeUsed()
{
if (m_InputSourceMode == InputSourceMode.InputAction)
m_InputAction.Disable();
}
/// <summary>
/// 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 <see cref="InputSourceMode.ObjectReference"/>.
/// </summary>
/// <returns>Returns the object reference, which may be <see langword="null"/>.</returns>
public IXRHapticImpulseProvider GetObjectReference()
{
return m_ObjectReference.Get(m_ObjectReferenceObject);
}
/// <summary>
/// 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 <see cref="InputSourceMode.ObjectReference"/>.
/// </summary>
/// <param name="value">The object reference.</param>
/// <remarks>
/// If the argument is to be serialized, it must be a Unity <see cref="Object"/> type.
/// </remarks>
public void SetObjectReference(IXRHapticImpulseProvider value)
{
m_ObjectReference.Set(ref m_ObjectReferenceObject, value);
}
/// <inheritdoc />
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();
}
}
}
}