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(); } } } }