Skip to content

Commit bbd15b2

Browse files
authored
FIX: Composite bindings with the default interaction will now correct… (#753)
1 parent 83bca71 commit bbd15b2

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

Assets/Tests/InputSystem/CoreTests_Actions.cs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4813,6 +4813,82 @@ public void Actions_CanCreateCompositesWithMultipleBindings()
48134813
Assert.That(value, Is.EqualTo(new Vector2(-1, -1).normalized).Using(Vector2EqualityComparer.Instance));
48144814
}
48154815

4816+
[Test]
4817+
[Category("Actions")]
4818+
public void Actions_WithMultipleCompositesCancelsIfCompositeIsReleased()
4819+
{
4820+
var keyboard = InputSystem.AddDevice<Keyboard>();
4821+
var gamepad = InputSystem.AddDevice<Gamepad>();
4822+
4823+
InputSystem.RegisterInteraction<LogInteraction>();
4824+
4825+
var action = new InputAction();
4826+
action.AddCompositeBinding("Dpad(normalize=0)")
4827+
.With("Up", "<Keyboard>/w")
4828+
.With("Down", "<Keyboard>/s")
4829+
.With("Left", "<Keyboard>/a")
4830+
.With("Right", "<Keyboard>/d");
4831+
action.AddCompositeBinding("Dpad")
4832+
.With("Up", "<Keyboard>/upArrow")
4833+
.With("Down", "<Keyboard>/downArrow")
4834+
.With("Left", "<Keyboard>/leftArrow")
4835+
.With("Right", "<Keyboard>/rightArrow");
4836+
action.Enable();
4837+
4838+
InputControl performedControl = null;
4839+
InputControl canceledControl = null;
4840+
var value = Vector2.zero;
4841+
action.performed += ctx =>
4842+
{
4843+
performedControl = ctx.control;
4844+
value = ctx.ReadValue<Vector2>();
4845+
};
4846+
action.canceled += ctx =>
4847+
{
4848+
canceledControl = ctx.control;
4849+
value = ctx.ReadValue<Vector2>();
4850+
};
4851+
4852+
InputSystem.QueueStateEvent(keyboard, new KeyboardState(Key.A));
4853+
InputSystem.Update();
4854+
4855+
Assert.That(canceledControl, Is.Null);
4856+
Assert.That(performedControl, Is.EqualTo(keyboard.aKey));
4857+
Assert.That(value, Is.EqualTo(Vector2.left));
4858+
performedControl = null;
4859+
4860+
InputSystem.QueueStateEvent(keyboard, new KeyboardState(Key.A, Key.W));
4861+
InputSystem.Update();
4862+
4863+
Assert.That(canceledControl, Is.Null);
4864+
Assert.That(performedControl, Is.EqualTo(keyboard.wKey));
4865+
Assert.That(value, Is.EqualTo(Vector2.up + Vector2.left));
4866+
performedControl = null;
4867+
4868+
InputSystem.QueueStateEvent(keyboard, new KeyboardState(Key.W));
4869+
InputSystem.Update();
4870+
4871+
Assert.That(canceledControl, Is.Null);
4872+
Assert.That(performedControl, Is.EqualTo(keyboard.aKey));
4873+
Assert.That(value, Is.EqualTo(Vector2.up));
4874+
performedControl = null;
4875+
4876+
InputSystem.QueueStateEvent(keyboard, new KeyboardState(Key.RightArrow));
4877+
InputSystem.Update();
4878+
4879+
Assert.That(canceledControl, Is.EqualTo(keyboard.wKey));
4880+
Assert.That(performedControl, Is.EqualTo(keyboard.rightArrowKey));
4881+
Assert.That(value, Is.EqualTo(Vector2.right));
4882+
performedControl = null;
4883+
4884+
InputSystem.QueueStateEvent(keyboard, new KeyboardState());
4885+
InputSystem.Update();
4886+
4887+
Assert.That(canceledControl, Is.EqualTo(keyboard.rightArrowKey));
4888+
Assert.That(performedControl, Is.Null);
4889+
Assert.That(value, Is.EqualTo(Vector2.zero));
4890+
}
4891+
48164892
[Test]
48174893
[Category("Actions")]
48184894
public void Actions_CompositesReportControlThatTriggeredTheCompositeInCallback()

Packages/com.unity.inputsystem/CHANGELOG.md

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

2424
- Fixed actions not updating their set of controls when the usages of a device are changed.
25+
- Composite bindings with the default interaction will now correctly cancel when the composite is released, even if there are multiple composite bindings on the action.
2526

2627
### Changed
2728

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,13 @@ private bool ShouldIgnoreControlStateChange(ref TriggerState trigger, int action
10411041
return false;
10421042
}
10431043

1044+
var actionStateControlIndex = actionState->controlIndex;
1045+
if (bindingStates[actionState->bindingIndex].isPartOfComposite)
1046+
{
1047+
var compositeBindingIndex = bindingStates[actionState->bindingIndex].compositeOrCompositeBindingIndex;
1048+
actionStateControlIndex = bindingStates[compositeBindingIndex].controlStartIndex;
1049+
}
1050+
10441051
// If the control is actuated *less* then the current level of actuation we
10451052
// recorded for the action *and* the control that changed is the one that is currently
10461053
// driving the action, we have to check whether there is another actuation
@@ -1049,7 +1056,7 @@ private bool ShouldIgnoreControlStateChange(ref TriggerState trigger, int action
10491056
{
10501057
// If we're not currently driving the action, it's simple. Doesn't matter that we lowered
10511058
// actuation as we didn't have the highest actuation anyway.
1052-
if (triggerControlIndex != actionState->controlIndex)
1059+
if (triggerControlIndex != actionStateControlIndex)
10531060
{
10541061
Profiler.EndSample();
10551062
////REVIEW: should we *count* actuations instead? (problem is that then we have to reliably determine when a control
@@ -1164,6 +1171,10 @@ private bool ShouldIgnoreControlStateChange(ref TriggerState trigger, int action
11641171
// before we let it drive the action.
11651172
if (Mathf.Approximately(trigger.magnitude, actionState->magnitude))
11661173
{
1174+
// However, if we have changed the control to a different control on the same composite, we *should* let
1175+
// it drive the action - this is like a direction change on the same control.
1176+
if (bindingStates[trigger.bindingIndex].isPartOfComposite && triggerControlIndex == actionStateControlIndex)
1177+
return false;
11671178
if (trigger.magnitude > 0 && triggerControlIndex != actionState->controlIndex)
11681179
actionState->hasMultipleConcurrentActuations = true;
11691180
return true;

0 commit comments

Comments
 (0)