Skip to content

Commit f010d4c

Browse files
authored
FIX: Trackedposedriver stops tracking (ISXB-1555) (#2189)
1 parent 652aed9 commit f010d4c

File tree

3 files changed

+91
-18
lines changed

3 files changed

+91
-18
lines changed

Assets/Tests/InputSystem/Plugins/XRTests.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// ENABLE_VR is not defined on Game Core but the assembly is available with limited features when the XR module is enabled.
22
#if ENABLE_VR || UNITY_GAMECORE
33
using System;
4+
using System.Collections;
45
using System.Collections.Generic;
56
using System.Runtime.InteropServices;
67
using NUnit.Framework;
@@ -11,6 +12,7 @@
1112
using UnityEngine.InputSystem.LowLevel;
1213
using UnityEngine.InputSystem.Utilities;
1314
using UnityEngine.InputSystem.XR;
15+
using UnityEngine.TestTools;
1416
using UnityEngine.XR;
1517

1618
using Usages = UnityEngine.InputSystem.CommonUsages;
@@ -629,6 +631,54 @@ public void Components_TrackedPoseDriver_DoesNotEnableOrDisableReferenceActions(
629631
Assert.That(trackingStateInput.action.enabled, Is.False);
630632
}
631633

634+
[UnityTest]
635+
[Category("Components")]
636+
public IEnumerator CanUseTrackedPoseDriverWithoutTrackingAction()
637+
{
638+
var go = new GameObject();
639+
var tpd = go.AddComponent<TrackedPoseDriver>();
640+
tpd.updateType = TrackedPoseDriver.UpdateType.UpdateAndBeforeRender;
641+
tpd.trackingType = TrackedPoseDriver.TrackingType.RotationAndPosition;
642+
tpd.ignoreTrackingState = false;
643+
var transform = tpd.transform;
644+
645+
var positionAction = new InputAction(binding: "<XRController>/devicePosition");
646+
var rotationAction = new InputAction(binding: "<XRController>/deviceRotation");
647+
tpd.positionInput = new InputActionProperty(positionAction);
648+
tpd.rotationInput = new InputActionProperty(rotationAction);
649+
650+
yield return null;
651+
652+
Assert.That(positionAction.controls.Count, Is.EqualTo(0));
653+
Assert.That(rotationAction.controls.Count, Is.EqualTo(0));
654+
655+
var device = InputSystem.AddDevice<XRController>();
656+
InputSystem.AddDeviceUsage(device, "RightHand");
657+
658+
yield return null;
659+
660+
Assert.That(positionAction.controls.Count, Is.EqualTo(1));
661+
Assert.That(rotationAction.controls.Count, Is.EqualTo(1));
662+
663+
var position = new Vector3(1f, 2f, 3f);
664+
var rotation = new Quaternion(0.09853293f, 0.09853293f, 0.09853293f, 0.9853293f);
665+
using (StateEvent.From(device, out var stateEvent))
666+
{
667+
device.devicePosition.WriteValueIntoEvent(position, stateEvent);
668+
device.deviceRotation.WriteValueIntoEvent(rotation, stateEvent);
669+
670+
transform.position = Vector3.zero;
671+
transform.rotation = Quaternion.identity;
672+
InputSystem.QueueEvent(stateEvent);
673+
InputSystem.Update(InputUpdateType.Dynamic);
674+
}
675+
676+
yield return null;
677+
678+
Assert.That(transform.position, Is.EqualTo(position));
679+
Assert.That(transform.rotation, Is.EqualTo(rotation));
680+
}
681+
632682
[Test]
633683
[Category("Components")]
634684
public void Components_TrackedPoseDriver_RequiresResolvedTrackingStateBindings()

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ however, it has to be formatted properly to pass verification tests.
3131
- Fixed PlayerInput component automatically switching away from the default ActionMap set to 'None'.
3232
- Fixed a console error being shown when targeting visionOS builds in 2022.3.
3333
- Fixed a Tap Interaction issue with analog controls. The Tap interaction would keep re-starting after timeout. [ISXB-627](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-627)
34+
- Fixed TrackedPoseDriver stops updating position and rotation when device is added after its initialization. [ISXB-1555](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1555)
3435
- Fixed PlayerInput component not working with C# Wrappers (ISXB-1535). This reverted changes done to fix [ISXB-920](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-920) but users can now fix it themselves.
3536

3637
## [1.14.0] - 2025-03-20

Packages/com.unity.inputsystem/InputSystem/Plugins/XR/TrackedPoseDriver.cs

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ protected virtual void Awake()
432432
protected void OnEnable()
433433
{
434434
InputSystem.onAfterUpdate += UpdateCallback;
435+
InputSystem.onDeviceChange += OnDeviceChanged;
435436
BindActions();
436437

437438
// Read current input values when becoming enabled,
@@ -446,6 +447,7 @@ protected void OnDisable()
446447
{
447448
UnbindActions();
448449
InputSystem.onAfterUpdate -= UpdateCallback;
450+
InputSystem.onDeviceChange -= OnDeviceChanged;
449451
}
450452

451453
/// <summary>
@@ -484,7 +486,7 @@ protected void UpdateCallback()
484486
else
485487
m_CurrentRotation = transform.localRotation;
486488

487-
ReadTrackingState(hasResolvedPositionInputControl, hasResolvedRotationInputControl);
489+
ReadTrackingState();
488490

489491
m_IsFirstUpdate = false;
490492
}
@@ -495,7 +497,40 @@ protected void UpdateCallback()
495497
OnUpdate();
496498
}
497499

498-
void ReadTrackingState(bool hasResolvedPositionInputControl, bool hasResolvedRotationInputControl)
500+
void OnDeviceChanged(InputDevice inputDevice, InputDeviceChange inputDeviceChange)
501+
{
502+
if (m_IsFirstUpdate)
503+
return;
504+
ReadTrackingStateWithoutTrackingAction();
505+
}
506+
507+
/// <summary>
508+
/// React to changes of devices to stop the tracking of position / rotation or both if a device is removed, starts the tracking if
509+
/// a device is added.
510+
/// </summary>
511+
void ReadTrackingStateWithoutTrackingAction()
512+
{
513+
var trackingStateAction = m_TrackingStateInput.action;
514+
if (trackingStateAction != null && trackingStateAction.m_BindingsCount != 0)
515+
return;
516+
517+
var hasResolvedPositionInputControl = HasResolvedControl(m_PositionInput.action);
518+
var hasResolvedRotationInputControl = HasResolvedControl(m_RotationInput.action);
519+
520+
// Treat an Input Action Reference with no reference the same as
521+
// an enabled Input Action with no authored bindings, and allow driving the Transform pose.
522+
// Check if we have transform and rotation controls to drive the pose.
523+
if (hasResolvedPositionInputControl && hasResolvedRotationInputControl)
524+
m_CurrentTrackingState = TrackingStates.Position | TrackingStates.Rotation;
525+
else if (hasResolvedPositionInputControl)
526+
m_CurrentTrackingState = TrackingStates.Position;
527+
else if (hasResolvedRotationInputControl)
528+
m_CurrentTrackingState = TrackingStates.Rotation;
529+
else
530+
m_CurrentTrackingState = TrackingStates.None;
531+
}
532+
533+
void ReadTrackingState()
499534
{
500535
var trackingStateAction = m_TrackingStateInput.action;
501536
if (trackingStateAction != null && !trackingStateAction.enabled)
@@ -504,29 +539,16 @@ void ReadTrackingState(bool hasResolvedPositionInputControl, bool hasResolvedRot
504539
m_CurrentTrackingState = TrackingStates.None;
505540
return;
506541
}
507-
508-
if (trackingStateAction == null || trackingStateAction.m_BindingsCount == 0)
509-
{
510-
// Treat an Input Action Reference with no reference the same as
511-
// an enabled Input Action with no authored bindings, and allow driving the Transform pose.
512-
// Check if we have transform and rotation controls to drive the pose.
513-
if (hasResolvedPositionInputControl && hasResolvedRotationInputControl)
514-
m_CurrentTrackingState = TrackingStates.Position | TrackingStates.Rotation;
515-
else if (hasResolvedPositionInputControl)
516-
m_CurrentTrackingState = TrackingStates.Position;
517-
else if (hasResolvedRotationInputControl)
518-
m_CurrentTrackingState = TrackingStates.Rotation;
519-
else
520-
m_CurrentTrackingState = TrackingStates.None;
521-
}
522-
else if (HasResolvedControl(trackingStateAction))
542+
if (HasResolvedControl(trackingStateAction))
523543
{
524544
// Retain the current value if there is no resolved binding.
525545
// Since the field initializes to allowing position and rotation,
526546
// this allows for driving the Transform pose always when the device
527547
// doesn't support reporting the tracking state.
528548
m_CurrentTrackingState = (TrackingStates)trackingStateAction.ReadValue<int>();
549+
return;
529550
}
551+
ReadTrackingStateWithoutTrackingAction();
530552
}
531553

532554
/// <summary>

0 commit comments

Comments
 (0)