Skip to content

Commit 43efc3b

Browse files
authored
FIX: ISXB-1127 composite incorrectly returning IsPressed (#2035)
* Revert "FIX: Composite binding isn't triggered after ResetDevice() called during Action handler (ISXB-746) (#1893)" This reverts commit 0ddd534.
1 parent c52fff9 commit 43efc3b

File tree

3 files changed

+24
-134
lines changed

3 files changed

+24
-134
lines changed

Assets/Tests/InputSystem/CoreTests_Actions.cs

Lines changed: 0 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -12405,99 +12405,4 @@ public void Actions_ActionMapDisabledDuringOnAfterSerialization()
1240512405
Assert.That(map.enabled, Is.True);
1240612406
Assert.That(map.FindAction("MyAction", true).enabled, Is.True);
1240712407
}
12408-
12409-
// ResetDevice wasn't properly clearly Composite key state, i.e. BindingState.pressTime
12410-
// https://jira.unity3d.com/browse/ISXB-746
12411-
[Test]
12412-
[TestCase(false)]
12413-
[TestCase(true)]
12414-
[Category("Actions")]
12415-
public void Actions_CompositeBindingResetWhenResetDeviceCalledWhileExecutingAction(bool useTwoModifierComposite)
12416-
{
12417-
var keyboard = InputSystem.AddDevice<Keyboard>();
12418-
bool actionPerformed;
12419-
12420-
// Enables "Modifier must be pressed first" behavior on all Composite Bindings
12421-
InputSystem.settings.shortcutKeysConsumeInput = true;
12422-
12423-
const string modifier1 = "<Keyboard>/shift";
12424-
const string modifier2 = "<Keyboard>/ctrl";
12425-
const string key = "<Keyboard>/F1";
12426-
12427-
var map = new InputActionMap();
12428-
var resetAction = map.AddAction("resetAction");
12429-
12430-
if (!useTwoModifierComposite)
12431-
{
12432-
resetAction.AddCompositeBinding("OneModifier")
12433-
.With("Modifier", modifier1)
12434-
.With("Binding", key);
12435-
}
12436-
else
12437-
{
12438-
resetAction.AddCompositeBinding("TwoModifiers")
12439-
.With("Modifier1", modifier1)
12440-
.With("Modifier2", modifier2)
12441-
.With("Binding", key);
12442-
}
12443-
12444-
resetAction.performed += (InputAction.CallbackContext ctx) =>
12445-
{
12446-
// Disable the Keyboard while action is being performed.
12447-
// This simulates an "OnFocusLost" event occurring while processing the Action, e.g. when switching primary displays or moving the main window
12448-
actionPerformed = true;
12449-
InputSystem.s_Manager.EnableOrDisableDevice(keyboard.device, false, InputManager.DeviceDisableScope.TemporaryWhilePlayerIsInBackground);
12450-
};
12451-
12452-
map.Enable();
12453-
12454-
actionPerformed = false;
12455-
Press(keyboard.leftShiftKey);
12456-
Press(keyboard.leftCtrlKey);
12457-
Press(keyboard.f1Key);
12458-
12459-
Assert.IsTrue(actionPerformed);
12460-
12461-
// Re enable the Keyboard (before keys are released) and execute Action again
12462-
InputSystem.s_Manager.EnableOrDisableDevice(keyboard.device, true, InputManager.DeviceDisableScope.TemporaryWhilePlayerIsInBackground);
12463-
12464-
actionPerformed = false;
12465-
Release(keyboard.leftShiftKey);
12466-
Release(keyboard.leftCtrlKey);
12467-
Release(keyboard.f1Key);
12468-
12469-
Press(keyboard.leftCtrlKey);
12470-
Press(keyboard.leftShiftKey);
12471-
Press(keyboard.f1Key);
12472-
12473-
Assert.IsTrue(actionPerformed);
12474-
12475-
actionPerformed = false;
12476-
Release(keyboard.leftCtrlKey);
12477-
Release(keyboard.leftShiftKey);
12478-
Release(keyboard.f1Key);
12479-
12480-
// Re enable the Keyboard (after keys are released) and execute Action one more time
12481-
InputSystem.s_Manager.EnableOrDisableDevice(keyboard.device, true, InputManager.DeviceDisableScope.TemporaryWhilePlayerIsInBackground);
12482-
12483-
Press(keyboard.leftCtrlKey);
12484-
Press(keyboard.leftShiftKey);
12485-
Press(keyboard.f1Key);
12486-
12487-
Assert.IsTrue(actionPerformed);
12488-
12489-
actionPerformed = false;
12490-
Press(keyboard.leftShiftKey);
12491-
Press(keyboard.leftCtrlKey);
12492-
Press(keyboard.f1Key);
12493-
12494-
// Re enable the Keyboard (before keys are released) and verify Action isn't triggered when Key pressed first
12495-
InputSystem.s_Manager.EnableOrDisableDevice(keyboard.device, true, InputManager.DeviceDisableScope.TemporaryWhilePlayerIsInBackground);
12496-
12497-
Press(keyboard.f1Key);
12498-
Press(keyboard.leftCtrlKey);
12499-
Press(keyboard.leftShiftKey);
12500-
12501-
Assert.IsFalse(actionPerformed);
12502-
}
1250312408
}

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ however, it has to be formatted properly to pass verification tests.
1212

1313
### Fixed
1414
- Fixed an issue causing the Action context menu to not show on right click when right clicking an action in the Input Action Editor [ISXB-1134](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1134).
15+
- Reverted changes from 0ddd534d8 (ISXB-746) which introduced a regression [ISXB-1127](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1127).
1516
- Fixed `ArgumentNullException: Value cannot be null.` during the migration of Project-wide Input Actions from `InputManager.asset` to `InputSystem_Actions.inputactions` asset which lead do the lost of the configuration [ISXB-1105](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1105)
1617
- Fixed pointerId staying the same when simultaneously releasing and then pressing in the same frame on mobile using touch. [ISXB-1006](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-845)
1718

Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,43 +1476,37 @@ private void ProcessControlStateChange(int mapIndex, int controlIndex, int bindi
14761476
// If the binding is part of a composite, check for interactions on the composite
14771477
// itself and give them a first shot at processing the value change.
14781478
var haveInteractionsOnComposite = false;
1479-
var compositeAlreadyTriggered = false;
14801479
if (bindingStatePtr->isPartOfComposite)
14811480
{
14821481
var compositeBindingIndex = bindingStatePtr->compositeOrCompositeBindingIndex;
14831482
var compositeBindingPtr = &bindingStates[compositeBindingIndex];
14841483

1485-
// If the composite has already been triggered from the very same event set a flag so it isn't triggered again.
1484+
// If the composite has already been triggered from the very same event, ignore it.
14861485
// Example: KeyboardState change that includes both A and W key state changes and we're looking
14871486
// at a WASD composite binding. There's a state change monitor on both the A and the W
14881487
// key and thus the manager will notify us individually of both changes. However, we
14891488
// want to perform the action only once.
1490-
// NOTE: Do NOT ignore this Event, we still need finish processing the individual button states.
1491-
if (!ShouldIgnoreInputOnCompositeBinding(compositeBindingPtr, eventPtr))
1492-
{
1493-
// Update magnitude for composite.
1494-
var compositeIndex = bindingStates[compositeBindingIndex].compositeOrCompositeBindingIndex;
1495-
var compositeContext = new InputBindingCompositeContext
1496-
{
1497-
m_State = this,
1498-
m_BindingIndex = compositeBindingIndex
1499-
};
1500-
trigger.magnitude = composites[compositeIndex].EvaluateMagnitude(ref compositeContext);
1501-
memory.compositeMagnitudes[compositeIndex] = trigger.magnitude;
1489+
if (ShouldIgnoreInputOnCompositeBinding(compositeBindingPtr, eventPtr))
1490+
return;
15021491

1503-
// Run through interactions on composite.
1504-
var interactionCountOnComposite = compositeBindingPtr->interactionCount;
1505-
if (interactionCountOnComposite > 0)
1506-
{
1507-
haveInteractionsOnComposite = true;
1508-
ProcessInteractions(ref trigger,
1509-
compositeBindingPtr->interactionStartIndex,
1510-
interactionCountOnComposite);
1511-
}
1512-
}
1513-
else
1492+
// Update magnitude for composite.
1493+
var compositeIndex = bindingStates[compositeBindingIndex].compositeOrCompositeBindingIndex;
1494+
var compositeContext = new InputBindingCompositeContext
1495+
{
1496+
m_State = this,
1497+
m_BindingIndex = compositeBindingIndex
1498+
};
1499+
trigger.magnitude = composites[compositeIndex].EvaluateMagnitude(ref compositeContext);
1500+
memory.compositeMagnitudes[compositeIndex] = trigger.magnitude;
1501+
1502+
// Run through interactions on composite.
1503+
var interactionCountOnComposite = compositeBindingPtr->interactionCount;
1504+
if (interactionCountOnComposite > 0)
15141505
{
1515-
compositeAlreadyTriggered = true;
1506+
haveInteractionsOnComposite = true;
1507+
ProcessInteractions(ref trigger,
1508+
compositeBindingPtr->interactionStartIndex,
1509+
interactionCountOnComposite);
15161510
}
15171511
}
15181512

@@ -1521,31 +1515,21 @@ private void ProcessControlStateChange(int mapIndex, int controlIndex, int bindi
15211515
// one of higher magnitude) or may even lead us to switch to processing a different binding
15221516
// (e.g. when an input of previously greater magnitude has now fallen below the level of another
15231517
// ongoing input with now higher magnitude).
1524-
//
1525-
// If Composite has already been triggered, skip this step; it's unnecessary and could also
1526-
// cause a processing issue if we switch to another binding.
1527-
var isConflictingInput = false;
1528-
if (!compositeAlreadyTriggered)
1529-
{
1530-
isConflictingInput = IsConflictingInput(ref trigger, actionIndex);
1531-
bindingStatePtr = &bindingStates[trigger.bindingIndex]; // IsConflictingInput may switch us to a different binding.
1532-
}
1518+
var isConflictingInput = IsConflictingInput(ref trigger, actionIndex);
1519+
bindingStatePtr = &bindingStates[trigger.bindingIndex]; // IsConflictingInput may switch us to a different binding.
15331520

15341521
// Process button presses/releases.
1535-
// We MUST execute this processing even if Composite has already been triggered to ensure button states
1536-
// are properly updated (ISXB-746)
15371522
if (!isConflictingInput)
15381523
ProcessButtonState(ref trigger, actionIndex, bindingStatePtr);
15391524

15401525
// If we have interactions, let them do all the processing. The presence of an interaction
15411526
// essentially bypasses the default phase progression logic of an action.
1542-
// Interactions are skipped if compositeAlreadyTriggered is set.
15431527
var interactionCount = bindingStatePtr->interactionCount;
15441528
if (interactionCount > 0 && !bindingStatePtr->isPartOfComposite)
15451529
{
15461530
ProcessInteractions(ref trigger, bindingStatePtr->interactionStartIndex, interactionCount);
15471531
}
1548-
else if (!haveInteractionsOnComposite && !isConflictingInput && !compositeAlreadyTriggered)
1532+
else if (!haveInteractionsOnComposite && !isConflictingInput)
15491533
{
15501534
ProcessDefaultInteraction(ref trigger, actionIndex);
15511535
}

0 commit comments

Comments
 (0)