diff --git a/Assets/Tests/InputSystem/CoreTests_Actions.cs b/Assets/Tests/InputSystem/CoreTests_Actions.cs index 9f266e9e81..d0c8802462 100644 --- a/Assets/Tests/InputSystem/CoreTests_Actions.cs +++ b/Assets/Tests/InputSystem/CoreTests_Actions.cs @@ -9245,6 +9245,53 @@ public void Actions_WhenGettingDisplayTextForBindingsOnAction_CompositesAreForma Assert.That(action.GetBindingDisplayString(8), Is.EqualTo("Left Shift|Right Shift+A")); } + // https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-141423 + [Test] + [Category("Actions")] + public void Actions_WhenGettingDisplayTextForBindingsOnAction_CompositeIsIncludedWhenAtLeastOnePartMatchesBindingMask() + { + var action = new InputAction(); + + action.AddCompositeBinding("1DAxis") + .With("Negative", "/a", groups: "Keyboard") + .With("Positive", "/d", groups: "Keyboard"); + + Assert.That(action.GetBindingDisplayString(InputBinding.MaskByGroup("Keyboard")), + Is.EqualTo("A/D")); + } + + // https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-141423 + [Test] + [Category("Actions")] + public void Actions_WhenGettingDisplayTextForBindingsOnAction_MixedGroupCompositeIsRenderedAtomicallyWhenAnyPartMatchesBindingMask() + { + var action = new InputAction(); + + action.AddCompositeBinding("1DAxis") + .With("Negative", "/a", groups: "Keyboard") + .With("Positive", "/leftButton", groups: "Mouse"); + + Assert.That(action.GetBindingDisplayString(InputBinding.MaskByGroup("Keyboard")), + Is.EqualTo("A/LMB")); + Assert.That(action.GetBindingDisplayString(InputBinding.MaskByGroup("Mouse")), + Is.EqualTo("A/LMB")); + } + + // https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-141423 + [Test] + [Category("Actions")] + public void Actions_WhenGettingDisplayTextForCompositeWithNoMatchingGroups_IsExcluded() + { + var action = new InputAction(); + + action.AddCompositeBinding("1DAxis") + .With("Negative", "/a", groups: "Keyboard") + .With("Positive", "/d", groups: "Keyboard"); + + Assert.That(action.GetBindingDisplayString(InputBinding.MaskByGroup("Gamepad")), + Is.Empty); + } + // https://fogbugz.unity3d.com/f/cases/1321175/ [Test] [Category("Actions")] diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index cbed429754..02a6867477 100644 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed +- Fixed `InputActionRebindingExtensions.GetBindingDisplayString(InputAction, InputBinding, ...)` returning an empty string for composite bindings when the binding mask filters by group [UUM-141423](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-141423) - Fixed `InputEventPtr.handled` not preventing actions from triggering when switching devices. The default event handled policy has been changed from `SuppressStateUpdates` (now deprecated) to `SuppressActionEventNotifications`, which keeps device state synchronized while suppressing action callbacks for handled events. [ISXB-1097](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1097) - Fixed all `InputAction.WasXxxThisFrame()` and `WasXxxThisDynamicUpdate()` polling APIs to use per-action suppression tracking instead of a map-wide flag. Previously, when multiple events arrived in the same frame with mixed handled/unhandled states, the last event's suppression state could incorrectly affect all actions in the map. [ISXB-1097](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1097) - Fixed `InputRecorder` playback not starting when the Game View is not focused in the Editor [ISXB-1319](https://jira.unity3d.com/browse/ISXB-1319) diff --git a/Packages/com.unity.inputsystem/InputSystem/Runtime/Actions/InputActionRebindingExtensions.cs b/Packages/com.unity.inputsystem/InputSystem/Runtime/Actions/InputActionRebindingExtensions.cs index b8342ecb81..975a7d6213 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Runtime/Actions/InputActionRebindingExtensions.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Runtime/Actions/InputActionRebindingExtensions.cs @@ -321,7 +321,25 @@ public static string GetBindingDisplayString(this InputAction action, InputBindi if (bindings[i].isPartOfComposite) continue; if (!bindingMask.Matches(bindings[i])) - continue; + { + // Composites are filtered atomically: any matching part promotes the whole + // composite, consistent with how the index-based GetBindingDisplayString + // overload below treats composites as one display unit; per-part filtering + // would require a separate API. + if (!bindings[i].isComposite) + continue; + var anyPartMatches = false; + for (var partIndex = i + 1; partIndex < bindings.Count && bindings[partIndex].isPartOfComposite; ++partIndex) + { + if (bindingMask.Matches(bindings[partIndex])) + { + anyPartMatches = true; + break; + } + } + if (!anyPartMatches) + continue; + } ////REVIEW: should this filter out bindings that are not resolving to any controls?