justink2 Posted November 7 Posted November 7 Hello, I am trying to get data in from the HTC Vive Tracker 3.0 into Unity. I am using the SteamVR app to connect to the devices. HTC’s tracker 3.0 developer guidelines https://developer.vive.com/documents/850/HTC_Vive_Tracker_3.0_Developer_Guidelines_v1.1_06022021.pdf specify how you can use the pogo pins to send input to an application. Those pogo pins give you four booleans to work with. It also specifies how you can use USB to send additional data to the tracker (three float values and two additional booleans), although these only show up in the SteamVR test controller screen if you modify the tracker's config file to say it's a controller https://www.reddit.com/r/beatsaber/comments/bn6e4u/ragesaqs_school_of_making_a_vive_tracker_maul/ The issue at hand is that I cannot get that input into Unity or any other application using OpenXR if the tracker is not set to "Held in Hand." There have been a number of forum posts that bring up this issue, and it's always mentioned that it works by setting the role to held in hand, but my use case requires the use of more than two controllers. I'm already using both controllers and I want to be able to use the additional input provided by the trackers. I don't see anything in the OpenXR specifications that would indicate input is restricted to only held in hand trackers. My current thought is that SteamVR simply hasn't implemented the ability to get input from all trackers. The script I am using is below. It is based off this script from Unity staff member thep3000 https://discussions.unity.com/t/openxr-and-openvr-together/841675/21, this script from HTC's Vive OpenXR github repo https://github.com/ViveSoftware/VIVE-OpenXR/blob/5ac252bf2edfcbc04d952e183bfaa49d35534b2e/com.htc.upm.vive.openxr/Runtime/Features/Tracker/XR/Scripts/ViveXRTracker.cs#L49, and Unity's builtin OpenXR HTC Vive Controller profile https://github.com/needle-mirror/com.unity.xr.openxr/blob/151909c9b7844198486520b1c4b6ae77aa9d4d62/Runtime/Features/Interactions/HTCViveControllerProfile.cs#L34 This script doesn't actually read in anything besides the pose data that originally worked with thep3000's script. Thus, I have two questions 1) How can I read in input data from the tracker into any application, specifically Unity here? I think this is a SteamVR issue where it's just not doing anything with input data if the tracker isn't set to held in hand 2) How can I get full USB input to read into SteamVR without having to manually change the configuration file of the tracker? Having to do so basically removes the ability, as it significantly increases complexity for the end user. But being able to use it would be great since it's so much added data. Relevant links: Vive forum: how to use the Vive Tracker in OpenXR: https://forum.htc.com/topic/14370-tutorial-openxr-pc-vr-how-to-use-vive-tracker/#comment-50165 Vive forum: tracker pogo pin input in OpenXR: https://forum.htc.com/topic/9467-tracker-pogo-pin-input-in-openxr/#comment-39822 SteamVR forum: getting haptic output from the trackers: https://steamcommunity.com/app/250820/discussions/0/4357871582651459139/ using System; using System.Collections.Generic; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Layouts; using UnityEngine.InputSystem.XR; using UnityEngine.Scripting; using UnityEngine.XR.OpenXR.Input; #if UNITY_EDITOR using UnityEditor; #endif using PoseControl = UnityEngine.InputSystem.XR.PoseControl; /// OpenXR HTC vive tracker interaction specification /// <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_HTCX_vive_tracker_interaction"/> /// original HTC Vive Tracker Interaction Profile with only device Pose /// <see href="https://discussions.unity.com/t/openxr-and-openvr-together/841675/21"/> /// Vive's official OpenXR interaction profile for the Ultimate Tracker /// <see href="https://github.com/ViveSoftware/VIVE-OpenXR/blob/5ac252bf2edfcbc04d952e183bfaa49d35534b2e/com.htc.upm.vive.openxr/Runtime/Features/Tracker/XR/Scripts/ViveXRTracker.cs"/> namespace UnityEngine.XR.OpenXR.Features.Interactions { /// <summary> /// This <see cref="OpenXRInteractionFeature"/> enables the use of the HTC Vive Tracker interaction profiles in OpenXR /// </summary> #if UNITY_EDITOR [UnityEditor.XR.OpenXR.Features.OpenXRFeature( UiName = "HTC Vive Tracker OpenXR Profile", BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA }, Company = "MASSIVE", Desc = "Support for enabling the Vive XR Tracker interaction profile. Registers the controller map for tracker if enabled.", DocumentationLink = Constants.k_DocumentationManualURL, OpenxrExtensionStrings = extensionName, Category = UnityEditor.XR.OpenXR.Features.FeatureCategory.Interaction, FeatureId = featureId, Version = "0.0.1")] #endif public class ViveTrackerOpenXRProfile : OpenXRInteractionFeature { /// <summary> /// OpenXR specification that supports the vive tracker /// <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_HTCX_vive_tracker_interaction"/> /// </summary> public const string extensionName = "XR_HTCX_vive_tracker_interaction"; /// <summary> /// The feature id string. This is used to give the feature a well known id for reference /// </summary> public const string featureId = "com.massive.openxr.feature.input.htcvivetracker"; /// <summary> /// The interaction profile path for the HTC Vive Tracker in OpenXR /// </summary> public const string profile = "/interaction_profiles/htc/vive_tracker_htcx"; /// <summary> /// /// </summary> private const string kDeviceLocalizedName = "HTC Vive Tracker OpenXR"; /// <summary> /// OpenXR user path definitions for XR_HTCX_vive_tracker_interaction /// </summary> public struct TrackerUserPaths { // if you add the below missing paths, also add the path name to commonUsages of XRViveTracker // as of the creation of this script, left_wrist, right_wrist, left_ankle, and right_ankle are not supported by SteamVR // missing XR_NULL_PATH // missing handheld_object public const string leftFoot = "/user/vive_tracker_htcx/role/left_foot"; public const string rightFoot = "/user/vive_tracker_htcx/role/right_foot"; public const string leftShoulder = "/user/vive_tracker_htcx/role/left_shoulder"; public const string rightShoulder = "/user/vive_tracker_htcx/role/right_shoulder"; public const string leftElbow = "/user/vive_tracker_htcx/role/left_elbow"; public const string rightElbow = "/user/vive_tracker_htcx/role/right_elbow"; public const string leftKnee = "/user/vive_tracker_htcx/role/left_knee"; public const string rightKnee = "/user/vive_tracker_htcx/role/right_knee"; // missing left_wrist // missing right_wrist // missing left_ankle // missing right_ankle public const string waist = "/user/vive_tracker_htcx/role/waist"; public const string chest = "/user/vive_tracker_htcx/role/chest"; public const string camera = "/user/vive_tracker_htcx/role/camera"; public const string keyboard = "/user/vive_tracker_htcx/role/keyboard"; } /// <summary> /// OpenXR component path definitions for XR_HTCX_vive_tracker_interaction. /// Component paths are used by input subsystem to bind physical inputs to actions. /// </summary> public struct TrackerComponentPaths { // type PoseControl public const string devicepose = "/input/grip/pose"; // type ButtonControl public const string system = "/input/system/click"; // may not be available for application use public const string menu = "/input/menu/click"; public const string grip = "/input/squeeze/click"; public const string trigger = "/input/trigger/click"; public const string pad = "/input/trackpad/click"; public const string padTouch = "/input/trackpad/touch"; // type AxisControl public const string triggerValue = "/input/trigger/value"; public const string padXValue = "/input/trackpad/x"; public const string padYValue = "/input/trackpad/y"; //type HapticControl public const string haptic = "/output/haptic"; } /// <summary> /// A set of bit flags describing XR.InputDevice characteristics /// </summary> [Flags] public enum InputDeviceTrackerCharacteristics : uint { TrackerLeftFoot = 0x1000u, TrackerRightFoot = 0x2000u, TrackerLeftShoulder = 0x4000u, TrackerRightShoulder = 0x8000u, TrackerLeftElbow = 0x10000u, TrackerRightElbow = 0x20000u, TrackerLeftKnee = 0x40000u, TrackerRightKnee = 0x80000u, TrackerWaist = 0x100000u, TrackerChest = 0x200000u, TrackerCamera = 0x400000u, TrackerKeyboard = 0x800000u } /// <summary> /// An Input System device based off the <a href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_HTCX_vive_tracker_interaction">HTC Vive Tracker OpenXR specifications /// </summary> [Preserve, InputControlLayout(displayName = "HTC Vive Tracker (OpenXR)", commonUsages = new[] { "Left Foot", "Right Foot", "Left Shoulder", "Right Shoulder", "Left Elbow", "Right Elbow", "Left Knee", "Right Knee", "Waist", "Chest", "Camera", "Keyboard" }, isGenericTypeOfDevice = true)] public class ViveTrackerOpenXR : XRControllerWithRumble { #region Pose /// <summary> /// device pose. Contains isTracked, trackingState, position, rotation, velocity, and angularVelocity /// <see cref="TrackerComponentPaths.devicepose"/> /// </summary> [Preserve, InputControl(offset = 0, aliases = new[] { "device", "entityPose" }, usage = "Device", noisy = true)] public PoseControl devicePose { get; private set; } /// <summary> /// if data is valid, equivalent to devicePose/isTracked /// necessary for compatibility with XRSDK layouts /// </summary> [Preserve, InputControl(offset = 0, usage = "IsTracked")] new public ButtonControl isTracked { get; private set; } /// <summary> /// represents what data is valid, equivalent to devicePose/trackingState /// necessary for compatibility with XRSDK layouts /// </summary> [Preserve, InputControl(offset = 4, usage = "TrackingState")] new public IntegerControl trackingState { get; private set; } /// <summary> /// position of device, equivalent to devicePose/position /// necessary for compatibility with XRSDK layouts /// </summary> [Preserve, InputControl(offset = 8, alias = "gripPosition")] new public Vector3Control devicePosition { get; private set; } /// <summary> /// rotation/orientation of device, equivalent to devicePose/rotation /// necessary for compatibility with XRSDK layouts /// </summary> [Preserve, InputControl(offset = 20, alias = "gripOrientation")] new public QuaternionControl deviceRotation { get; private set; } #endregion #region Boolean Inputs /// <summary> /// System button on top of tracker. May not be available for application use /// <see cref="TrackerComponentPaths.system"/> /// </summary> [Preserve, InputControl(alias = "systemButton", usage = "SystemButton")] public ButtonControl system { get; private set; } /// <summary> /// Menu button. Accessed on vive tracker 3.0 via USB or by shorting pins 2 and 6 /// <see cref="TrackerComponentPaths.menu"/> /// </summary> [Preserve, InputControl(alias = "menuButton", usage = "MenuButton")] public ButtonControl menu { get; private set; } /// <summary> /// Grip button. Accessed on vive tracker 3.0 via USB or by shorting pins 2 and 3 /// <see cref="TrackerComponentPaths.grip"/> /// </summary> [Preserve, InputControl(alias = "gripButton", usage = "GripButton")] public ButtonControl grip { get; private set; } /// <summary> /// Trigger button. Accessed on vive tracker 3.0 via USB or by shorting pins 2 and 4 /// <see cref="TrackerComponentPaths.trigger"/> /// </summary> [Preserve, InputControl(alias = "triggerButton", usage = "TriggerButton")] public ButtonControl trigger { get; private set; } /// <summary> /// Trackpad button. Accessed on vive tracker 3.0 via USB or by shorting pins 2 and 5 /// <see cref="TrackerComponentPaths.pad"/> /// </summary> [Preserve, InputControl(alias = "trackpadButton", usage = "TrackpadButton")] public ButtonControl pad { get; private set; } /// <summary> /// Trackpad touch. Only accessible on vive tracker 3.0 via USB /// <see cref="TrackerComponentPaths.padTouch"/> /// </summary> [Preserve, InputControl(alias = "trackpadTouch", usage = "TrackpadTouch")] public ButtonControl padTouch { get; private set; } #endregion #region Float Inputs /// <summary> /// Trigger pull analog value. Only accessible on vive tracker 3.0 via USB /// <see cref="TrackerComponentPaths.triggerValue"/> /// </summary> [Preserve, InputControl(alias = "triggerValue", usage = "TriggerValue")] public AxisControl triggerValue { get; private set; } /// <summary> /// Trackpad X/horizontal analog value. Only accessible on vive tracker 3.0 via USB /// <see cref="TrackerComponentPaths.padXValue"/> /// </summary> [Preserve, InputControl(alias = "trackpadXValue", usage = "TrackpadXValue")] public AxisControl padXValue { get; private set; } /// <summary> /// Trackpad Y/vertical analog value. Only accessible on vive tracker 3.0 via USB /// <see cref="TrackerComponentPaths.padYValue"/> /// </summary> [Preserve, InputControl(alias = "trackpadYValue", usage = "TrackpadYValue")] public AxisControl padYValue { get; private set; } #endregion #region device Outputs /// <summary> /// Haptic outputs. Accessed on vive tracker 3.0 by pogo pin 1. Untested via USB /// <see cref="TrackerComponentPaths.haptic"/> /// </summary> [Preserve, InputControl(usage = "Haptic")] public HapticControl haptic { get; private set; } #endregion /// <inheritdoc cref="OpenXRDevice"/> protected override void FinishSetup() { base.FinishSetup(); devicePose = GetChildControl<PoseControl>("devicePose"); isTracked = GetChildControl<ButtonControl>("isTracked"); trackingState = GetChildControl<IntegerControl>("trackingState"); devicePosition = GetChildControl<Vector3Control>("devicePosition"); deviceRotation = GetChildControl<QuaternionControl>("deviceRotation"); system = GetChildControl<ButtonControl>("system"); menu = GetChildControl<ButtonControl>("menu"); grip = GetChildControl<ButtonControl>("grip"); trigger = GetChildControl<ButtonControl>("trigger"); pad = GetChildControl<ButtonControl>("pad"); padTouch = GetChildControl<ButtonControl>("padTouch"); triggerValue = GetChildControl<AxisControl>("triggerValue"); padXValue = GetChildControl<AxisControl>("padXValue"); padYValue = GetChildControl<AxisControl>("padYValue"); haptic = GetChildControl<HapticControl>("haptic"); var deviceDescriptor = XRDeviceDescriptor.FromJson(description.capabilities); if ((deviceDescriptor.characteristics & (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerLeftFoot) != 0) InputSystem.InputSystem.SetDeviceUsage(this, "Left Foot"); else if ((deviceDescriptor.characteristics & (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerRightFoot) != 0) InputSystem.InputSystem.SetDeviceUsage(this, "Right Foot"); else if ((deviceDescriptor.characteristics & (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerLeftShoulder) != 0) InputSystem.InputSystem.SetDeviceUsage(this, "Left Shoulder"); else if ((deviceDescriptor.characteristics & (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerRightShoulder) != 0) InputSystem.InputSystem.SetDeviceUsage(this, "Right Shoulder"); else if ((deviceDescriptor.characteristics & (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerLeftElbow) != 0) InputSystem.InputSystem.SetDeviceUsage(this, "Left Elbow"); else if ((deviceDescriptor.characteristics & (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerRightElbow) != 0) InputSystem.InputSystem.SetDeviceUsage(this, "Right Elbow"); else if ((deviceDescriptor.characteristics & (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerLeftKnee) != 0) InputSystem.InputSystem.SetDeviceUsage(this, "Left Knee"); else if ((deviceDescriptor.characteristics & (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerRightKnee) != 0) InputSystem.InputSystem.SetDeviceUsage(this, "Right Knee"); else if ((deviceDescriptor.characteristics & (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerWaist) != 0) InputSystem.InputSystem.SetDeviceUsage(this, "Waist"); else if ((deviceDescriptor.characteristics & (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerChest) != 0) InputSystem.InputSystem.SetDeviceUsage(this, "Chest"); else if ((deviceDescriptor.characteristics & (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerCamera) != 0) InputSystem.InputSystem.SetDeviceUsage(this, "Camera"); else if ((deviceDescriptor.characteristics & (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerKeyboard) != 0) InputSystem.InputSystem.SetDeviceUsage(this, "Keyboard"); else { Debug.Log("No tracker role could be found that matches this device"); } Debug.Log("Device added"); } } /// <summary> /// Registers the <see cref="ViveTracker"/> layout with the Input System. /// </summary> protected override void RegisterDeviceLayout() { InputSystem.InputSystem.RegisterLayout(typeof(ViveTrackerOpenXR), matches: new InputDeviceMatcher() .WithInterface(XRUtilities.InterfaceMatchAnyVersion) .WithProduct(kDeviceLocalizedName)); } /// <summary> /// Removes the <see cref="ViveTracker"/> layout from the Input System. /// </summary> protected override void UnregisterDeviceLayout() { InputSystem.InputSystem.RemoveLayout(nameof(ViveTrackerOpenXR)); } /// <inheritdoc/> protected override void RegisterActionMapsWithRuntime() { ActionMapConfig actionMap = new ActionMapConfig() { name = "htcvivetracker", localizedName = kDeviceLocalizedName, desiredInteractionProfile = profile, manufacturer = "HTC", serialNumber = "", deviceInfos = new List<DeviceConfig>() { new DeviceConfig() { characteristics = (InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerLeftFoot), userPath = TrackerUserPaths.leftFoot }, new DeviceConfig() { characteristics = (InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerRightFoot), userPath = TrackerUserPaths.rightFoot }, new DeviceConfig() { characteristics = (InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerLeftShoulder), userPath = TrackerUserPaths.leftShoulder }, new DeviceConfig() { characteristics = (InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerRightShoulder), userPath = TrackerUserPaths.rightShoulder }, new DeviceConfig() { characteristics = (InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerLeftElbow), userPath = TrackerUserPaths.leftElbow }, new DeviceConfig() { characteristics = (InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerRightElbow), userPath = TrackerUserPaths.rightElbow }, new DeviceConfig() { characteristics = (InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerLeftKnee), userPath = TrackerUserPaths.leftKnee }, new DeviceConfig() { characteristics = (InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerRightKnee), userPath = TrackerUserPaths.rightKnee }, new DeviceConfig() { characteristics = (InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerWaist), userPath = TrackerUserPaths.waist }, new DeviceConfig() { characteristics = (InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerChest), userPath = TrackerUserPaths.chest }, new DeviceConfig() { characteristics = (InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerCamera), userPath = TrackerUserPaths.camera }, new DeviceConfig() { characteristics = (InputDeviceCharacteristics.TrackedDevice | InputDeviceCharacteristics.Controller | (InputDeviceCharacteristics)InputDeviceTrackerCharacteristics.TrackerKeyboard), userPath = TrackerUserPaths.keyboard } }, actions = new List<ActionConfig>() { // Device Pose new ActionConfig() { name = "devicePose", localizedName = "Grip Pose", type = ActionType.Pose, usages = new List<string>() { "Device" }, bindings = new List<ActionBinding>() { new ActionBinding() { interactionPath = TrackerComponentPaths.devicepose, interactionProfileName = profile, } } }, // System button new ActionConfig() { name = "system", localizedName = "System", type = ActionType.Binary, usages = new List<string>() { "SystemButton" }, bindings = new List<ActionBinding>() { new ActionBinding() { interactionPath = TrackerComponentPaths.system, interactionProfileName = profile, } } }, // Menu button new ActionConfig() { name = "menu", localizedName = "Menu", type = ActionType.Binary, usages = new List<string>() { "MenuButton" }, bindings = new List<ActionBinding>() { new ActionBinding() { interactionPath = TrackerComponentPaths.menu, interactionProfileName = profile, } } }, // Grip button new ActionConfig() { name = "grip", localizedName = "Grip", type = ActionType.Binary, usages = new List<string>() { "GripButton" }, bindings = new List<ActionBinding>() { new ActionBinding() { interactionPath = TrackerComponentPaths.grip, interactionProfileName = profile, } } }, // Trigger button new ActionConfig() { name = "trigger", localizedName = "Trigger", type = ActionType.Binary, usages = new List<string>() { "TriggerButton" }, bindings = new List<ActionBinding>() { new ActionBinding() { interactionPath = TrackerComponentPaths.trigger, interactionProfileName = profile, } } }, // Trackpad button new ActionConfig() { name = "pad", localizedName = "Pad", type = ActionType.Binary, usages = new List<string>() { "TrackpadButton" }, bindings = new List<ActionBinding>() { new ActionBinding() { interactionPath = TrackerComponentPaths.pad, interactionProfileName = profile, } } }, // Trackpad touch new ActionConfig() { name = "padTouch", localizedName = "PadTouch", type = ActionType.Binary, usages = new List<string>() { "TrackpadTouch" }, bindings = new List<ActionBinding>() { new ActionBinding() { interactionPath = TrackerComponentPaths.padTouch, interactionProfileName = profile, } } }, // Trigger pull analog value new ActionConfig() { name = "triggerValue", localizedName = "TriggerValue", type = ActionType.Axis1D, usages = new List<string>() { "TrackpadValue" }, bindings = new List<ActionBinding>() { new ActionBinding() { interactionPath = TrackerComponentPaths.triggerValue, interactionProfileName = profile, } } }, // Trackpad X/horizontal analog value new ActionConfig() { name = "padXValue", localizedName = "Trackpad X Value", type = ActionType.Axis1D, usages = new List<string>() { "TrackpadXValue" }, bindings = new List<ActionBinding>() { new ActionBinding() { interactionPath = TrackerComponentPaths.padXValue, interactionProfileName = profile, } } }, // Trackpad Y/vertical analog value new ActionConfig() { name = "padYValue", localizedName = "Trackpad Y Value", type = ActionType.Axis1D, usages = new List<string>() { "TrackpadYValue" }, bindings = new List<ActionBinding>() { new ActionBinding() { interactionPath = TrackerComponentPaths.padYValue, interactionProfileName = profile, } } }, // Haptic output new ActionConfig() { name = "haptic", localizedName = "Haptic Output", type = ActionType.Vibrate, usages = new List<string>() { "Haptic" }, bindings = new List<ActionBinding>() { new ActionBinding() { interactionPath = TrackerComponentPaths.haptic, interactionProfileName = profile, } } } } }; AddActionMap(actionMap); } protected override bool OnInstanceCreate(ulong xrInstance) { bool res = base.OnInstanceCreate(xrInstance); string debug = "HTC Vive Tracker OpenXR Extension "; if (OpenXRRuntime.IsExtensionEnabled(extensionName)) { Debug.Log(debug + "Enabled"); } else { Debug.LogWarning(debug + "Not Enabled"); } return res; } } }
VIVE_chengnay Posted November 22 Posted November 22 Hi @justink2, We are looking into this and need to check with Unity. Will get back to you when I have answer or fix for this issue. Sorry for the inconvenience.
justink2 Posted November 27 Author Posted November 27 Hi @VIVE_chengnay, I have seen a bunch of sources state that SteamVR is the issue for not properly implementing the XR_HTCX_vive_tracker_interaction extension. I cannot say for certain, but I am pretty sure Unity's Input System is device-agnostic and thus shouldn't be the issue. It seems to me that once SteamVR allows applications to get input from trackers via OpenXR (currently, I have to use a janky workaround using SteamVR.GetControllerState that doesn't always work), both Unity and other engines should be able to grab input from the extension with ease.
VIVE_chengnay Posted November 27 Posted November 27 Hi @justink2, Thanks for your information, but we did verify with Unreal which works. That's why we would like to clarify with Unity. 1
MilanTemp Posted November 28 Posted November 28 Are there any updates or new information available regarding its implementation or support in Unity?
justink2 Posted December 5 Author Posted December 5 (edited) On 11/27/2024 at 11:19 AM, VIVE_chengnay said: Hi @justink2, Thanks for your information, but we did verify with Unreal which works. That's why we would like to clarify with Unity. I did run a quick test with Unreal to confirm it was SteamVR and I couldn't get it to work on my end, would you be willing to provide the script/any resources you used? Thanks Edited December 5 by justink2
VIVE_chengnay Posted December 6 Posted December 6 Hi @justink2, May I know the versions of plugins, Unreal and SteamVR that you are using? How did you test the pogo pin input?
VIVE_chengnay Posted December 6 Posted December 6 Hi @justink2, There is workaround method that you can try. https://forums.unrealengine.com/t/how-to-use-vive-trackers-in-ue-5-2-and-later-versions/782293/38
justink2 Posted December 6 Author Posted December 6 17 hours ago, VIVE_chengnay said: Hi @justink2, May I know the versions of plugins, Unreal and SteamVR that you are using? How did you test the pogo pin input? @VIVE_chengnay I followed the tutorial you sent above, I should have clarified that I cannot get input if I am already using two controllers. My use case is using two controllers in hand and additional trackers for supplementary input. The tutorial also states that they only used two trackers without controllers. Were you able to get it working with 2 controllers and additional trackers? I believe any input I can currently get via the trackers is done by SteamVR or another application just mapping those inputs to the primary controller inputs which are then received by the application. This of course means that if I already have two controllers connected, I can't receive that input. Unity 2022.3 LTS, Input System 1.7.0, OpenXR 1.7.0, XR Interaction Toolkit 2.5.2 Unreal 5.4, OpenXR 1.0, OpenXRViveTracker 1.0, Enhanced Input 1.0 SteamVR 2.0
VIVE_chengnay Posted December 7 Posted December 7 9 hours ago, justink2 said: SteamVR 2.0 This seems kinda old? I saw my version is 2.8.7. 9 hours ago, justink2 said: I followed the tutorial you sent above, I should have clarified that I cannot get input if I am already using two controllers. My use case is using two controllers in hand and additional trackers for supplementary input. I will need to check with my colleague and get back to you later. Did you check using SteamVR's input debugger where you can choose current connected devices? May I know what role did you set for your trackers? Did you try HandRole or other body parts(Waist or Knee)?
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now