1598 lines
67 KiB
C#
1598 lines
67 KiB
C#
#define VRIF
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
#if UNITY_2018_4_OR_NEWER
|
|
using UnityEngine.XR;
|
|
#endif
|
|
#if STEAM_VR_SDK
|
|
using Valve.VR;
|
|
#endif
|
|
|
|
namespace BNG {
|
|
|
|
#region Enums
|
|
public enum ControllerHand {
|
|
Left,
|
|
Right,
|
|
None
|
|
}
|
|
|
|
/// <summary>
|
|
/// Controller Options available to bind buttons to via Inspector. You can use GetControllerBindingValue() to determine if that button has been pressed.
|
|
/// </summary>
|
|
public enum ControllerBinding {
|
|
None,
|
|
AButton,
|
|
AButtonDown,
|
|
BButton,
|
|
BButtonDown,
|
|
XButton,
|
|
XButtonDown,
|
|
YButton,
|
|
YButtonDown,
|
|
LeftTrigger,
|
|
LeftTriggerDown,
|
|
LeftGrip,
|
|
LeftGripDown,
|
|
LeftThumbstick,
|
|
LeftThumbstickDown,
|
|
RightTrigger,
|
|
RightTriggerDown,
|
|
RightGrip,
|
|
RightGripDown,
|
|
RightThumbstick,
|
|
RightThumbstickDown,
|
|
StartButton,
|
|
StartButtonDown,
|
|
BackButton,
|
|
BackButtonDown
|
|
}
|
|
|
|
/// <summary>
|
|
/// Controller Options available to bind buttons to via Inspector. Input is relative to the controller holding it.
|
|
/// Ex : Button 1 = Button A if held in Right controller, Button X if held in Left.
|
|
/// </summary>
|
|
public enum GrabbedControllerBinding {
|
|
None,
|
|
Button1, // Button A, X
|
|
Button1Down,
|
|
Button2, // Button B, Y
|
|
Button2Down,
|
|
Trigger,
|
|
TriggerDown,
|
|
Grip,
|
|
GripDown
|
|
}
|
|
|
|
public enum InputAxis {
|
|
None,
|
|
LeftThumbStickAxis,
|
|
LeftTouchPadAxis,
|
|
RightThumbStickAxis,
|
|
RightTouchPadAxis
|
|
}
|
|
|
|
public enum ControllerType {
|
|
None,
|
|
Unknown,
|
|
OculusTouch,
|
|
Wand,
|
|
Knuckles
|
|
}
|
|
|
|
public enum HandControl {
|
|
LeftGrip,
|
|
RightGrip,
|
|
LeftTrigger,
|
|
RightTrigger,
|
|
None
|
|
}
|
|
|
|
public enum GrabButton {
|
|
Grip,
|
|
Trigger,
|
|
Inherit
|
|
}
|
|
|
|
public enum HoldType {
|
|
HoldDown, // Hold down the grab button
|
|
Toggle, // Click the grab button down to switch between hold and release
|
|
Inherit // Inherit from Grabber
|
|
}
|
|
|
|
public enum XRInputSource {
|
|
XRInput,
|
|
OVRInput,
|
|
SteamVR,
|
|
Pico,
|
|
UnityInput
|
|
}
|
|
|
|
public enum SDKProvider {
|
|
Unknown,
|
|
OculusSDK,
|
|
OpenVR
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// A proxy for handling input from various input providers such as OVRInput, XRInput, and SteamVR.
|
|
/// </summary>
|
|
public class InputBridge : MonoBehaviour {
|
|
|
|
#region Singleton
|
|
/// <summary>
|
|
/// Instance of our Singleton
|
|
/// </summary>
|
|
public static InputBridge Instance {
|
|
get {
|
|
if (_instance == null) {
|
|
_instance = FindObjectOfType<InputBridge>();
|
|
if (_instance == null) {
|
|
_instance = new GameObject("InputBridge").AddComponent<InputBridge>();
|
|
}
|
|
}
|
|
return _instance;
|
|
}
|
|
}
|
|
private static InputBridge _instance;
|
|
|
|
#endregion
|
|
|
|
#region Input Properties
|
|
[Header("Input Settings")]
|
|
[SerializeField]
|
|
public XRInputSource InputSource = XRInputSource.XRInput;
|
|
|
|
[SerializeField]
|
|
[Tooltip("Specify an InputActionSet for when using the Unity Input system. These actions will be enabled on load.")]
|
|
public UnityEngine.InputSystem.InputActionAsset actionSet;
|
|
|
|
[Header("Tracking Origin")]
|
|
[SerializeField]
|
|
[Tooltip("Set the TrackingOriginModeFlags on device connect. Should typically be set to 'Floor'")]
|
|
public TrackingOriginModeFlags TrackingOrigin = TrackingOriginModeFlags.Floor;
|
|
|
|
[Header("Thumbstick Deadzone")]
|
|
|
|
/// <summary>
|
|
/// Thumbstick X must be greater than this amount to be considered valid
|
|
/// </summary>
|
|
[Tooltip("Thumbstick X must be greater than this amount to be considered valid")]
|
|
public float ThumbstickDeadzoneX = 0.001f;
|
|
|
|
/// <summary>
|
|
/// Thumbstick Y must be greater than this amount to be considered valid
|
|
/// </summary>
|
|
[Tooltip("Thumbstick Y must be greater than this amount to be considered valid")]
|
|
public float ThumbstickDeadzoneY = 0.001f;
|
|
|
|
#endregion
|
|
|
|
#region Raw Inputs
|
|
|
|
[Header("Grip")]
|
|
/// <summary>
|
|
/// How far Left Grip is Held down. Values : 0 - 1 (Fully Open / Closed)
|
|
/// </summary>
|
|
public float LeftGrip = 0;
|
|
|
|
/// <summary>
|
|
/// Left Grip was pressed down this frame, but not last
|
|
/// </summary>
|
|
public bool LeftGripDown = false;
|
|
|
|
/// <summary>
|
|
/// How far Right Grip is Held down. Values : 0 - 1 (Fully Open / Closed)
|
|
/// </summary>
|
|
public float RightGrip = 0;
|
|
|
|
/// <summary>
|
|
/// Right Grip was pressed down this frame, but not last
|
|
/// </summary>
|
|
public bool RightGripDown = false;
|
|
|
|
[Header("Trigger")]
|
|
/// <summary>
|
|
/// How far Left Trigger is Held down. Values : 0 - 1 (Fully Open / Closed)
|
|
/// </summary>
|
|
public float LeftTrigger = 0;
|
|
public bool LeftTriggerNear = false;
|
|
public bool LeftTriggerUp = false;
|
|
|
|
/// <summary>
|
|
/// Returns true if Left Trigger was held down this frame but not the last
|
|
/// </summary>
|
|
public bool LeftTriggerDown = false;
|
|
|
|
/// <summary>
|
|
/// How far Left Trigger is Held down. Values : 0 - 1 (Fully Open / Closed)
|
|
/// </summary>
|
|
public float RightTrigger = 0;
|
|
|
|
/// <summary>
|
|
/// Returns true if Right Trigger is all the way up this frame but not last
|
|
/// </summary>
|
|
public bool RightTriggerUp = false;
|
|
|
|
/// <summary>
|
|
/// Returns true if Right Trigger was held down this frame but not the last
|
|
/// </summary>
|
|
public bool RightTriggerDown = false;
|
|
public bool RightTriggerNear = false;
|
|
|
|
public bool LeftThumbNear = false;
|
|
public bool RightThumbNear = false;
|
|
|
|
[Header("Thumbstick")]
|
|
/// <summary>
|
|
/// Pressed down this frame, but not last
|
|
/// </summary>
|
|
public bool LeftThumbstickDown = false;
|
|
|
|
/// <summary>
|
|
/// Released this frame but not last
|
|
/// </summary>
|
|
public bool LeftThumbstickUp = false;
|
|
|
|
/// <summary>
|
|
/// Pressed down this frame, but not last
|
|
/// </summary>
|
|
public bool RightThumbstickDown = false;
|
|
|
|
/// <summary>
|
|
/// Released this frame but not last
|
|
/// </summary>
|
|
public bool RightThumbstickUp = false;
|
|
|
|
/// <summary>
|
|
/// Currently Held Down
|
|
/// </summary>
|
|
public bool LeftThumbstick = false;
|
|
public bool RightThumbstick = false;
|
|
|
|
[Header("Buttons")]
|
|
/// <summary>
|
|
/// Is the A button currently being held down
|
|
/// </summary>
|
|
public bool AButton = false;
|
|
|
|
/// <summary>
|
|
/// Returns true if the A Button was pressed down this frame but not last
|
|
/// </summary>
|
|
[Tooltip("Returns true if the A Button was pressed down this frame but not last")]
|
|
public bool AButtonDown = false;
|
|
|
|
// A Button Up this frame but down the last
|
|
public bool AButtonUp = false;
|
|
|
|
/// <summary>
|
|
/// Is the B button currently being held down
|
|
/// </summary>
|
|
public bool BButton = false;
|
|
|
|
/// <summary>
|
|
/// Returns true if the B Button was pressed down this frame but not last
|
|
/// </summary>
|
|
[Tooltip("Returns true if the B Button was pressed down this frame but not last")]
|
|
public bool BButtonDown = false;
|
|
|
|
// B Button Up this frame but down the last
|
|
public bool BButtonUp = false;
|
|
|
|
public bool XButton = false;
|
|
|
|
/// <summary>
|
|
/// Returns true if the X Button was pressed down this frame but not last
|
|
/// </summary>
|
|
[Tooltip("Returns true if the X Button was pressed down this frame but not last")]
|
|
public bool XButtonDown = false;
|
|
|
|
// X Button Up this frame but down the last
|
|
public bool XButtonUp = false;
|
|
|
|
public bool YButton = false;
|
|
/// <summary>
|
|
/// Returns true if the Y Button was pressed down this frame but not last
|
|
/// </summary>
|
|
public bool YButtonDown = false;
|
|
public bool YButtonUp = false;
|
|
|
|
public bool StartButton = false;
|
|
public bool StartButtonDown = false;
|
|
public bool BackButton = false;
|
|
public bool BackButtonDown = false;
|
|
|
|
[Header("Axis")]
|
|
public Vector2 LeftThumbstickAxis;
|
|
public Vector2 RightThumbstickAxis;
|
|
|
|
public Vector2 LeftTouchPadAxis;
|
|
public Vector2 RightTouchPadAxis;
|
|
|
|
[Header("Finger Tracking")]
|
|
[Tooltip("SteamVR Only - Shows the curl value of the thumb. 0 = Fully extended, 1 = Fully Curled")]
|
|
public float LeftThumbCurl = 0f;
|
|
public float LeftIndexCurl = 0f;
|
|
public float LeftMiddleCurl = 0f;
|
|
public float LeftRingCurl = 0f;
|
|
public float LeftPinkyCurl = 0f;
|
|
|
|
[Tooltip("SteamVR Only - Shows the curl value of the thumb. 0 = Fully extended, 1 = Fully Curled")]
|
|
public float RightThumbCurl = 0f;
|
|
public float RightIndexCurl = 0f;
|
|
public float RightMiddleCurl = 0f;
|
|
public float RightRingCurl = 0f;
|
|
public float RightPinkyCurl = 0f;
|
|
|
|
#endregion
|
|
|
|
#region Device Properties
|
|
/// <summary>
|
|
/// What threshold constitutes a "down" event.
|
|
/// For example, pushing the trigger down 20% (0.2) of the way considered starting a trigger down event
|
|
/// This is used in XRInput
|
|
/// </summary>
|
|
public float DownThreshold {
|
|
get {
|
|
return _downThreshold;
|
|
}
|
|
}
|
|
private float _downThreshold = 0.2f;
|
|
|
|
bool SteamVRSupport = false;
|
|
|
|
[Header("HMD / Hardware")]
|
|
public ControllerType ConnectedControllerType;
|
|
|
|
[Tooltip("Is there an HMD present and in use.")]
|
|
public bool HMDActive
|
|
{
|
|
get => _hmdActive;
|
|
set
|
|
{
|
|
_hmdActive = value;
|
|
if (_hmdActive)
|
|
{
|
|
OnConnected?.Invoke();
|
|
}
|
|
else
|
|
{
|
|
OnDisconnected?.Invoke();
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool _hmdActive = false;
|
|
|
|
public UnityEvent OnConnected;
|
|
public UnityEvent OnDisconnected;
|
|
|
|
public SDKProvider LoadedSDK { get; private set; }
|
|
|
|
public bool IsOculusDevice { get; private set; }
|
|
|
|
public bool IsOculusQuest { get; private set; }
|
|
|
|
public bool IsHTCDevice { get; private set; }
|
|
|
|
public bool IsPicoDevice { get; private set; }
|
|
|
|
public bool IsValveIndexController { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Returns true if the controller has both a Touchpad and a Joystick. Currently only the Valve Index has both.
|
|
/// </summary>
|
|
[Tooltip("Returns true if the controller has both a Touchpad and a Joystick. Currently on the Valve Index has both.")]
|
|
public bool SupportsBothTouchPadAndJoystick;
|
|
|
|
/// <summary>
|
|
/// Returns true if the controllers support the 'indexTouch' (or 'near trigger') XR input mapping. Currently only Oculus devices on the Oculus SDK support index touch. OpenVR is not supported.
|
|
/// </summary>
|
|
[Tooltip("Returns true if the controllers support the 'indexTouch' XR input mapping. Currently only Oculus devices on the Oculus SDK support thumb touch. OpenVR is not supported.")]
|
|
public bool SupportsIndexTouch;
|
|
|
|
/// <summary>
|
|
/// Returns true if the controllers support the 'ThumbTouch' (or near thumbstick) XR input mapping. Currently only Oculus devices on the Oculus SDK support index touch. OpenVR is not supported.
|
|
/// </summary>
|
|
[Tooltip("Returns true if the controllers support the 'ThumbTouch' (or near thumbstick) XR input mapping. Currently only Oculus devices on the Oculus SDK support thumb touch. OpenVR is not supported.")]
|
|
public bool SupportsThumbTouch;
|
|
|
|
#if UNITY_2019_3_OR_NEWER
|
|
static List<InputDevice> devices = new List<InputDevice>();
|
|
#endif
|
|
|
|
#endregion
|
|
|
|
#region Events
|
|
// Events
|
|
/// <summary>
|
|
/// Called after update loop.
|
|
/// </summary>
|
|
public delegate void InputsUpdatedAction();
|
|
public static event InputsUpdatedAction OnInputsUpdated;
|
|
|
|
/// <summary>
|
|
/// Called once a controller has been successfully detected
|
|
/// </summary>
|
|
public delegate void ControllerFoundAction();
|
|
public static event ControllerFoundAction OnControllerFound;
|
|
|
|
#endregion
|
|
|
|
#region Unity Input Actions
|
|
UnityEngine.InputSystem.InputAction leftGrip;
|
|
UnityEngine.InputSystem.InputAction leftTrigger;
|
|
UnityEngine.InputSystem.InputAction leftTriggerNear;
|
|
UnityEngine.InputSystem.InputAction rightGrip;
|
|
UnityEngine.InputSystem.InputAction rightTrigger;
|
|
UnityEngine.InputSystem.InputAction rightTriggerNear;
|
|
UnityEngine.InputSystem.InputAction leftThumbstick;
|
|
UnityEngine.InputSystem.InputAction leftThumbstickDown;
|
|
UnityEngine.InputSystem.InputAction leftThumbNear;
|
|
UnityEngine.InputSystem.InputAction leftTouchpad;
|
|
UnityEngine.InputSystem.InputAction leftTouchpadDown;
|
|
UnityEngine.InputSystem.InputAction rightThumbstick;
|
|
UnityEngine.InputSystem.InputAction rightThumbstickDown;
|
|
UnityEngine.InputSystem.InputAction rightThumbNear;
|
|
UnityEngine.InputSystem.InputAction rightTouchpad;
|
|
UnityEngine.InputSystem.InputAction rightTouchpadDown;
|
|
UnityEngine.InputSystem.InputAction aButton;
|
|
UnityEngine.InputSystem.InputAction bButton;
|
|
UnityEngine.InputSystem.InputAction xButton;
|
|
UnityEngine.InputSystem.InputAction yButton;
|
|
|
|
UnityEngine.InputSystem.InputAction startButton;
|
|
UnityEngine.InputSystem.InputAction backButton;
|
|
|
|
|
|
#endregion
|
|
|
|
#region Input Debugging
|
|
// Used for showing a custom inspector
|
|
[HideInInspector]
|
|
public bool ShowInputDebugger = false;
|
|
#endregion
|
|
|
|
private void Awake() {
|
|
// Destroy any duplicate instances that may have been created
|
|
if (_instance != null && _instance != this) {
|
|
Destroy(this);
|
|
return;
|
|
}
|
|
|
|
_instance = this;
|
|
|
|
// Update all device properties
|
|
List<InputDevice> devices = new List<InputDevice>();
|
|
InputDevices.GetDevices(devices);
|
|
|
|
setDeviceProperties();
|
|
}
|
|
|
|
void Start() {
|
|
|
|
SetTrackingOriginMode(TrackingOrigin);
|
|
|
|
#if STEAM_VR_SDK
|
|
SteamVRSupport = true;
|
|
|
|
// Warn that input source has not been set, even though the SteamVR SDK is present.
|
|
if(InputSource != XRInputSource.SteamVR) {
|
|
Debug.Log("SteamVR SDK detected, but not set as source on InputBridge. Recommend switching input Source from " + InputSource.ToString() + " to SteamVR.");
|
|
}
|
|
|
|
// Set the default action set if not provided
|
|
SteamVR_ActivateActionSetOnLoad VRIFLoader = FindObjectOfType<SteamVR_ActivateActionSetOnLoad>();
|
|
if (VRIFLoader == null) {
|
|
Debug.Log("SteamVR_ActivateActionSetOnLoad component not found - adding VRIF custom actions default.");
|
|
VRIFLoader = gameObject.AddComponent<SteamVR_ActivateActionSetOnLoad>();
|
|
VRIFLoader.actionSet = SteamVR_Actions.VRIF;
|
|
}
|
|
|
|
SteamVR.Initialize();
|
|
#endif
|
|
}
|
|
|
|
void OnEnable() {
|
|
#if UNITY_2019_3_OR_NEWER
|
|
InputDevices.deviceConfigChanged += onDeviceChanged;
|
|
InputDevices.deviceConnected += onDeviceChanged;
|
|
InputDevices.deviceDisconnected += onDeviceChanged;
|
|
#endif
|
|
CreateUnityInputActions();
|
|
EnableActions();
|
|
}
|
|
|
|
void OnDisable() {
|
|
#if UNITY_2019_3_OR_NEWER
|
|
InputDevices.deviceConfigChanged -= onDeviceChanged;
|
|
InputDevices.deviceConnected -= onDeviceChanged;
|
|
InputDevices.deviceDisconnected -= onDeviceChanged;
|
|
#endif
|
|
DisableActions();
|
|
}
|
|
|
|
void Update() {
|
|
UpdateDeviceActive();
|
|
UpdateInputs();
|
|
}
|
|
|
|
public virtual void UpdateInputs() {
|
|
|
|
// SteamVR uses an action system. Only update if HMD is reported as Active
|
|
if (InputSource == XRInputSource.SteamVR && SteamVRSupport && HMDActive) {
|
|
UpdateSteamInput();
|
|
}
|
|
// Use OVRInput to get more Oculus Specific inputs, such as "Near Touch"
|
|
else if (InputSource == XRInputSource.OVRInput) {
|
|
UpdateOVRInput();
|
|
}
|
|
// Use XRInput
|
|
else if(InputSource == XRInputSource.XRInput) {
|
|
UpdateXRInput();
|
|
}
|
|
// New Unity Input System
|
|
else if(InputSource == XRInputSource.UnityInput) {
|
|
UpdateUnityInput();
|
|
}
|
|
// Pico
|
|
else if(InputSource == XRInputSource.Pico) {
|
|
UpdatePicoInput();
|
|
}
|
|
|
|
// Call events
|
|
OnInputsUpdated?.Invoke();
|
|
}
|
|
|
|
#region SteamVR Action Input
|
|
public virtual void UpdateSteamInput() {
|
|
#if STEAM_VR_SDK
|
|
|
|
LeftThumbstickAxis = ApplyDeadZones(SteamVR_Actions.vRIF_LeftThumbstickAxis.axis, ThumbstickDeadzoneX, ThumbstickDeadzoneY);
|
|
RightThumbstickAxis = ApplyDeadZones(SteamVR_Actions.vRIF_RightThumbstickAxis.axis, ThumbstickDeadzoneX, ThumbstickDeadzoneY);
|
|
|
|
var prevBool = LeftThumbstick;
|
|
LeftThumbstick = SteamVR_Actions.vRIF_LeftThumbstickDown.state;
|
|
// LeftThumbstickDown = SteamVR_Actions.vRIF_LeftThumbstickDown.stateDown;
|
|
LeftThumbstickDown = prevBool == false && LeftThumbstick == true;
|
|
LeftThumbstickUp = prevBool == true && LeftThumbstick == false;
|
|
|
|
prevBool = RightThumbstick;
|
|
RightThumbstick = SteamVR_Actions.vRIF_RightThumbstickDown.state;
|
|
// RightThumbstickDown = SteamVR_Actions.vRIF_RightThumbstickDown.stateDown;
|
|
RightThumbstickDown = prevBool == false && RightThumbstick == true;
|
|
RightThumbstickUp = prevBool == true && RightThumbstick == false;
|
|
|
|
LeftThumbNear = SteamVR_Actions.vRIF_LeftThumbstickNear.state;
|
|
//LeftThumbNear = SteamVR_Actions.vRIF_LeftTrackpadNear.state;
|
|
RightThumbNear = SteamVR_Actions.vRIF_RightThumbstickNear.state;
|
|
//RightThumbNear = SteamVR_Actions.vRIF_RightTrackpadNear.state;
|
|
|
|
var prevVal = LeftGrip;
|
|
LeftGrip = LeftGrip = correctValue(SteamVR_Actions.vRIF_LeftGrip.axis);
|
|
LeftGripDown = prevVal < _downThreshold && LeftGrip >= _downThreshold;
|
|
|
|
prevVal = RightGrip;
|
|
RightGrip = correctValue(SteamVR_Actions.vRIF_RightGrip.axis);
|
|
RightGripDown = prevVal < _downThreshold && RightGrip >= _downThreshold;
|
|
|
|
prevVal = LeftTrigger;
|
|
LeftTrigger = correctValue(SteamVR_Actions.vRIF_LeftTrigger.axis);
|
|
LeftTriggerDown = prevVal < _downThreshold && LeftTrigger >= _downThreshold;
|
|
LeftTriggerUp = prevVal > _downThreshold && LeftTrigger < _downThreshold;
|
|
LeftTriggerNear = SteamVR_Actions.vRIF_LeftTriggerNear.state;
|
|
|
|
prevVal = RightTrigger;
|
|
RightTrigger = correctValue(SteamVR_Actions.vRIF_RightTrigger.axis);
|
|
RightTriggerDown = prevVal < _downThreshold && RightTrigger >= _downThreshold;
|
|
RightTriggerUp = prevVal > _downThreshold && RightTrigger < _downThreshold;
|
|
RightTriggerNear = SteamVR_Actions.vRIF_RightTriggerNear.state;
|
|
|
|
AButton = SteamVR_Actions.vRIF_AButton.state;
|
|
AButtonDown = SteamVR_Actions.vRIF_AButton.stateDown;
|
|
AButtonUp = SteamVR_Actions.vRIF_AButton.stateUp;
|
|
BButton = SteamVR_Actions.vRIF_BButton.state;
|
|
BButtonDown = SteamVR_Actions.vRIF_BButton.stateDown;
|
|
BButtonUp = SteamVR_Actions.vRIF_AButton.stateUp;
|
|
XButton = SteamVR_Actions.vRIF_XButton.state;
|
|
XButtonDown = SteamVR_Actions.vRIF_XButton.stateDown;
|
|
XButtonUp = SteamVR_Actions.vRIF_XButton.stateUp;
|
|
YButton = SteamVR_Actions.vRIF_YButton.state;
|
|
YButtonDown = SteamVR_Actions.vRIF_YButton.stateDown;
|
|
YButtonUp = SteamVR_Actions.vRIF_YButton.stateUp;
|
|
|
|
// Hand Tracking (Ie Valve Knuckles Finger Tracking)
|
|
LeftThumbCurl = SteamVR_Actions.vRIF_SkeletonLeftHand.thumbCurl;
|
|
LeftIndexCurl = SteamVR_Actions.vRIF_SkeletonLeftHand.indexCurl;
|
|
LeftMiddleCurl = SteamVR_Actions.vRIF_SkeletonLeftHand.middleCurl;
|
|
LeftRingCurl = SteamVR_Actions.vRIF_SkeletonLeftHand.ringCurl;
|
|
LeftPinkyCurl = SteamVR_Actions.vRIF_SkeletonLeftHand.pinkyCurl;
|
|
|
|
RightThumbCurl = SteamVR_Actions.vRIF_SkeletonRightHand.thumbCurl;
|
|
RightIndexCurl = SteamVR_Actions.vRIF_SkeletonRightHand.indexCurl;
|
|
RightMiddleCurl = SteamVR_Actions.vRIF_SkeletonRightHand.middleCurl;
|
|
RightRingCurl = SteamVR_Actions.vRIF_SkeletonRightHand.ringCurl;
|
|
RightPinkyCurl = SteamVR_Actions.vRIF_SkeletonRightHand.pinkyCurl;
|
|
|
|
//prevBool = StartButton;
|
|
//StartButton = SteamVR_Actions.vRIF_StartButton.state;
|
|
//StartButtonDown = prevBool == false && StartButton == true;
|
|
|
|
//prevBool = BackButton;
|
|
//BackButton = SteamVR_Actions.vRIF_BackButton.state;
|
|
//BackButtonDown = prevBool == false && BackButton == true;
|
|
#endif
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region XR Input
|
|
#if UNITY_2019_3_OR_NEWER
|
|
#region XRInputVariables
|
|
InputDevice primaryLeftController;
|
|
InputDevice primaryRightController;
|
|
InputFeatureUsage<Vector2> thumbstickAxis;
|
|
InputFeatureUsage<Vector2> thumbstickAxisSecondary;
|
|
InputFeatureUsage<bool> thumbstickAxisClick;
|
|
#endregion
|
|
#endif
|
|
|
|
public virtual void UpdateXRInput() {
|
|
#if UNITY_2019_3_OR_NEWER
|
|
// Refresh XR devices
|
|
InputDevices.GetDevices(devices);
|
|
|
|
// Left XR Controller
|
|
primaryLeftController = GetLeftController();
|
|
|
|
// Right XR Controller
|
|
primaryRightController = GetRightController();
|
|
|
|
// For most cases thumbstick is on the primary2DAxis
|
|
// However, if the Controller has both a touchpad and a controller on it (i.e. Valve Index Knuckles) then the thumbstick axis is actually on the secondary axis, not the primary axis
|
|
thumbstickAxis = SupportsBothTouchPadAndJoystick ? CommonUsages.secondary2DAxis : CommonUsages.primary2DAxis;
|
|
thumbstickAxisSecondary = SupportsBothTouchPadAndJoystick ? CommonUsages.primary2DAxis : CommonUsages.secondary2DAxis;
|
|
thumbstickAxisClick = SupportsBothTouchPadAndJoystick ? CommonUsages.secondary2DAxisClick : CommonUsages.primary2DAxisClick;
|
|
|
|
var prevBool = LeftThumbstick;
|
|
LeftThumbstick = getFeatureUsage(primaryLeftController, thumbstickAxisClick);
|
|
LeftThumbstickDown = prevBool == false && LeftThumbstick == true;
|
|
LeftThumbstickUp = prevBool == true && LeftThumbstick == false;
|
|
|
|
prevBool = RightThumbstick;
|
|
RightThumbstick = getFeatureUsage(primaryRightController, thumbstickAxisClick);
|
|
RightThumbstickDown = prevBool == false && RightThumbstick == true;
|
|
RightThumbstickUp = prevBool == true && RightThumbstick == false;
|
|
|
|
LeftTouchPadAxis = ApplyDeadZones(getFeatureUsage(primaryLeftController, thumbstickAxisSecondary), ThumbstickDeadzoneX, ThumbstickDeadzoneY);
|
|
LeftThumbstickAxis = ApplyDeadZones(getFeatureUsage(primaryLeftController, thumbstickAxis), ThumbstickDeadzoneX, ThumbstickDeadzoneY);
|
|
|
|
RightTouchPadAxis = ApplyDeadZones(getFeatureUsage(primaryRightController, thumbstickAxisSecondary), ThumbstickDeadzoneX, ThumbstickDeadzoneY);
|
|
RightThumbstickAxis = ApplyDeadZones(getFeatureUsage(primaryRightController, thumbstickAxis), ThumbstickDeadzoneX, ThumbstickDeadzoneY);
|
|
|
|
// Store copy of previous value so we can determine if we need to call OnDownEvent
|
|
var prevVal = LeftGrip;
|
|
LeftGrip = correctValue(getFeatureUsage(primaryLeftController, CommonUsages.grip));
|
|
LeftGripDown = prevVal < _downThreshold && LeftGrip >= _downThreshold;
|
|
|
|
prevVal = RightGrip;
|
|
RightGrip = correctValue(getFeatureUsage(primaryRightController, CommonUsages.grip));
|
|
RightGripDown = prevVal < _downThreshold && RightGrip >= _downThreshold;
|
|
|
|
prevVal = LeftTrigger;
|
|
LeftTrigger = correctValue(getFeatureUsage(primaryLeftController, CommonUsages.trigger));
|
|
LeftTriggerUp = prevVal > _downThreshold && LeftTrigger < _downThreshold;
|
|
LeftTriggerDown = prevVal < _downThreshold && LeftTrigger >= _downThreshold;
|
|
|
|
prevVal = RightTrigger;
|
|
RightTrigger = correctValue(getFeatureUsage(primaryRightController, CommonUsages.trigger));
|
|
RightTriggerUp = prevVal > _downThreshold && RightTrigger < _downThreshold;
|
|
RightTriggerDown = prevVal < _downThreshold && RightTrigger >= _downThreshold;
|
|
|
|
// While OculusUsages.indexTouch is recommended, only CommonUsages.indexTouch is currently providing proper values on certain platforms
|
|
// OculusUsages.indexTouch is returning proper values in Oculus XR plugin >= v1.6.0
|
|
// Oculus Desktop / Android packages require CommonUsages, not OculusUsages ¯\_(ツ)_/¯
|
|
#pragma warning disable 0618
|
|
|
|
LeftTriggerNear = getFeatureUsage(primaryLeftController, CommonUsages.indexTouch) > 0;
|
|
|
|
// Check Oculus Usage if not found with CommonUsages
|
|
if (!LeftTriggerNear) {
|
|
#if OCULUS_XR_PLUGIN
|
|
LeftTriggerNear = getFeatureUsage(primaryLeftController, Unity.XR.Oculus.OculusUsages.indexTouch);
|
|
#endif
|
|
}
|
|
|
|
// Fallback to checking UnityInput if available
|
|
if (!LeftTriggerNear && leftTriggerNear != null && correctValue(leftTriggerNear.ReadValue<float>()) > 0) {
|
|
LeftTriggerNear = true;
|
|
};
|
|
|
|
LeftThumbNear = getFeatureUsage(primaryLeftController, CommonUsages.thumbTouch) > 0 ||
|
|
getFeatureUsage(primaryLeftController, CommonUsages.primaryTouch) ||
|
|
getFeatureUsage(primaryLeftController, CommonUsages.secondaryTouch) ||
|
|
getFeatureUsage(primaryLeftController, CommonUsages.primary2DAxisTouch);
|
|
|
|
if (!LeftThumbNear) {
|
|
#if OCULUS_XR_PLUGIN
|
|
LeftThumbNear = getFeatureUsage(primaryLeftController, Unity.XR.Oculus.OculusUsages.thumbTouch);
|
|
#endif
|
|
}
|
|
|
|
RightTriggerNear = getFeatureUsage(primaryRightController, CommonUsages.indexTouch) > 0;
|
|
|
|
// Try Oculus Usages if not found with Common
|
|
if (!RightTriggerNear) {
|
|
#if OCULUS_XR_PLUGIN
|
|
RightTriggerNear = getFeatureUsage(primaryRightController, Unity.XR.Oculus.OculusUsages.indexTouch);
|
|
#endif
|
|
}
|
|
|
|
// Fallback to checking UnityInput for trigger near if available
|
|
if (!RightTriggerNear && rightTriggerNear != null && correctValue(rightTriggerNear.ReadValue<float>()) > 0) {
|
|
RightTriggerNear = true;
|
|
};
|
|
|
|
RightThumbNear = getFeatureUsage(primaryRightController, CommonUsages.thumbTouch) > 0 ||
|
|
getFeatureUsage(primaryRightController, CommonUsages.primaryTouch) ||
|
|
getFeatureUsage(primaryRightController, CommonUsages.secondaryTouch) ||
|
|
getFeatureUsage(primaryRightController, CommonUsages.primary2DAxisTouch);
|
|
|
|
if (!RightThumbNear) {
|
|
#if OCULUS_XR_PLUGIN
|
|
RightThumbNear = getFeatureUsage(primaryRightController, Unity.XR.Oculus.OculusUsages.thumbTouch);
|
|
#endif
|
|
}
|
|
|
|
#pragma warning restore 0618
|
|
prevBool = AButton;
|
|
AButton = getFeatureUsage(primaryRightController, CommonUsages.primaryButton);
|
|
AButtonDown = prevBool == false && AButton == true;
|
|
AButtonUp = prevBool == true && AButton == false;
|
|
|
|
prevBool = BButton;
|
|
BButton = getFeatureUsage(primaryRightController, CommonUsages.secondaryButton);
|
|
BButtonDown = prevBool == false && BButton == true;
|
|
BButtonUp = prevBool == true && BButton == false;
|
|
|
|
prevBool = XButton;
|
|
XButton = getFeatureUsage(primaryLeftController, CommonUsages.primaryButton);
|
|
XButtonDown = prevBool == false && XButton == true;
|
|
XButtonUp = prevBool == true && XButton == false;
|
|
|
|
prevBool = YButton;
|
|
YButton = getFeatureUsage(primaryLeftController, CommonUsages.secondaryButton);
|
|
YButtonDown = prevBool == false && YButton == true;
|
|
YButtonUp = prevBool == true && YButton == false;
|
|
|
|
prevBool = StartButton;
|
|
StartButton = getFeatureUsage(primaryRightController, CommonUsages.menuButton);
|
|
StartButtonDown = prevBool == false && StartButton == true;
|
|
|
|
prevBool = BackButton;
|
|
BackButton = getFeatureUsage(primaryLeftController, CommonUsages.menuButton);
|
|
BackButtonDown = prevBool == false && BackButton == true;
|
|
#endif
|
|
}
|
|
#endregion
|
|
|
|
#region Unity Input
|
|
public virtual void UpdateUnityInput() {
|
|
|
|
var prevVal = LeftGrip;
|
|
LeftGrip = correctValue(leftGrip.ReadValue<float>());
|
|
LeftGripDown = prevVal < _downThreshold && LeftGrip >= _downThreshold;
|
|
|
|
prevVal = LeftTrigger;
|
|
LeftTrigger = correctValue(leftTrigger.ReadValue<float>());
|
|
LeftTriggerDown = prevVal < _downThreshold && LeftTrigger >= _downThreshold;
|
|
LeftTriggerNear = correctValue(leftTriggerNear.ReadValue<float>()) > 0;
|
|
LeftTriggerUp = prevVal > _downThreshold && LeftTrigger < _downThreshold;
|
|
|
|
prevVal = RightGrip;
|
|
RightGrip = correctValue(rightGrip.ReadValue<float>());
|
|
RightGripDown = prevVal < _downThreshold && RightGrip >= _downThreshold;
|
|
|
|
prevVal = RightTrigger;
|
|
RightTrigger = correctValue(rightTrigger.ReadValue<float>());
|
|
RightTriggerDown = prevVal < _downThreshold && RightTrigger >= _downThreshold;
|
|
RightTriggerNear = correctValue(rightTriggerNear.ReadValue<float>()) > 0;
|
|
RightTriggerUp = prevVal > _downThreshold && RightTrigger < _downThreshold;
|
|
|
|
LeftThumbstickAxis = leftThumbstick.ReadValue<Vector2>();
|
|
var prevBool = LeftThumbstick;
|
|
LeftThumbstick = correctValue(leftThumbstickDown.ReadValue<float>()) > 0;
|
|
LeftThumbstickDown = prevBool == false && LeftThumbstick == true;
|
|
LeftThumbstickUp = prevBool == true && LeftThumbstick == false;
|
|
LeftThumbNear = correctValue(leftThumbNear.ReadValue<float>()) > 0;
|
|
LeftTouchPadAxis = leftTouchpad.ReadValue<Vector2>();
|
|
|
|
RightThumbstickAxis = rightThumbstick.ReadValue<Vector2>();
|
|
prevBool = RightThumbstick;
|
|
RightThumbstick = correctValue(rightThumbstickDown.ReadValue<float>()) > 0;
|
|
RightThumbstickDown = prevBool == false && RightThumbstick == true;
|
|
RightThumbstickUp = prevBool == true && RightThumbstick == false;
|
|
RightThumbNear = correctValue(rightThumbNear.ReadValue<float>()) > 0;
|
|
RightTouchPadAxis = rightTouchpad.ReadValue<Vector2>();
|
|
|
|
prevBool = AButton;
|
|
AButton = correctValue(aButton.ReadValue<float>()) > 0;
|
|
AButtonDown = prevBool == false && AButton == true;
|
|
AButtonUp = prevBool == true && AButton == false;
|
|
|
|
prevBool = BButton;
|
|
BButton = correctValue(bButton.ReadValue<float>()) > 0;
|
|
BButtonDown = prevBool == false && BButton == true;
|
|
BButtonUp = prevBool == true && BButton == false;
|
|
|
|
prevBool = XButton;
|
|
XButton = correctValue(xButton.ReadValue<float>()) > 0;
|
|
XButtonDown = prevBool == false && XButton == true;
|
|
XButtonUp = prevBool == true && XButton == false;
|
|
|
|
prevBool = YButton;
|
|
YButton = correctValue(yButton.ReadValue<float>()) > 0;
|
|
YButtonDown = prevBool == false && YButton == true;
|
|
YButtonUp = prevBool == true && YButton == false;
|
|
|
|
prevBool = StartButton;
|
|
StartButton = correctValue(startButton.ReadValue<float>()) > 0;
|
|
StartButtonDown = prevBool == false && StartButton == true;
|
|
|
|
prevBool = BackButton;
|
|
BackButton = correctValue(backButton.ReadValue<float>()) > 0;
|
|
BackButtonDown = prevBool == false && BackButton == true;
|
|
}
|
|
|
|
public virtual void CreateUnityInputActions() {
|
|
leftGrip = CreateInputAction("leftGrip", "<XRController>{LeftHand}/{grip}", true);
|
|
leftTrigger = CreateInputAction("leftTrigger", "<XRController>{LeftHand}/{trigger}", true);
|
|
leftTriggerNear = CreateInputAction("leftTriggerNear", "<XRController>{LeftHand}/triggerTouched", true);
|
|
|
|
rightGrip = CreateInputAction("rightGrip", "<XRController>{RightHand}/{grip}", true);
|
|
rightTrigger = CreateInputAction("rightTrigger", "<XRController>{RightHand}/{trigger}", true);
|
|
rightTriggerNear = CreateInputAction("rightTriggerNear", "<XRController>{RightHand}/triggerTouched", true);
|
|
|
|
leftThumbstick = CreateInputAction("leftThumbstick", "<XRController>{LeftHand}/{primary2DAxis}", true);
|
|
leftThumbstickDown = CreateInputAction("leftThumbstickDown", "<XRController>{LeftHand}/{primary2DAxisClick}", false);
|
|
leftThumbNear = CreateInputAction("leftThumbNear", "<XRController>{LeftHand}/thumbstickTouched", true);
|
|
leftTouchpad = CreateInputAction("leftTouchpad", "<XRController>{LeftHand}/{secondary2DAxis}", true);
|
|
leftTouchpadDown = CreateInputAction("leftTouchpadDown", "<XRController>{LeftHand}/{secondary2DAxisClick}", false);
|
|
|
|
rightThumbstick = CreateInputAction("rightThumbstick", "<XRController>{RightHand}/{primary2DAxis}", true);
|
|
rightThumbstickDown = CreateInputAction("rightThumbstickDown", "<XRController>{RightHand}/{primary2DAxisClick}", false);
|
|
rightThumbNear = CreateInputAction("rightThumbNear", "<XRController>{RightHand}/thumbstickTouched", true);
|
|
rightTouchpad = CreateInputAction("rightTouchpad", "<XRController>{RightHand}/{secondary2DAxis}", true);
|
|
rightTouchpadDown = CreateInputAction("rightTouchpadDown", "<XRController>{RightHand}/{secondary2DAxisClick}", false);
|
|
|
|
aButton = CreateInputAction("aButton", "<XRController>{RightHand}/{primaryButton}", false);
|
|
bButton = CreateInputAction("bButton", "<XRController>{RightHand}/{secondaryButton}", false);
|
|
xButton = CreateInputAction("xButton", "<XRController>{LeftHand}/{primaryButton}", false);
|
|
yButton = CreateInputAction("yButton", "<XRController>{LeftHand}/{secondaryButton}", false);
|
|
|
|
startButton = CreateInputAction("startButton", "<XRController>{RightHand}/{menu}", false);
|
|
backButton = CreateInputAction("backButton", "<XRController>{LeftHand}/{menu}", false);
|
|
}
|
|
|
|
public virtual void EnableActions() {
|
|
if (actionSet != null) {
|
|
foreach (var map in actionSet.actionMaps) {
|
|
foreach (var action in map) {
|
|
action.Enable();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public virtual void DisableActions() {
|
|
if (actionSet != null) {
|
|
foreach (var map in actionSet.actionMaps) {
|
|
foreach (var action in map) {
|
|
action.Disable();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public UnityEngine.InputSystem.InputAction CreateInputAction(string actionName, string binding, bool valueType) {
|
|
var act = new UnityEngine.InputSystem.InputAction(actionName,
|
|
valueType ? UnityEngine.InputSystem.InputActionType.Value : UnityEngine.InputSystem.InputActionType.Button,
|
|
binding);
|
|
|
|
// Automatically enable this binding
|
|
act.Enable();
|
|
|
|
return act;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region OVR Input
|
|
public virtual void UpdateOVRInput() {
|
|
#if OCULUS_INTEGRATION
|
|
LeftThumbstickAxis = ApplyDeadZones(OVRInput.Get(OVRInput.Axis2D.PrimaryThumbstick), ThumbstickDeadzoneX, ThumbstickDeadzoneY);
|
|
RightThumbstickAxis = ApplyDeadZones(OVRInput.Get(OVRInput.Axis2D.SecondaryThumbstick), ThumbstickDeadzoneX, ThumbstickDeadzoneY);
|
|
|
|
LeftGrip = correctValue(OVRInput.Get(OVRInput.Axis1D.PrimaryHandTrigger, OVRInput.Controller.LTouch));
|
|
LeftGripDown = OVRInput.GetDown(OVRInput.Button.PrimaryHandTrigger, OVRInput.Controller.LTouch);
|
|
|
|
RightGrip = correctValue(OVRInput.Get(OVRInput.Axis1D.PrimaryHandTrigger, OVRInput.Controller.RTouch));
|
|
RightGripDown = OVRInput.GetDown(OVRInput.Button.PrimaryHandTrigger, OVRInput.Controller.RTouch);
|
|
|
|
LeftTrigger = correctValue(OVRInput.Get(OVRInput.Axis1D.PrimaryIndexTrigger, OVRInput.Controller.LTouch));
|
|
LeftTriggerUp = OVRInput.GetUp(OVRInput.Button.PrimaryIndexTrigger, OVRInput.Controller.LTouch);
|
|
LeftTriggerDown = OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger, OVRInput.Controller.LTouch);
|
|
|
|
RightTrigger = correctValue(OVRInput.Get(OVRInput.Axis1D.PrimaryIndexTrigger, OVRInput.Controller.RTouch));
|
|
RightTriggerUp = OVRInput.GetUp(OVRInput.Button.PrimaryIndexTrigger, OVRInput.Controller.RTouch);
|
|
RightTriggerDown = OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger, OVRInput.Controller.RTouch);
|
|
|
|
LeftTriggerNear = OVRInput.Get(OVRInput.NearTouch.PrimaryIndexTrigger, OVRInput.Controller.LTouch);
|
|
LeftThumbNear = OVRInput.Get(OVRInput.NearTouch.PrimaryThumbButtons, OVRInput.Controller.LTouch);
|
|
|
|
RightTriggerNear = OVRInput.Get(OVRInput.NearTouch.PrimaryIndexTrigger, OVRInput.Controller.RTouch);
|
|
RightThumbNear = OVRInput.Get(OVRInput.NearTouch.PrimaryThumbButtons, OVRInput.Controller.RTouch);
|
|
|
|
AButton = OVRInput.Get(OVRInput.Button.One, OVRInput.Controller.RTouch);
|
|
AButtonDown = OVRInput.GetDown(OVRInput.Button.One, OVRInput.Controller.RTouch);
|
|
AButtonUp = OVRInput.GetUp(OVRInput.Button.One, OVRInput.Controller.RTouch);
|
|
|
|
BButton = OVRInput.Get(OVRInput.Button.Two);
|
|
BButtonDown = OVRInput.GetDown(OVRInput.Button.Two);
|
|
BButtonUp = OVRInput.GetUp(OVRInput.Button.Two);
|
|
|
|
XButton = OVRInput.Get(OVRInput.Button.Three);
|
|
XButtonDown = OVRInput.GetDown(OVRInput.Button.Three);
|
|
XButtonUp = OVRInput.GetUp(OVRInput.Button.Three);
|
|
|
|
YButton = OVRInput.Get(OVRInput.Button.Four);
|
|
YButtonDown = OVRInput.GetDown(OVRInput.Button.Four);
|
|
YButtonUp = OVRInput.GetUp(OVRInput.Button.Four);
|
|
|
|
StartButton = OVRInput.Get(OVRInput.Button.Start);
|
|
StartButtonDown = OVRInput.GetDown(OVRInput.Button.Start);
|
|
|
|
BackButton = OVRInput.Get(OVRInput.Button.Back);
|
|
BackButtonDown = OVRInput.GetDown(OVRInput.Button.Back);
|
|
|
|
LeftThumbstickDown = OVRInput.GetDown(OVRInput.Button.PrimaryThumbstick, OVRInput.Controller.LTouch);
|
|
LeftThumbstickUp = OVRInput.GetUp(OVRInput.Button.PrimaryThumbstick, OVRInput.Controller.LTouch);
|
|
|
|
RightThumbstickDown = OVRInput.GetDown(OVRInput.Button.PrimaryThumbstick, OVRInput.Controller.RTouch);
|
|
RightThumbstickUp = OVRInput.GetUp(OVRInput.Button.PrimaryThumbstick, OVRInput.Controller.RTouch);
|
|
|
|
LeftThumbstick = OVRInput.Get(OVRInput.Button.PrimaryThumbstick, OVRInput.Controller.LTouch);
|
|
RightThumbstick = OVRInput.Get(OVRInput.Button.PrimaryThumbstick, OVRInput.Controller.RTouch);
|
|
#endif
|
|
|
|
// Call events
|
|
OnInputsUpdated?.Invoke();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Pico Input
|
|
|
|
public virtual void UpdatePicoInput() {
|
|
#if PICO_SDK
|
|
int rightHand = 1;
|
|
int leftHand = 0;
|
|
var prevBool = LeftThumbstick;
|
|
var prevVal = LeftGrip;
|
|
|
|
LeftThumbstickAxis = ApplyDeadZones(Pvr_UnitySDKAPI.Controller.UPvr_GetAxis2D(leftHand), ThumbstickDeadzoneX, ThumbstickDeadzoneY);
|
|
RightThumbstickAxis = ApplyDeadZones(Pvr_UnitySDKAPI.Controller.UPvr_GetAxis2D(rightHand), ThumbstickDeadzoneX, ThumbstickDeadzoneY);
|
|
|
|
prevBool = LeftThumbstick;
|
|
LeftThumbstick = Pvr_UnitySDKAPI.Controller.UPvr_GetKey(leftHand, Pvr_UnitySDKAPI.Pvr_KeyCode.TOUCHPAD);
|
|
LeftThumbstickDown = Pvr_UnitySDKAPI.Controller.UPvr_GetKeyDown(leftHand, Pvr_UnitySDKAPI.Pvr_KeyCode.TOUCHPAD);
|
|
LeftThumbstickUp = prevBool == true && LeftThumbstick == false;
|
|
|
|
prevBool = RightThumbstick;
|
|
RightThumbstick = Pvr_UnitySDKAPI.Controller.UPvr_GetKey(rightHand, Pvr_UnitySDKAPI.Pvr_KeyCode.TOUCHPAD);
|
|
RightThumbstickDown = Pvr_UnitySDKAPI.Controller.UPvr_GetKeyDown(rightHand, Pvr_UnitySDKAPI.Pvr_KeyCode.TOUCHPAD);
|
|
RightThumbstickUp = prevBool == true && RightThumbstick == false;
|
|
|
|
LeftThumbNear = Pvr_UnitySDKAPI.Controller.UPvr_IsTouching(leftHand);
|
|
RightThumbNear = Pvr_UnitySDKAPI.Controller.UPvr_IsTouching(rightHand);
|
|
|
|
prevVal = LeftGrip;
|
|
LeftGrip = Pvr_UnitySDKAPI.Controller.UPvr_GetKey(leftHand, Pvr_UnitySDKAPI.Pvr_KeyCode.Left) ? 1f : 0;
|
|
LeftGripDown = Pvr_UnitySDKAPI.Controller.UPvr_GetKeyDown(leftHand, Pvr_UnitySDKAPI.Pvr_KeyCode.Left);
|
|
|
|
prevVal = RightGrip;
|
|
RightGrip = Pvr_UnitySDKAPI.Controller.UPvr_GetKey(rightHand, Pvr_UnitySDKAPI.Pvr_KeyCode.Right) ? 1f : 0;
|
|
RightGripDown = Pvr_UnitySDKAPI.Controller.UPvr_GetKeyDown(rightHand, Pvr_UnitySDKAPI.Pvr_KeyCode.Right);
|
|
|
|
prevVal = LeftTrigger;
|
|
LeftTrigger = Pvr_UnitySDKAPI.Controller.UPvr_GetControllerTriggerValue(leftHand) / 255f;
|
|
LeftTriggerUp = prevVal > _downThreshold && LeftTrigger < _downThreshold;
|
|
LeftTriggerDown = prevVal < _downThreshold && LeftTrigger >= _downThreshold;
|
|
|
|
prevVal = RightTrigger;
|
|
RightTrigger = Pvr_UnitySDKAPI.Controller.UPvr_GetControllerTriggerValue(rightHand) / 255f;
|
|
RightTriggerUp = prevVal > _downThreshold && RightTrigger < _downThreshold;
|
|
RightTriggerDown = prevVal < _downThreshold && RightTrigger >= _downThreshold;
|
|
|
|
prevBool = AButton;
|
|
AButton = Pvr_UnitySDKAPI.Controller.UPvr_GetKey(rightHand, Pvr_UnitySDKAPI.Pvr_KeyCode.A);
|
|
AButtonDown = Pvr_UnitySDKAPI.Controller.UPvr_GetKeyDown(rightHand, Pvr_UnitySDKAPI.Pvr_KeyCode.A);
|
|
AButtonUp = prevBool == true && AButton == false;
|
|
|
|
prevBool = BButton;
|
|
BButton = Pvr_UnitySDKAPI.Controller.UPvr_GetKey(rightHand, Pvr_UnitySDKAPI.Pvr_KeyCode.B);
|
|
BButtonDown = Pvr_UnitySDKAPI.Controller.UPvr_GetKeyDown(rightHand, Pvr_UnitySDKAPI.Pvr_KeyCode.B);
|
|
BButtonUp = prevBool == true && BButton == false;
|
|
|
|
prevBool = XButton;
|
|
XButton = Pvr_UnitySDKAPI.Controller.UPvr_GetKey(leftHand, Pvr_UnitySDKAPI.Pvr_KeyCode.X);
|
|
XButtonDown = Pvr_UnitySDKAPI.Controller.UPvr_GetKeyDown(leftHand, Pvr_UnitySDKAPI.Pvr_KeyCode.X);
|
|
XButtonUp = prevBool == true && XButton == false;
|
|
|
|
prevBool = YButton;
|
|
YButton = Pvr_UnitySDKAPI.Controller.UPvr_GetKey(leftHand, Pvr_UnitySDKAPI.Pvr_KeyCode.Y);
|
|
YButtonDown = prevBool == false && YButton == true;
|
|
// Alternatively :
|
|
// YButtonDown = Pvr_UnitySDKAPI.Controller.UPvr_GetKeyDown(leftHand, Pvr_UnitySDKAPI.Pvr_KeyCode.Y);
|
|
YButtonUp = prevBool == true && YButton == false;
|
|
#endif
|
|
}
|
|
|
|
#endregion
|
|
|
|
public virtual void UpdateDeviceActive() {
|
|
|
|
InputDevice hmd = GetHMD();
|
|
|
|
// Can bail early
|
|
if (hmd.isValid == false) {
|
|
HMDActive = false;
|
|
return;
|
|
}
|
|
|
|
// Make sure the device supports the presence feature
|
|
bool userPresent = false;
|
|
bool presenceFeatureSupported = hmd.TryGetFeatureValue(CommonUsages.userPresence, out userPresent);
|
|
if(presenceFeatureSupported) {
|
|
HMDActive = userPresent;
|
|
}
|
|
else {
|
|
HMDActive = XRSettings.isDeviceActive;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Round to nearest thousandth. This can alleviate some floating point precision errors found when using certain inputs.
|
|
/// </summary>
|
|
/// <param name="inputValue"></param>
|
|
/// <returns></returns>
|
|
float correctValue(float inputValue) {
|
|
return (float)System.Math.Round(inputValue * 1000f) / 1000f;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Returns true if the given binding is pressed
|
|
/// </summary>
|
|
public bool GetControllerBindingValue(ControllerBinding val) {
|
|
if (val == ControllerBinding.AButton && AButton) { return true; }
|
|
if (val == ControllerBinding.AButtonDown && AButtonDown) { return true; }
|
|
if (val == ControllerBinding.BButton && BButton) { return true; }
|
|
if (val == ControllerBinding.BButtonDown && BButtonDown) { return true; }
|
|
if (val == ControllerBinding.XButton && XButton) { return true; }
|
|
if (val == ControllerBinding.XButtonDown && XButtonDown) { return true; }
|
|
if (val == ControllerBinding.YButton && YButton) { return true; }
|
|
if (val == ControllerBinding.YButtonDown && YButtonDown) { return true; }
|
|
if (val == ControllerBinding.LeftTrigger && LeftTrigger > _downThreshold) { return true; }
|
|
if (val == ControllerBinding.LeftTriggerDown && LeftTriggerDown) { return true; }
|
|
if (val == ControllerBinding.LeftGrip && LeftGrip > _downThreshold) { return true; }
|
|
if (val == ControllerBinding.LeftGripDown && LeftGripDown) { return true; }
|
|
if (val == ControllerBinding.LeftThumbstick && LeftThumbstick) { return true; }
|
|
if (val == ControllerBinding.LeftThumbstickDown && LeftThumbstickDown) { return true; }
|
|
if (val == ControllerBinding.RightTrigger && RightTrigger > _downThreshold) { return true; }
|
|
if (val == ControllerBinding.RightTriggerDown && RightTriggerDown) { return true; }
|
|
if (val == ControllerBinding.RightGrip && RightGrip > _downThreshold) { return true; }
|
|
if (val == ControllerBinding.RightGripDown && RightGripDown) { return true; }
|
|
if (val == ControllerBinding.RightThumbstick && RightThumbstick) { return true; }
|
|
if (val == ControllerBinding.RightThumbstickDown && RightThumbstickDown) { return true; }
|
|
if (val == ControllerBinding.StartButton && StartButton) { return true; }
|
|
if (val == ControllerBinding.StartButtonDown && StartButtonDown) { return true; }
|
|
if (val == ControllerBinding.BackButton && BackButton) { return true; }
|
|
if (val == ControllerBinding.BackButtonDown && BackButtonDown) { return true; }
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool GetGrabbedControllerBinding(GrabbedControllerBinding val, ControllerHand hand) {
|
|
if(hand == ControllerHand.Right) {
|
|
if (val == GrabbedControllerBinding.Button1 && AButton) { return true; }
|
|
if (val == GrabbedControllerBinding.Button1Down && AButtonDown) { return true; }
|
|
if (val == GrabbedControllerBinding.Button2 && BButton) { return true; }
|
|
if (val == GrabbedControllerBinding.Button2Down && BButtonDown) { return true; }
|
|
if (val == GrabbedControllerBinding.Grip && RightGrip > _downThreshold) { return true; }
|
|
if (val == GrabbedControllerBinding.GripDown && RightGripDown) { return true; }
|
|
if (val == GrabbedControllerBinding.Trigger && RightTrigger > _downThreshold) { return true; }
|
|
if (val == GrabbedControllerBinding.TriggerDown && RightTriggerDown) { return true; }
|
|
}
|
|
else if (hand == ControllerHand.Left) {
|
|
if (val == GrabbedControllerBinding.Button1 && XButton) { return true; }
|
|
if (val == GrabbedControllerBinding.Button1Down && XButtonDown) { return true; }
|
|
if (val == GrabbedControllerBinding.Button2 && YButton) { return true; }
|
|
if (val == GrabbedControllerBinding.Button2Down && YButtonDown) { return true; }
|
|
if (val == GrabbedControllerBinding.Grip && LeftGrip > _downThreshold) { return true; }
|
|
if (val == GrabbedControllerBinding.GripDown && LeftGripDown) { return true; }
|
|
if (val == GrabbedControllerBinding.Trigger && LeftTrigger > _downThreshold) { return true; }
|
|
if (val == GrabbedControllerBinding.TriggerDown && LeftTriggerDown) { return true; }
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public Vector2 GetInputAxisValue(InputAxis val) {
|
|
if (val == InputAxis.LeftThumbStickAxis) { return LeftThumbstickAxis; }
|
|
if (val == InputAxis.RightThumbStickAxis) { return RightThumbstickAxis; }
|
|
if (val == InputAxis.LeftTouchPadAxis) { return LeftTouchPadAxis; }
|
|
if (val == InputAxis.RightTouchPadAxis) { return RightTouchPadAxis; }
|
|
|
|
return Vector3.zero;
|
|
}
|
|
|
|
Vector2 ApplyDeadZones(Vector2 pos, float deadZoneX, float deadZoneY) {
|
|
|
|
if (Mathf.Abs(pos.x) < deadZoneX) {
|
|
pos.x = 0f;
|
|
}
|
|
|
|
if (Mathf.Abs(pos.y) < deadZoneY) {
|
|
pos.y = 0f;
|
|
}
|
|
|
|
return pos;
|
|
}
|
|
|
|
// Called when an input device has changed (connect / disconnect, etc.)
|
|
void onDeviceChanged(InputDevice inputDevice) {
|
|
|
|
setDeviceProperties();
|
|
|
|
SetTrackingOriginMode(TrackingOrigin);
|
|
}
|
|
|
|
void setDeviceProperties() {
|
|
|
|
// Update device properties such as device name, controller properties, etc.
|
|
// We only want to update this information if a device has changed in order to skip unnecessary checks every frame
|
|
IsOculusDevice = GetIsOculusDevice();
|
|
IsOculusQuest = GetIsOculusQuest();
|
|
IsHTCDevice = GetIsHTCDevice();
|
|
IsPicoDevice = GetIsPicoDevice();
|
|
IsValveIndexController = GetIsValveIndexController();
|
|
|
|
// Set the SDK we are using
|
|
LoadedSDK = GetLoadedSDK();
|
|
|
|
// Get specific device support
|
|
SupportsIndexTouch = GetSupportsIndexTouch();
|
|
SupportsThumbTouch = GetSupportsThumbTouch();
|
|
|
|
// Currently only the Valve Index has both a touchpad and a joystick on the same controller
|
|
SupportsBothTouchPadAndJoystick = IsValveIndexController;
|
|
|
|
// Update Controller Type
|
|
ConnectedControllerType = GetControllerType();
|
|
|
|
// Call any events
|
|
if(!string.IsNullOrEmpty(InputBridge.Instance.GetControllerName())) {
|
|
OnControllerFound?.Invoke();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if the controllers support the 'indexTouch' XR input mapping.Currently only Oculus devices on the Oculus SDK support index touch. OpenVR is not supported.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public virtual bool GetSupportsIndexTouch() {
|
|
//if(IsOculusDevice && LoadedSDK == SDKProvider.OculusSDK) {
|
|
// return true;
|
|
//}
|
|
|
|
return true;
|
|
}
|
|
|
|
public virtual SDKProvider GetLoadedSDK() {
|
|
|
|
// Can exit early if no device name has been picked up yet
|
|
if (XRSettings.loadedDeviceName == null) {
|
|
return SDKProvider.Unknown;
|
|
}
|
|
|
|
string deviceName = XRSettings.loadedDeviceName.ToLower();
|
|
|
|
// Example : "oculus display"
|
|
if (deviceName.StartsWith("oculus")) {
|
|
return SDKProvider.OculusSDK;
|
|
}
|
|
// Example : "OpenVR Display"
|
|
else if (deviceName.StartsWith("openvr")) {
|
|
return SDKProvider.OpenVR;
|
|
}
|
|
|
|
return SDKProvider.Unknown;
|
|
}
|
|
|
|
public virtual bool GetSupportsThumbTouch() {
|
|
//if (IsOculusDevice && LoadedSDK == SDKProvider.OculusSDK) {
|
|
// return true;
|
|
//}
|
|
|
|
return true;
|
|
}
|
|
|
|
public virtual bool GetIsOculusDevice() {
|
|
|
|
var primaryHMD = GetHMD();
|
|
|
|
// OpenVR Format
|
|
if (primaryHMD != null && primaryHMD.manufacturer == "Oculus") {
|
|
return true;
|
|
}
|
|
|
|
#if UNITY_2019_2_OR_NEWER
|
|
return XRSettings.loadedDeviceName != null && XRSettings.loadedDeviceName.ToLower().Contains("oculus");
|
|
#else
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
public virtual bool GetIsOculusQuest() {
|
|
#if UNITY_2019_2_OR_NEWER
|
|
|
|
var primaryHMD = GetHMD();
|
|
|
|
// Example : "OpenVR Headset(Oculus Quest)"
|
|
if (primaryHMD != null && primaryHMD.name != null && primaryHMD.name.EndsWith("(Oculus Quest)")) {
|
|
return true;
|
|
}
|
|
// Non-OpenVR version use "contains" on string.
|
|
else if (primaryHMD != null && primaryHMD.name != null && primaryHMD.name.Contains("Oculus Quest")) {
|
|
return true;
|
|
}
|
|
|
|
// Fallback to refresh rate
|
|
return GetIsOculusDevice() && XRDevice.refreshRate == 72f;
|
|
#else
|
|
if (Application.platform == RuntimePlatform.Android) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
public virtual bool GetIsHTCDevice() {
|
|
// Is HTC Device
|
|
#if UNITY_2019_2_OR_NEWER
|
|
var primaryHMD = GetHMD();
|
|
|
|
// OpenVR Format
|
|
if (primaryHMD != null && primaryHMD.manufacturer == "HTC") {
|
|
return true;
|
|
}
|
|
|
|
return XRSettings.loadedDeviceName.StartsWith("HTC");
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
public virtual bool GetIsPicoDevice() {
|
|
#if UNITY_2019_2_OR_NEWER
|
|
return InputSource == XRInputSource.Pico || XRSettings.loadedDeviceName.StartsWith("Pico");
|
|
#else
|
|
return InputSource == XRInputSource.Pico;
|
|
#endif
|
|
}
|
|
|
|
public InputDevice GetHMD() {
|
|
InputDevices.GetDevices(devices);
|
|
|
|
var hmds = new List<InputDevice>();
|
|
var dc1 = InputDeviceCharacteristics.HeadMounted;
|
|
InputDevices.GetDevicesWithCharacteristics(dc1, hmds);
|
|
|
|
return hmds.FirstOrDefault();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Returns the name of the InputDevice if found. Returns String.empty if not found
|
|
/// </summary>
|
|
/// <returns> The name of the InputDevice if found, or String.empty if not found</returns>
|
|
public string GetHMDName() {
|
|
var device = GetHMD();
|
|
if(device != null) {
|
|
return device.name;
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
|
|
public Vector3 GetHMDLocalPosition() {
|
|
Vector3 localPosition;
|
|
|
|
GetHMD().TryGetFeatureValue(CommonUsages.devicePosition, out localPosition);
|
|
|
|
return localPosition;
|
|
}
|
|
|
|
public Quaternion GetHMDLocalRotation() {
|
|
Quaternion localRotation;
|
|
|
|
GetHMD().TryGetFeatureValue(CommonUsages.deviceRotation, out localRotation);
|
|
|
|
return localRotation;
|
|
}
|
|
|
|
public InputDevice GetLeftController() {
|
|
InputDevices.GetDevices(devices);
|
|
|
|
var leftHandedControllers = new List<InputDevice>();
|
|
var dc = InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.Left | InputDeviceCharacteristics.Controller;
|
|
InputDevices.GetDevicesWithCharacteristics(dc, leftHandedControllers);
|
|
return leftHandedControllers.FirstOrDefault();
|
|
}
|
|
|
|
public InputDevice GetRightController() {
|
|
InputDevices.GetDevices(devices);
|
|
|
|
var rightHandedControllers = new List<InputDevice>();
|
|
var dc = InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.Right | InputDeviceCharacteristics.Controller;
|
|
InputDevices.GetDevicesWithCharacteristics(dc, rightHandedControllers);
|
|
|
|
return rightHandedControllers.FirstOrDefault();
|
|
}
|
|
|
|
public Vector3 GetControllerLocalPosition(ControllerHand handSide) {
|
|
Vector3 localPosition = Vector3.zero;
|
|
|
|
if (handSide == ControllerHand.Left) {
|
|
GetLeftController().TryGetFeatureValue(CommonUsages.devicePosition, out localPosition);
|
|
}
|
|
else if (handSide == ControllerHand.Right) {
|
|
GetRightController().TryGetFeatureValue(CommonUsages.devicePosition, out localPosition);
|
|
}
|
|
|
|
return localPosition;
|
|
}
|
|
|
|
public Quaternion GetControllerLocalRotation(ControllerHand handSide) {
|
|
Quaternion localRotation = Quaternion.identity;
|
|
|
|
if (handSide == ControllerHand.Left) {
|
|
GetLeftController().TryGetFeatureValue(CommonUsages.deviceRotation, out localRotation);
|
|
}
|
|
else if (handSide == ControllerHand.Right) {
|
|
GetRightController().TryGetFeatureValue(CommonUsages.deviceRotation, out localRotation);
|
|
}
|
|
|
|
return localRotation;
|
|
}
|
|
|
|
public virtual ControllerType GetControllerType() {
|
|
|
|
if (IsValveIndexController) {
|
|
return ControllerType.Knuckles;
|
|
}
|
|
else if (IsOculusDevice) {
|
|
return ControllerType.OculusTouch;
|
|
}
|
|
else if (IsHTCDevice) {
|
|
return ControllerType.Wand;
|
|
}
|
|
|
|
return ControllerType.Unknown;
|
|
}
|
|
|
|
public Vector3 GetControllerVelocity(ControllerHand hand) {
|
|
InputDevice inputDevice = hand == ControllerHand.Left ? GetLeftController() : GetRightController();
|
|
return getFeatureUsage(inputDevice, CommonUsages.deviceVelocity);
|
|
}
|
|
|
|
public Vector3 GetControllerAngularVelocity(ControllerHand hand) {
|
|
InputDevice inputDevice = hand == ControllerHand.Left ? GetLeftController() : GetRightController();
|
|
return getFeatureUsage(inputDevice, CommonUsages.deviceAngularVelocity);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the name of the primary controller
|
|
/// </summary>
|
|
/// <returns>The name of the primary controller. Returns empty if no controller found</returns>
|
|
public virtual string GetControllerName() {
|
|
|
|
// First try right controller
|
|
var rightHandedControllers = new List<InputDevice>();
|
|
var dc = InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.Right | InputDeviceCharacteristics.Controller;
|
|
InputDevices.GetDevicesWithCharacteristics(dc, rightHandedControllers);
|
|
var primaryRightController = rightHandedControllers.FirstOrDefault();
|
|
|
|
// Return name of the found controller
|
|
if (primaryRightController != null && !System.String.IsNullOrEmpty(primaryRightController.name)) {
|
|
return primaryRightController.name;
|
|
}
|
|
|
|
// No right controller found, try the left
|
|
var leftHandedControllers = new List<InputDevice>();
|
|
dc = InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.Left | InputDeviceCharacteristics.Controller;
|
|
InputDevices.GetDevicesWithCharacteristics(dc, leftHandedControllers);
|
|
var primaryLeftController = leftHandedControllers.FirstOrDefault();
|
|
|
|
// Return name of the found controller
|
|
if (primaryLeftController != null && !System.String.IsNullOrEmpty(primaryLeftController.name)) {
|
|
return primaryLeftController.name;
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
|
|
public virtual bool GetIsValveIndexController() {
|
|
var rightHandedControllers = new List<InputDevice>();
|
|
var dc = InputDeviceCharacteristics.HeldInHand | InputDeviceCharacteristics.Right | InputDeviceCharacteristics.Controller;
|
|
InputDevices.GetDevicesWithCharacteristics(dc, rightHandedControllers);
|
|
var primaryRightController = rightHandedControllers.FirstOrDefault();
|
|
|
|
// Are we using Valve Index Controllers?
|
|
if (primaryRightController != null && !System.String.IsNullOrEmpty(primaryRightController.name)) {
|
|
return primaryRightController.name.Contains("Knuckles");
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#if UNITY_2019_2_OR_NEWER
|
|
float getFeatureUsage(InputDevice device, InputFeatureUsage<float> usage, bool clamp = true) {
|
|
float val;
|
|
device.TryGetFeatureValue(usage, out val);
|
|
|
|
return Mathf.Clamp01(val);
|
|
}
|
|
|
|
bool getFeatureUsage(InputDevice device, InputFeatureUsage<bool> usage) {
|
|
bool val;
|
|
if (device.TryGetFeatureValue(usage, out val)) {
|
|
return val;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
Vector2 getFeatureUsage(InputDevice device, InputFeatureUsage<Vector2> usage) {
|
|
Vector2 val;
|
|
if (device.TryGetFeatureValue(usage, out val)) {
|
|
return val;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
Vector3 getFeatureUsage(InputDevice device, InputFeatureUsage<Vector3> usage) {
|
|
Vector3 val;
|
|
if (device.TryGetFeatureValue(usage, out val)) {
|
|
return val;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
#endif
|
|
|
|
bool setTrackingOrigin = false;
|
|
public virtual void SetTrackingOriginMode(TrackingOriginModeFlags trackingOrigin) {
|
|
// 2019.4 Needs to use XRDevice.SetTrackingSpaceType; TrySetTrackingOriginMode does not function properly.
|
|
// *Removed from VRIF v1.6 as XR plugin should properly set tracking space
|
|
#if UNITY_2019_4
|
|
if (trackingOrigin == TrackingOriginModeFlags.Floor) {
|
|
#pragma warning disable
|
|
XRDevice.SetTrackingSpaceType(TrackingSpaceType.RoomScale);
|
|
#pragma warning restore
|
|
}
|
|
#endif
|
|
StartCoroutine(changeOriginModeRoutine(trackingOrigin));
|
|
}
|
|
|
|
IEnumerator changeOriginModeRoutine(TrackingOriginModeFlags trackingOrigin) {
|
|
|
|
// Wait one frame as Unity has an issue with calling this immediately
|
|
yield return null;
|
|
|
|
if(!setTrackingOrigin) {
|
|
List<XRInputSubsystem> subsystems = new List<XRInputSubsystem>();
|
|
SubsystemManager.GetInstances(subsystems);
|
|
int subSystemsCount = subsystems.Count;
|
|
|
|
if (subSystemsCount > 0) {
|
|
for (int x = 0; x < subSystemsCount; x++) {
|
|
if (subsystems[x].TrySetTrackingOriginMode(trackingOrigin)) {
|
|
setTrackingOrigin = true;
|
|
// Debug.Log("Successfully set TrackingOriginMode to " + trackingOrigin);
|
|
}
|
|
else {
|
|
Debug.LogWarning("Failed to set TrackingOriginMode to " + trackingOrigin);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// Debug.LogWarning("No subsystems detected. Unable to set Tracking Origin to " + trackingOrigin);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Start Vibration on controller
|
|
public void VibrateController(float frequency, float amplitude, float duration, ControllerHand hand) {
|
|
|
|
if (InputSource == XRInputSource.OVRInput) {
|
|
StartCoroutine(Vibrate(frequency, amplitude, duration, hand));
|
|
}
|
|
else if (InputSource == XRInputSource.SteamVR && SteamVRSupport && HMDActive) {
|
|
#if STEAM_VR_SDK
|
|
if (hand == ControllerHand.Right) {
|
|
if(SteamVR_Actions.vRIF_Haptic != null) {
|
|
SteamVR_Actions.vRIF_Haptic.Execute(0, duration, frequency, amplitude, SteamVR_Input_Sources.RightHand);
|
|
}
|
|
}
|
|
else {
|
|
if (SteamVR_Actions.vRIF_Haptic != null) {
|
|
SteamVR_Actions.vRIF_Haptic.Execute(0, duration, frequency, amplitude, SteamVR_Input_Sources.LeftHand);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
// Default / Fallback to XRInput
|
|
else {
|
|
if (hand == ControllerHand.Right) {
|
|
InputDevices.GetDevicesWithCharacteristics(InputDeviceCharacteristics.Right, devices);
|
|
}
|
|
else {
|
|
InputDevices.GetDevicesWithCharacteristics(InputDeviceCharacteristics.Left, devices);
|
|
}
|
|
|
|
for (int x = 0; x < devices.Count; x++) {
|
|
HapticCapabilities capabilities;
|
|
if (devices[x].TryGetHapticCapabilities(out capabilities)) {
|
|
if (capabilities.supportsImpulse) {
|
|
uint channel = 0;
|
|
devices[x].SendHapticImpulse(channel, amplitude, duration);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
IEnumerator Vibrate(float frequency, float amplitude, float duration, ControllerHand hand) {
|
|
#if OCULUS_INTEGRATION
|
|
// Start vibration
|
|
if (hand == ControllerHand.Right) {
|
|
OVRInput.SetControllerVibration(frequency, amplitude, OVRInput.Controller.RTouch);
|
|
}
|
|
else if (hand == ControllerHand.Left) {
|
|
OVRInput.SetControllerVibration(frequency, amplitude, OVRInput.Controller.LTouch);
|
|
}
|
|
|
|
yield return new WaitForSeconds(duration);
|
|
|
|
// Stop vibration
|
|
if (hand == ControllerHand.Right) {
|
|
OVRInput.SetControllerVibration(0, 0, OVRInput.Controller.RTouch);
|
|
}
|
|
else if (hand == ControllerHand.Left) {
|
|
OVRInput.SetControllerVibration(0, 0, OVRInput.Controller.LTouch);
|
|
}
|
|
#else
|
|
yield return new WaitForSeconds(duration);
|
|
#endif
|
|
}
|
|
}
|
|
} |