Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Assets/Tests/InputSystem/CoreTests_Controls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1428,7 +1428,7 @@ public void Controls_OptimizedControls_TrivialControlsAreOptimized()
Assert.That(mouse.position.x.optimizedControlDataType, Is.EqualTo(InputStateBlock.FormatFloat));
Assert.That(mouse.position.y.optimizedControlDataType, Is.EqualTo(InputStateBlock.FormatFloat));
Assert.That(mouse.position.optimizedControlDataType, Is.EqualTo(InputStateBlock.FormatVector2));
Assert.That(mouse.leftButton.optimizedControlDataType, Is.EqualTo(InputStateBlock.FormatInvalid));
Assert.That(mouse.leftButton.optimizedControlDataType, Is.EqualTo(InputStateBlock.FormatBit));

InputSystem.settings.SetInternalFeatureFlag(InputFeatureNames.kUseOptimizedControls, false);
Assert.That(mouse.position.x.optimizedControlDataType, Is.EqualTo(InputStateBlock.FormatInvalid));
Expand Down
46 changes: 46 additions & 0 deletions Assets/Tests/InputSystem/Plugins/XRTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,52 @@ public void Controls_OptimizedControls_PoseControl_IsOptimized()
Assert.That((device["posecontrol"] as PoseControl).optimizedControlDataType, Is.EqualTo(InputStateBlock.FormatPose));
}

[Test]
[Category("Controls")]
[TestCase(true)]
[TestCase(false)]
public void Controls_PoseControl_IsTracked_ReadsCorrectly(bool useOptimizedControls)
{
InputSystem.settings.SetInternalFeatureFlag(InputFeatureNames.kUseOptimizedControls, useOptimizedControls);

runtime.ReportNewInputDevice(PoseDeviceState.CreateDeviceDescription().ToJson());

InputSystem.Update();

var device = InputSystem.devices[0];
var poseControl = device["posecontrol"] as PoseControl;

// Queue state with isTracked = true (byte value 1)
InputSystem.QueueStateEvent(device, new PoseDeviceState
{
isTracked = 1,
trackingState = (uint)(InputTrackingState.Position | InputTrackingState.Rotation),
position = new Vector3(1, 2, 3),
rotation = Quaternion.identity,
});
InputSystem.Update();

// Reading isTracked as a ButtonControl should return true
Assert.That(poseControl.isTracked.isPressed, Is.True, "isTracked.isPressed should be true when tracked");
Assert.That(poseControl.isTracked.ReadValue(), Is.EqualTo(1.0f).Within(0.001f), "isTracked.ReadValue() should be 1.0f when tracked");

// Reading the full PoseState should also have isTracked = true
var poseState = poseControl.ReadValue();
Assert.That(poseState.isTracked, Is.True, "PoseState.isTracked should be true when tracked");

// Queue state with isTracked = false (byte value 0)
InputSystem.QueueStateEvent(device, new PoseDeviceState
{
isTracked = 0,
trackingState = 0,
});
InputSystem.Update();

Assert.That(poseControl.isTracked.isPressed, Is.False, "isTracked.isPressed should be false when not tracked");
Assert.That(poseControl.isTracked.ReadValue(), Is.EqualTo(0.0f).Within(0.001f), "isTracked.ReadValue() should be 0.0f when not tracked");
Assert.That(poseControl.ReadValue().isTracked, Is.False, "PoseState.isTracked should be false when not tracked");
}

// ISXB-405
[Test]
[Category("Devices")]
Expand Down
1 change: 1 addition & 0 deletions Packages/com.unity.inputsystem/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fixed an incorrect ArraysHelper.HaveDuplicateReferences implementation that didn't use its arguments right [ISXB-1792] (https://github.com/Unity-Technologies/InputSystem/pull/2376)
- Fixed `InputAction.IsPressed`, `WasPressedThisFrame`, and `WasReleasedThisFrame` using a `ButtonControl`'s `pressPoint` when a binding also had an explicit `PressInteraction` with its own `pressPoint`, which could make those APIs disagree with the interaction's press and release behavior. Action-level press APIs now follow the interaction threshold when both are set explicitly.
- Fixed `IndexOutOfRangeException` in `InputDeviceBuilder` when connecting an HID gamepad whose report descriptor declares a hat switch with Report Size 8 (e.g. ESP32-BLE-Gamepad). The HID layer now anchors the hat's directional sub-controls to the hat's own byte instead of letting the layout system auto-allocate a fresh byte for each [UUM-143659](https://jira.unity3d.com/browse/UUM-143659).
- Fixed `PoseControl.isTracked` always returning false when read through non-optimized code paths (e.g. Input Debugger) due to `sizeInBits = 8` causing the bool value to be normalized as `1/255` instead of `1.0`.

### Changed
- Action-level `IsPressed`, `WasPressedThisFrame`, and `WasReleasedThisFrame` for bindings to `Vector2Control` / `StickControl` no longer consult a per-control `pressPoint` on the vector (that field was removed). Use a `Press` interaction to set a custom threshold, or rely on `defaultButtonPressPoint`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,20 @@ internal void UpdateWasPressedEditor()

#endif // UNITY_EDITOR

protected override FourCC CalculateOptimizedControlDataType()
{
if (clamp == Clamp.None &&
invert == false &&
normalize == false &&
scale == false &&
m_StateBlock.format == InputStateBlock.FormatBit &&
m_StateBlock.sizeInBits == 1 &&
m_StateBlock.bitOffset == 0)
return InputStateBlock.FormatBit;

return base.CalculateOptimizedControlDataType();
}

// We make the current global default button press point available as a static so that we don't have to
// constantly make the hop from InputSystem.settings -> InputManager.m_Settings -> defaultButtonPressPoint.
internal static float s_GlobalDefaultButtonPressPoint;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public PoseState(bool isTracked, TrackingState trackingState, Vector3 position,
/// <remarks>
/// Fully tracked means that the pose is accurate and not using any simulated or extrapolated positions, and the system tracking this pose is able to confidently track this object.
/// </remarks>
[FieldOffset(0), InputControl(displayName = "Is Tracked", layout = "Button", sizeInBits = 8 /* needed to ensure optimization kicks-in */)]
[FieldOffset(0), InputControl(displayName = "Is Tracked", layout = "Button", sizeInBits = 1)]
public bool isTracked;

/// <summary>
Expand Down Expand Up @@ -252,7 +252,7 @@ protected override FourCC CalculateOptimizedControlDataType()
if (
m_StateBlock.sizeInBits == PoseState.kSizeInBytes * 8 &&
m_StateBlock.bitOffset == 0 &&
isTracked.optimizedControlDataType == InputStateBlock.kFormatByte &&
isTracked.optimizedControlDataType == InputStateBlock.kFormatBit &&
trackingState.optimizedControlDataType == InputStateBlock.kFormatInt &&
position.optimizedControlDataType == InputStateBlock.kFormatVector3 &&
rotation.optimizedControlDataType == InputStateBlock.kFormatQuaternion &&
Expand Down