Skip to content

Commit 3e301f9

Browse files
authored
FIX: OnAnyButtonPress not recognizing touch anymore (#2401)
1 parent 4e169d9 commit 3e301f9

3 files changed

Lines changed: 91 additions & 2 deletions

File tree

Assets/Tests/InputSystem/CoreTests_Events.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,88 @@ public void Events_OnAnyButtonPressed_FiltersOutOtherControls()
219219
Assert.That(callCount, Is.EqualTo(1));
220220
}
221221

222+
[Test]
223+
[Category("Events")]
224+
public void Events_OnAnyButtonPressed_WorksWithTouchControls()
225+
{
226+
InputSystem.settings.defaultButtonPressPoint = 0.5f;
227+
228+
var touch = InputSystem.AddDevice<Touchscreen>();
229+
230+
var callCount = 0;
231+
232+
InputSystem.onAnyButtonPress
233+
.Call(ctrl =>
234+
{
235+
Assert.That(ctrl, Is.SameAs(touch.touches[0].press));
236+
++callCount;
237+
});
238+
239+
240+
Assert.That(callCount, Is.Zero);
241+
242+
InputSystem.Update();
243+
244+
SetTouch(0, TouchPhase.Began, new Vector2(12, 12));
245+
InputSystem.Update();
246+
Assert.That(callCount, Is.EqualTo(1));
247+
248+
// TouchPhase.Moved must not register as a new button press.
249+
SetTouch(0, TouchPhase.Moved, new Vector2(13, 12), new Vector2(1, 0));
250+
InputSystem.Update();
251+
Assert.That(callCount, Is.EqualTo(1));
252+
253+
// TouchPhase.Canceled must not register as a new button press.
254+
SetTouch(0, TouchPhase.Canceled, new Vector2(13, 12));
255+
InputSystem.Update();
256+
Assert.That(callCount, Is.EqualTo(1));
257+
}
258+
259+
[Test]
260+
[Category("Events")]
261+
public void Events_OnAnyButtonPressed_WorksWithMultitouchTouchControls()
262+
{
263+
InputSystem.settings.defaultButtonPressPoint = 0.5f;
264+
265+
var touch = InputSystem.AddDevice<Touchscreen>();
266+
267+
var callCount = 0;
268+
269+
InputSystem.onAnyButtonPress
270+
.Call(ctrl =>
271+
{
272+
++callCount;
273+
});
274+
275+
Assert.That(callCount, Is.Zero);
276+
277+
InputSystem.Update();
278+
279+
SetTouch(1, TouchPhase.Began, new Vector2(10, 10), screen: touch);
280+
InputSystem.Update();
281+
Assert.That(callCount, Is.EqualTo(1));
282+
283+
SetTouch(1, TouchPhase.Moved, new Vector2(11, 10), new Vector2(1, 0), screen: touch);
284+
InputSystem.Update();
285+
Assert.That(callCount, Is.EqualTo(1));
286+
287+
SetTouch(2, TouchPhase.Began, new Vector2(100, 100), screen: touch);
288+
InputSystem.Update();
289+
Assert.That(callCount, Is.EqualTo(2));
290+
291+
SetTouch(2, TouchPhase.Moved, new Vector2(101, 100), new Vector2(1, 0), screen: touch);
292+
InputSystem.Update();
293+
Assert.That(callCount, Is.EqualTo(2));
294+
295+
SetTouch(1, TouchPhase.Canceled, new Vector2(11, 10), screen: touch);
296+
InputSystem.Update();
297+
Assert.That(callCount, Is.EqualTo(2));
298+
299+
SetTouch(2, TouchPhase.Canceled, new Vector2(101, 100), screen: touch);
300+
InputSystem.Update();
301+
Assert.That(callCount, Is.EqualTo(2));
302+
}
303+
222304
[Test]
223305
[Category("Events")]
224306
public void Events_OnAnyButtonPressed_FiltersOutNonStateEvents()

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
2222
- 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)
2323
- 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)
2424
- 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).
25+
- Fixed InputSystem.onAnyButtonPress fails to trigger when the device receives a touch [UUM-137930](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-137930).
2526
- Fixed an incorrect ArraysHelper.HaveDuplicateReferences implementation that didn't use its arguments right [ISXB-1792] (https://github.com/Unity-Technologies/InputSystem/pull/2376)
2627

2728
### Changed

Packages/com.unity.inputsystem/InputSystem/Runtime/Controls/InputControlExtensions.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,7 +1104,7 @@ public static bool HasButtonPress(this InputEventPtr eventPtr, float magnitude =
11041104
/// in the devices state memory. For example, in the gamepad state, button north (bit position 4) will be evaluated before button
11051105
/// east (bit position 5), so if both buttons were pressed in the given event, button north would be returned.
11061106
/// Note that the function returns null if the <paramref name="eventPtr"/> is not a StateEvent or DeltaStateEvent.</remarks>
1107-
public static InputControl GetFirstButtonPressOrNull(this InputEventPtr eventPtr, float magnitude = -1, bool buttonControlsOnly = true)
1107+
public static unsafe InputControl GetFirstButtonPressOrNull(this InputEventPtr eventPtr, float magnitude = -1, bool buttonControlsOnly = true)
11081108
{
11091109
if (eventPtr.type != StateEvent.Type && eventPtr.type != DeltaStateEvent.Type)
11101110
return null;
@@ -1114,7 +1114,13 @@ public static InputControl GetFirstButtonPressOrNull(this InputEventPtr eventPtr
11141114

11151115
foreach (var control in eventPtr.EnumerateControls(Enumerate.IgnoreControlsInDefaultState, magnitudeThreshold: magnitude))
11161116
{
1117-
if (!control.HasValueChangeInEvent(eventPtr))
1117+
// Skip if the value didn't change. For IInputStateCallbackReceiver devices (e.g. Touchscreen),
1118+
// the event may not carry full device state, so fall back to checking the control was at
1119+
// default (not pressed) before this event.
1120+
var stateInEvent = control.GetStatePtrFromStateEvent(eventPtr);
1121+
var currentState = control.currentStatePtr;
1122+
if (stateInEvent != null ? !control.CompareValue(currentState, stateInEvent)
1123+
: control.CompareValue(currentState, control.defaultStatePtr))
11181124
continue;
11191125
if (buttonControlsOnly && !control.isButton)
11201126
continue;

0 commit comments

Comments
 (0)