Skip to content
Draft
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
39 changes: 39 additions & 0 deletions Assets/Tests/InputSystem/CoreTests_Actions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,45 @@ public void Actions_ValueActionsEnabledInOnEvent_DoNotReactToCurrentStateOfContr
}
}

// Regression test for UUM-100125.
[Test]
[Category("Actions")]
public void Actions_InitialStateCheckAfterConfigurationChange_DoesNotTriggerForInactiveTouch()
{
var touchscreen = InputSystem.AddDevice<Touchscreen>();
var action = new InputAction(type: InputActionType.Value, binding: "<Touchscreen>/primaryTouch/position");
action.Enable();

// Run the first initial state check from enabling the action.
InputSystem.Update();

using (var trace = new InputActionTrace(action))
{
BeginTouch(1, new Vector2(123, 234));
EndTouch(1, new Vector2(345, 456));

Assert.That(touchscreen.primaryTouch.isInProgress, Is.False);
Assert.That(touchscreen.primaryTouch.position.ReadValue(), Is.Not.EqualTo(default(Vector2)));

trace.Clear();

// Configuration change causes full re-resolve and schedules initial state check.
InputSystem.QueueConfigChangeEvent(touchscreen);
InputSystem.Update();
InputSystem.Update();

// Full re-resolve may cancel the current action state. What must NOT happen is a synthetic
// Started/Performed pair from persisted inactive touch state.
Assert.AreEqual(1, trace.count);
foreach (var eventPtr in trace)
{
// The trace should only contain a Canceled event for the action.
Assert.AreEqual(InputActionPhase.Canceled, eventPtr.phase,
$"inactive touch state should not produce action callbacks, but received {eventPtr.phase}.");
}
}
}

// https://fogbugz.unity3d.com/f/cases/1192972/
[Test]
[Category("Actions")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1321,6 +1321,9 @@ private void OnBeforeInitialUpdate()
if (IsActiveControl(bindingIndex, controlIndex))
continue;

if (ShouldSkipInitialStateCheck(control))
continue;

if (!control.CheckStateIsAtDefault())
{
// Update press times.
Expand Down Expand Up @@ -1348,6 +1351,24 @@ private void OnBeforeInitialUpdate()
k_InputInitialActionStateCheckMarker.End();
}

private static bool ShouldSkipInitialStateCheck(InputControl control)
{
// UUM-100125
// Touch controls intentionally preserve state such as position even when no touch is currently active.
// During binding re-resolution this can make inactive touches look actuated and cause invalid triggers.
if (control is TouchControl touchControl)
{
return !touchControl.isInProgress;
}

if (control.parent is TouchControl parentTouchControl)
{
return !parentTouchControl.isInProgress;
}

return false;
}

// Called from InputManager when one of our state change monitors has fired.
// Tells us the time of the change *according to the state events coming in*.
// Also tells us which control of the controls we are binding to triggered the
Expand Down
Loading