// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) VRMADA, All rights reserved. // // -------------------------------------------------------------------------------------------------------------------- using System; using System.Collections.Generic; using UltimateXR.Core; using UltimateXR.Devices.Visualization; using UltimateXR.Haptics; using UltimateXR.Manipulation; using UnityEngine; namespace UltimateXR.Devices { /// /// Controller interface for all XR input devices, supporting single controller and dual controller setups. /// public interface IUxrControllerInput : IUxrDevice { #region Public Types & Data /// /// Event called right before the controller input state is updated. /// event EventHandler Updating; /// /// Event called right after the controller input state has been updated. /// event EventHandler Updated; /// /// Event called after a controller button state changed. /// event EventHandler ButtonStateChanged; /// /// Event called after a element changed. /// event EventHandler Input1DChanged; /// /// Event called after a element changed. /// event EventHandler Input2DChanged; /// /// Event called right before haptic feedback was requested. /// event EventHandler HapticRequesting; /// /// Gets the setup type. See . /// UxrControllerSetupType SetupType { get; } /// /// /// Gets whether can be used. In devices, it /// may be used to control which hand is holding the controller. In /// devices it is used to determine which hands have the (dominant) and /// (non-dominant) roles. /// /// Devices such as gamepads don't support handedness and will target the single device no matter which /// is used. In this case it is good practice to use to target the /// device in order to make the code cleaner. /// bool IsHandednessSupported { get; } /// /// /// Gets which hand is holding the controller in setups where /// is available. In setups /// it identifies the dominant hand. In both cases, determines which hand it is. /// /// In devices where handedness is not applicable ( /// is false) it is good practice to use to address the /// device, even if both left and right can too. /// /// UxrHandSide Primary { get; } /// /// Gets which hand is not holding the controller in setups where /// is available. In setups /// it identifies the non-dominant hand. /// /// UxrHandSide Secondary { get; } /// /// Gets the left controller name, or empty if not connected / doesn't exist. In /// configurations where is not /// available, both sides will return the same name. /// string LeftControllerName { get; } /// /// Gets the right controller name, or empty if not connected / doesn't exist. In /// configurations where is not /// available, both sides will return the same name. /// string RightControllerName { get; } /// /// Gets the left instanced 3D controller model, if available. In /// configurations where is false, both sides will return the same model. /// UxrController3DModel LeftController3DModel { get; } /// /// Gets the right instanced 3D controller model, if available. In /// configurations where is false, both sides will return the same model. /// UxrController3DModel RightController3DModel { get; } /// /// Gets a value indicating whether the main two-axis input element is a touchpad. If false, it usually means the main /// joystick is a thumbstick. /// bool MainJoystickIsTouchpad { get; } /// /// Gets the controller's joystick dead zone [0.0, 1.0]. Some controllers may have a more sensitive joystick, /// and this property can be used to compensate in different implementations. /// float JoystickDeadZone { get; } /// /// /// Gets or sets the handedness, which is the -dominant- hand in /// controller setups. In /// controller setups where the controller is grabbed with one hand, it determines which hand is being used. /// /// If false, such as in gamepads, the handedness value should be ignored. /// /// /// /// UxrHandSide Handedness { get; set; } #endregion #region Public Methods /// /// Checks whether the given controller is enabled. /// /// /// Which controller to check. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Whether the given controller is enabled bool IsControllerEnabled(UxrHandSide handSide); /// /// Checks if the given controller has specific elements. /// /// /// Which controller to check. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Flags indicating the element(s) to look for /// True if the controller has all the elements specified. If one is missing, it will return false bool HasControllerElements(UxrHandSide handSide, UxrControllerElements controllerElements); /// /// Gets the capabilities of the XR controller. /// /// /// Which controller to check. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Device capabilities flags UxrControllerInputCapabilities GetControllerCapabilities(UxrHandSide handSide); /// /// Gets the state of an analog controller input element. /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Element to get the input from /// Whether to return ignored input by /// Input value [0.0, 1.0] float GetInput1D(UxrHandSide handSide, UxrInput1D input1D, bool getIgnoredInput = false); /// /// Gets the state of a 2D input element (joystick, touchpad...). /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Element to get the input from /// Whether to return ignored input by /// /// Vector2 telling the state of the controller element. Each component between [-1.0, 1.0] /// Vector2 GetInput2D(UxrHandSide handSide, UxrInput2D input2D, bool getIgnoredInput = false); /// /// Gets an uint value representing touch states for each the controller flags in the /// current frame. /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Whether to return ignored input by /// Button flags representing touch states for each controller button in the current frame /// uint GetButtonTouchFlags(UxrHandSide handSide, bool getIgnoredInput = false); /// /// Gets an uint value representing touch states for each the controller flags in the /// last frame. /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Whether to return ignored input by /// Button flags representing touch states for each controller button in the last frame /// uint GetButtonTouchFlagsLastFrame(UxrHandSide handSide, bool getIgnoredInput = false); /// /// Gets an uint value representing press states for each the controller flags in the /// current frame. /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Whether to return ignored input by /// Button flags representing press states for each controller button in the current frame /// uint GetButtonPressFlags(UxrHandSide handSide, bool getIgnoredInput = false); /// /// Gets an uint value representing press states for each the in the last frame. /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Whether to return ignored input by /// Button flags representing press states for each controller button in the last frame /// uint GetButtonPressFlagsLastFrame(UxrHandSide handSide, bool getIgnoredInput = false); /// /// Checks if a given input event took place for a button or all buttons in a set in the current frame. /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// /// Button (or buttons by flag composition) to check. If it's a combination, all buttons require to /// meet the event criteria /// /// Input event type to check for /// Whether to return ignored input by /// /// True if the given event happened during the current frame for the specified button. If more than one button /// was specified by using flags it will return true only if the input event happened for all the given buttons. /// bool GetButtonsEvent(UxrHandSide handSide, UxrInputButtons buttons, UxrButtonEventType buttonEventType, bool getIgnoredInput = false); /// /// Checks if a given input event took place for a button or any button in a set in the current frame. /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// /// Button (or buttons by flag composition) to check. If it's a combination, any button that meets /// the event criteria will be enough /// /// Input event type to check for /// Whether to return ignored input by /// /// True if the given event happened during the current frame for the specified button. If more than one button /// was specified by using flags it will return true as long as any button had the event. /// bool GetButtonsEventAny(UxrHandSide handSide, UxrInputButtons buttons, UxrButtonEventType buttonEventType, bool getIgnoredInput = false); /// /// Checks if the given button or all buttons in a set are being touched in the current frame. /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Button (or buttons by flag composition) to check /// Whether to return ignored input by /// /// True if the given button is being touched in the current frame. If more than one button was specified by using /// flags it will return true only if all are being touched. /// bool GetButtonsTouch(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false); /// /// Checks if the given button or any button in a set is being touched in the current frame. /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Button (or buttons by flag composition) to check /// Whether to return ignored input by /// /// True if the given button is being touched in the current frame. If more than one button was specified by using /// flags it will return true if any button in the set is being touched. /// bool GetButtonsTouchAny(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false); /// /// Checks if the given button or buttons are being touched in the current frame but weren't the previous frame /// (touch-down). /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Button (or buttons by flag composition) to check /// Whether to return ignored input by /// /// True if the given button is just started being touched in the current frame. If more than one button was specified /// by using flags it will return true only if all meet the condition. /// bool GetButtonsTouchDown(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false); /// /// Checks if the given button or any button in a set is being touched in the current frame but not in the previous /// frame (touch-down). /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Button (or buttons by flag composition) to check /// Whether to return ignored input by /// /// True if the given button is just started being touched in the current frame. If more than one button was specified /// by using flags it will return true if any meets the condition. /// bool GetButtonsTouchDownAny(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false); /// /// Checks if the given button or buttons aren't being touched in the current frame but were during the previous frame /// (release touch). /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Button (or buttons by flag composition) to check /// Whether to return ignored input by /// /// True if the given button is being released from touching in the current frame. If more than one button was /// specified by using flags it will return true only if all meet the condition. /// bool GetButtonsTouchUp(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false); /// /// Checks if the given button or any button in a set isn't being touched in the current frame but was during the /// previous frame (release touch). /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Button (or buttons by flag composition) to check /// Whether to return ignored input by /// /// True if the given button is being released from touching in the current frame. If more than one button was /// specified by using flags it will return true as long as any meets the condition. /// bool GetButtonsTouchUpAny(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false); /// /// Checks if the given button or buttons are being pressed in the current frame. /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Button (or buttons by flag composition) to check /// Whether to return ignored input by /// /// True if the given button is being pressed in the current frame. If more than one button was specified by using /// flags it will return true only if all are being pressed. /// bool GetButtonsPress(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false); /// /// Checks if the given button or any button in a set is being pressed in the current frame. /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Button (or buttons by flag composition) to check /// Whether to return ignored input by /// /// True if the given button is being pressed in the current frame. If more than one button was specified by using /// flags it will return true as long as any is being pressed. /// bool GetButtonsPressAny(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false); /// /// Checks if the given button or buttons are being pressed in the current frame but weren't the previous frame /// (press-down). /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Button (or buttons by flag composition) to check /// Whether to return ignored input by /// /// True if the given button is just started being pressed in the current frame. If more than one button was specified /// by using flags it will return true only if all meet the condition. /// bool GetButtonsPressDown(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false); /// /// Checks if the given button or any button in a set is being pressed in the current frame but wasn't the previous /// frame (press-down). /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Button (or buttons by flag composition) to check /// Whether to return ignored input by /// /// True if the given button is just started being pressed in the current frame. If more than one button was specified /// by using flags it will return true only if any meets the condition. /// bool GetButtonsPressDownAny(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false); /// /// Checks if the given button or buttons aren't being pressed in the current frame but were during the previous frame /// (release press). /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Button (or buttons by flag composition) to check /// Whether to return ignored input by /// /// True if the given button is being released from pressing in the current frame. If more than one button was /// specified by using flags it will return true only if all meet the condition. /// bool GetButtonsPressUp(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false); /// /// Checks if the given button or any button in a set isn't being pressed in the current frame but was during the /// previous frame (release press). /// /// /// Which controller to get input from. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Button (or buttons by flag composition) to check /// Whether to return ignored input by /// /// True if the given button is being released from pressing in the current frame. If more than one button was /// specified by using flags it will return true if any meets the condition. /// bool GetButtonsPressUpAny(UxrHandSide handSide, UxrInputButtons buttons, bool getIgnoredInput = false); /// /// Sends haptic feedback to a controller if the controller supports it. /// /// /// Which controller to send the haptic feedback to. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Clip to send void SendHapticFeedback(UxrHandSide handSide, UxrHapticClip hapticClip); /// /// Sends haptic feedback to a controller if the controller supports it. /// /// /// Which controller to send the haptic feedback to. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Frequency of the feedback in hz /// Amplitude of the feedback between range [0.0, 1.0] /// Feedback duration in seconds /// The mode (stop and override all current haptics or mix it with the current existing haptics) void SendHapticFeedback(UxrHandSide handSide, float frequency, float amplitude, float durationSeconds, UxrHapticMode hapticMode = UxrHapticMode.Mix); /// /// Sends a predefined haptic clip to a controller. /// /// /// Which controller to send the haptic feedback to. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// The clip type from a set of predefined clips /// The intensity of the haptic feedback /// The duration in seconds. A zero/negative value will use a default duration. /// Whether the clip will stop all currently playing haptics or mix with them public void SendHapticFeedback(UxrHandSide handSide, UxrHapticClipType clipType, float amplitude, float durationSeconds = -1.0f, UxrHapticMode hapticMode = UxrHapticMode.Mix); /// /// Sends haptic feedback to XR controllers that are being used to manipulate a grabbable object. /// Each hand associated to an XR controller that is grabbing the object will receive haptic feedback. /// /// Grabbable object /// Clip type to send /// Intensity of the haptic feedback /// Duration in seconds /// Override current haptic feedback or mix it? public void SendGrabbableHapticFeedback(UxrGrabbableObject grabbableObject, UxrHapticClipType clipType, float amplitude, float durationSeconds = -1.0f, UxrHapticMode hapticMode = UxrHapticMode.Mix); /// /// Sends haptic feedback to XR controllers that are being used to manipulate a grabbable object. /// Each hand associated to an XR controller that is grabbing the object will receive haptic feedback. /// /// Grabbable object /// Haptic clip to send public void SendGrabbableHapticFeedback(UxrGrabbableObject grabbableObject, UxrHapticClip hapticClip); /// /// Stops all current haptics in a given controller. /// /// /// Which controller to stop sending haptic feedback to. In devices where /// is false, such as in gamepads, both hands will address the single device. /// void StopHapticFeedback(UxrHandSide handSide); /// /// Gets the instanced controller 3D model for a given hand. /// /// /// Which controller to get the 3D model of. In devices where /// is false, such as in gamepads, both hands will address the single device. /// UxrController3DModel GetController3DModel(UxrHandSide handSide); /// /// Returns a list of GameObjects that represent parts of the instantiated controller. This can be useful /// to highlight buttons or other elements during tutorials. /// Functionality to make these elements blink is also provided by the framework. /// /// /// Which controller to get the elements of. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Element (or elements using flags) to retrieve the GameObject(s) for /// A list of GameObject, one for each element requested /// /// /// /// /// IEnumerable GetControllerElementsGameObjects(UxrHandSide handSide, UxrControllerElements controllerElements); /// /// Starts blinking one or more elements in a controller. This can be useful during tutorials to highlight which /// button(s) to press. /// /// /// Which controller. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Element (or elements using flags) that should blink /// /// Emission color use to blink. Usually it can be set to white with a mid alpha value to avoid /// too much brightness /// /// Blinks per second /// Duration in seconds that it should blink /// /// /// /// /// void StartControllerElementsBlinking(UxrHandSide handSide, UxrControllerElements controllerElements, Color emissionColor, float blinksPerSec = 3.0f, float durationSeconds = -1.0f); /// /// Stops controller elements to blink /// /// /// Which controller. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Element (or elements using flags) that should stop blinking /// /// /// /// /// void StopControllerElementsBlinking(UxrHandSide handSide, UxrControllerElements controllerElements); /// /// Stops all controller elements to blink /// /// /// Which controller. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// /// /// /// /// void StopAllBlinking(UxrHandSide handSide); /// /// Checks if any specific controller element is currently blinking /// /// /// Which controller. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Element (or elements using flags) that should be checked /// True if any of the given elements is blinking /// /// /// /// /// bool IsAnyControllerElementBlinking(UxrHandSide handSide, UxrControllerElements controllerElements); /// /// Checks if all elements of a specific controller element are currently blinking /// /// /// Which controller. In devices where /// is false, such as in gamepads, both hands will address the single device. /// /// Element (or elements using flags) that should be checked /// True if all of the given elements are blinking /// /// /// /// /// bool AreAllControllerElementsBlinking(UxrHandSide handSide, UxrControllerElements controllerElements); #endregion } }