From 47cfc0234a6f9d01d5359860441788e5bce25950 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Fri, 27 Mar 2026 17:15:56 +0100 Subject: [PATCH 1/6] Fix for onAnyButtonPress not recognizing touch anymore --- Assets/Tests/InputSystem/CoreTests_Events.cs | 28 +++++++++++++++++++ Packages/com.unity.inputsystem/CHANGELOG.md | 1 + .../Controls/InputControlExtensions.cs | 2 +- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/Assets/Tests/InputSystem/CoreTests_Events.cs b/Assets/Tests/InputSystem/CoreTests_Events.cs index 7960e6f934..17777610dc 100644 --- a/Assets/Tests/InputSystem/CoreTests_Events.cs +++ b/Assets/Tests/InputSystem/CoreTests_Events.cs @@ -218,6 +218,34 @@ public void Events_OnAnyButtonPressed_FiltersOutOtherControls() Assert.That(callCount, Is.EqualTo(1)); } + + [Test] + [Category("Events")] + public void Events_OnAnyButtonPressed_WorksWithTouchControls() + { + InputSystem.settings.defaultButtonPressPoint = 0.5f; + + var touch = InputSystem.AddDevice(); + + var callCount = 0; + + InputSystem.onAnyButtonPress + .Call(ctrl => + { + Assert.That(ctrl, Is.SameAs(touch.touches[0].press)); + ++callCount; + }); + + Assert.That(callCount, Is.Zero); + + InputSystem.Update(); + + SetTouch(0,TouchPhase.Began, new Vector2(12,12)); + + InputSystem.Update(); + + Assert.That(callCount, Is.EqualTo(1)); + } [Test] [Category("Events")] diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index 006097717b..d547999ca7 100644 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fixed `buttonSouth` returning the state of the east button (and so on for all the compass named buttons) when using a Nintendo Switch Pro Controller on iOS [ISXB-1632](issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1632) - Fixed `aButton` returning the state of the east button (and so on for all the letter named buttons) when using a Nintendo Switch Pro Controller on Standalone & iOS [ISXB-1632](issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1632) - Fixed an issue where `UIToolkit` `ClickEvent` could be fired on Android after device rotation due to inactive touch state being replayed during action initial state checks [UUM-100125](https://jira.unity3d.com/browse/UUM-100125). +- Fixed InputSystem.onAnyButtonPress fails to trigger when the device receives a touch [UUM-137930](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-137930). ### Changed diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/InputControlExtensions.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/InputControlExtensions.cs index 10eeb4386e..5da0b981da 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/InputControlExtensions.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/InputControlExtensions.cs @@ -1114,7 +1114,7 @@ public static InputControl GetFirstButtonPressOrNull(this InputEventPtr eventPtr foreach (var control in eventPtr.EnumerateControls(Enumerate.IgnoreControlsInDefaultState, magnitudeThreshold: magnitude)) { - if (!control.HasValueChangeInEvent(eventPtr)) + if (!control.HasValueChangeInEvent(eventPtr) && !(control.device is Touchscreen)) // touches can happen to not have a previous state to compare to after the touch started continue; if (buttonControlsOnly && !control.isButton) continue; From 6fa81000f371ea1cd83f66982273c330f2c868f8 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Thu, 9 Apr 2026 17:00:12 +0200 Subject: [PATCH 2/6] change to using the pointer for this and look if the pointer has a previous state and if that was the same --- .../InputSystem/Controls/InputControlExtensions.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/InputControlExtensions.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/InputControlExtensions.cs index 5da0b981da..006e4410e2 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/InputControlExtensions.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/InputControlExtensions.cs @@ -1104,7 +1104,7 @@ public static bool HasButtonPress(this InputEventPtr eventPtr, float magnitude = /// in the devices state memory. For example, in the gamepad state, button north (bit position 4) will be evaluated before button /// east (bit position 5), so if both buttons were pressed in the given event, button north would be returned. /// Note that the function returns null if the is not a StateEvent or DeltaStateEvent. - public static InputControl GetFirstButtonPressOrNull(this InputEventPtr eventPtr, float magnitude = -1, bool buttonControlsOnly = true) + public static unsafe InputControl GetFirstButtonPressOrNull(this InputEventPtr eventPtr, float magnitude = -1, bool buttonControlsOnly = true) { if (eventPtr.type != StateEvent.Type && eventPtr.type != DeltaStateEvent.Type) return null; @@ -1114,7 +1114,9 @@ public static InputControl GetFirstButtonPressOrNull(this InputEventPtr eventPtr foreach (var control in eventPtr.EnumerateControls(Enumerate.IgnoreControlsInDefaultState, magnitudeThreshold: magnitude)) { - if (!control.HasValueChangeInEvent(eventPtr) && !(control.device is Touchscreen)) // touches can happen to not have a previous state to compare to after the touch started + // Continue if the control did change in the event or did not have a previous state to compare to. + var stateInEvent = control.GetStatePtrFromStateEvent(eventPtr); + if (stateInEvent == null || !control.CompareValue(control.currentStatePtr, stateInEvent)) continue; if (buttonControlsOnly && !control.isButton) continue; From 2c7f3f7cfdaa87e3c30ad21200a46970b3d839ad Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Mon, 13 Apr 2026 19:08:45 +0200 Subject: [PATCH 3/6] Fix to check against default for StateCallback receiver devices like TouchScreen --- .../InputSystem/Controls/InputControlExtensions.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/InputControlExtensions.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/InputControlExtensions.cs index 006e4410e2..38282c06c1 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/InputControlExtensions.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/InputControlExtensions.cs @@ -1114,9 +1114,13 @@ public static unsafe InputControl GetFirstButtonPressOrNull(this InputEventPtr e foreach (var control in eventPtr.EnumerateControls(Enumerate.IgnoreControlsInDefaultState, magnitudeThreshold: magnitude)) { - // Continue if the control did change in the event or did not have a previous state to compare to. + // Skip if the value didn't change. For IInputStateCallbackReceiver devices (e.g. Touchscreen), + // the event may not carry full device state, so fall back to checking the control was at + // default (not pressed) before this event. var stateInEvent = control.GetStatePtrFromStateEvent(eventPtr); - if (stateInEvent == null || !control.CompareValue(control.currentStatePtr, stateInEvent)) + var currentState = control.currentStatePtr; + if (stateInEvent != null ? !control.CompareValue(currentState, stateInEvent) + : control.CompareValue(currentState, control.defaultStatePtr)) continue; if (buttonControlsOnly && !control.isButton) continue; From 0437ffd341f5b16470034cfe81236c398450cb9a Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Mon, 13 Apr 2026 19:21:33 +0200 Subject: [PATCH 4/6] format test file --- Assets/Tests/InputSystem/CoreTests_Events.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Assets/Tests/InputSystem/CoreTests_Events.cs b/Assets/Tests/InputSystem/CoreTests_Events.cs index 17777610dc..b7805b6c71 100644 --- a/Assets/Tests/InputSystem/CoreTests_Events.cs +++ b/Assets/Tests/InputSystem/CoreTests_Events.cs @@ -218,7 +218,7 @@ public void Events_OnAnyButtonPressed_FiltersOutOtherControls() Assert.That(callCount, Is.EqualTo(1)); } - + [Test] [Category("Events")] public void Events_OnAnyButtonPressed_WorksWithTouchControls() @@ -236,12 +236,13 @@ public void Events_OnAnyButtonPressed_WorksWithTouchControls() ++callCount; }); + Assert.That(callCount, Is.Zero); InputSystem.Update(); - SetTouch(0,TouchPhase.Began, new Vector2(12,12)); - + SetTouch(0, TouchPhase.Began, new Vector2(12, 12)); + InputSystem.Update(); Assert.That(callCount, Is.EqualTo(1)); From c24a32d3f85d8493ef08c1dc486a98c6f337d0e3 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Thu, 30 Apr 2026 11:03:57 +0200 Subject: [PATCH 5/6] rewrote test and added multi touch test --- Assets/Tests/InputSystem/CoreTests_Events.cs | 67 ++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/Assets/Tests/InputSystem/CoreTests_Events.cs b/Assets/Tests/InputSystem/CoreTests_Events.cs index b7805b6c71..047bbc1eb1 100644 --- a/Assets/Tests/InputSystem/CoreTests_Events.cs +++ b/Assets/Tests/InputSystem/CoreTests_Events.cs @@ -242,12 +242,79 @@ public void Events_OnAnyButtonPressed_WorksWithTouchControls() InputSystem.Update(); SetTouch(0, TouchPhase.Began, new Vector2(12, 12)); + InputSystem.Update(); + Assert.That(callCount, Is.EqualTo(1)); + // TouchPhase.Moved must not register as a new button press. + SetTouch(0, TouchPhase.Moved, new Vector2(13, 12), new Vector2(1, 0)); InputSystem.Update(); + Assert.That(callCount, Is.EqualTo(1)); + // TouchPhase.Canceled must not register as a new button press. + SetTouch(0, TouchPhase.Canceled, new Vector2(13, 12)); + InputSystem.Update(); Assert.That(callCount, Is.EqualTo(1)); } + [Test] + [Category("Events")] + public void Events_OnAnyButtonPressed_WorksWithMultitouchTouchControls() + { + InputSystem.settings.defaultButtonPressPoint = 0.5f; + + var touch = InputSystem.AddDevice(); + + var callCount = 0; + var firstPress = (ButtonControl)null; + var secondPress = (ButtonControl)null; + + InputSystem.onAnyButtonPress + .Call(ctrl => + { + Assert.That(ctrl.device, Is.SameAs(touch)); + if (callCount == 0) + firstPress = (ButtonControl)ctrl; + else if (callCount == 1) + secondPress = (ButtonControl)ctrl; + else + Assert.Fail($"Unexpected extra onAnyButtonPress ({ctrl})"); + ++callCount; + }); + + Assert.That(callCount, Is.Zero); + + InputSystem.Update(); + + const int touchId0 = 1; + const int touchId1 = 2; + + SetTouch(touchId0, TouchPhase.Began, new Vector2(10, 10), screen: touch); + InputSystem.Update(); + Assert.That(callCount, Is.EqualTo(1)); + Assert.That(firstPress, Is.SameAs(touch.touches[0].press)); + + SetTouch(touchId0, TouchPhase.Moved, new Vector2(11, 10), new Vector2(1, 0), screen: touch); + InputSystem.Update(); + Assert.That(callCount, Is.EqualTo(1)); + + SetTouch(touchId1, TouchPhase.Began, new Vector2(100, 100), screen: touch); + InputSystem.Update(); + Assert.That(callCount, Is.EqualTo(2)); + Assert.That(secondPress, Is.SameAs(touch.touches[1].press)); + + SetTouch(touchId1, TouchPhase.Moved, new Vector2(101, 100), new Vector2(1, 0), screen: touch); + InputSystem.Update(); + Assert.That(callCount, Is.EqualTo(2)); + + SetTouch(touchId0, TouchPhase.Canceled, new Vector2(11, 10), screen: touch); + InputSystem.Update(); + Assert.That(callCount, Is.EqualTo(2)); + + SetTouch(touchId1, TouchPhase.Canceled, new Vector2(101, 100), screen: touch); + InputSystem.Update(); + Assert.That(callCount, Is.EqualTo(2)); + } + [Test] [Category("Events")] public void Events_OnAnyButtonPressed_FiltersOutNonStateEvents() From 3a6dfb4d9e8675f92091eabb7cdc13cc629898fc Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Thu, 30 Apr 2026 11:21:47 +0200 Subject: [PATCH 6/6] clean up tests --- Assets/Tests/InputSystem/CoreTests_Events.cs | 26 +++++--------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/Assets/Tests/InputSystem/CoreTests_Events.cs b/Assets/Tests/InputSystem/CoreTests_Events.cs index 047bbc1eb1..e3a22fd97d 100644 --- a/Assets/Tests/InputSystem/CoreTests_Events.cs +++ b/Assets/Tests/InputSystem/CoreTests_Events.cs @@ -265,19 +265,10 @@ public void Events_OnAnyButtonPressed_WorksWithMultitouchTouchControls() var touch = InputSystem.AddDevice(); var callCount = 0; - var firstPress = (ButtonControl)null; - var secondPress = (ButtonControl)null; InputSystem.onAnyButtonPress .Call(ctrl => { - Assert.That(ctrl.device, Is.SameAs(touch)); - if (callCount == 0) - firstPress = (ButtonControl)ctrl; - else if (callCount == 1) - secondPress = (ButtonControl)ctrl; - else - Assert.Fail($"Unexpected extra onAnyButtonPress ({ctrl})"); ++callCount; }); @@ -285,32 +276,27 @@ public void Events_OnAnyButtonPressed_WorksWithMultitouchTouchControls() InputSystem.Update(); - const int touchId0 = 1; - const int touchId1 = 2; - - SetTouch(touchId0, TouchPhase.Began, new Vector2(10, 10), screen: touch); + SetTouch(1, TouchPhase.Began, new Vector2(10, 10), screen: touch); InputSystem.Update(); Assert.That(callCount, Is.EqualTo(1)); - Assert.That(firstPress, Is.SameAs(touch.touches[0].press)); - SetTouch(touchId0, TouchPhase.Moved, new Vector2(11, 10), new Vector2(1, 0), screen: touch); + SetTouch(1, TouchPhase.Moved, new Vector2(11, 10), new Vector2(1, 0), screen: touch); InputSystem.Update(); Assert.That(callCount, Is.EqualTo(1)); - SetTouch(touchId1, TouchPhase.Began, new Vector2(100, 100), screen: touch); + SetTouch(2, TouchPhase.Began, new Vector2(100, 100), screen: touch); InputSystem.Update(); Assert.That(callCount, Is.EqualTo(2)); - Assert.That(secondPress, Is.SameAs(touch.touches[1].press)); - SetTouch(touchId1, TouchPhase.Moved, new Vector2(101, 100), new Vector2(1, 0), screen: touch); + SetTouch(2, TouchPhase.Moved, new Vector2(101, 100), new Vector2(1, 0), screen: touch); InputSystem.Update(); Assert.That(callCount, Is.EqualTo(2)); - SetTouch(touchId0, TouchPhase.Canceled, new Vector2(11, 10), screen: touch); + SetTouch(1, TouchPhase.Canceled, new Vector2(11, 10), screen: touch); InputSystem.Update(); Assert.That(callCount, Is.EqualTo(2)); - SetTouch(touchId1, TouchPhase.Canceled, new Vector2(101, 100), screen: touch); + SetTouch(2, TouchPhase.Canceled, new Vector2(101, 100), screen: touch); InputSystem.Update(); Assert.That(callCount, Is.EqualTo(2)); }