diff --git a/Assets/Tests/InputSystem/CoreTests_Actions.cs b/Assets/Tests/InputSystem/CoreTests_Actions.cs index 5c002d3ed7..07f6dabe4b 100644 --- a/Assets/Tests/InputSystem/CoreTests_Actions.cs +++ b/Assets/Tests/InputSystem/CoreTests_Actions.cs @@ -3644,6 +3644,32 @@ public void Actions_CanAddBindingsToActions_ToExistingComposite() .Property("path").EqualTo("/rightArrow")); } + [Test] + [Category("Actions")] + public void Actions_CanRemovePartBindings_ButNotExistingComposite() + { + var keyboard = InputSystem.AddDevice(); + + var action = new InputAction(); + action.AddCompositeBinding("Axis") + .With("Negative", "/a") + .With("Positive", "/d"); + action.ChangeCompositeBinding("Axis").Erase(onlyRemoveCompositeParts: true); + + Assert.That(action.bindings, Has.Count.EqualTo(1)); + Assert.That(action.controls, Has.Count.EqualTo(0)); + + try + { + action.AddBinding("/a"); + action.ChangeBinding(1).Erase(onlyRemoveCompositeParts: true); + } + catch (InvalidOperationException ex) + { + Assert.That(ex.Message, Is.EqualTo("Binding should be a composite binding")); + } + } + [Serializable] public enum Modification { diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index 36548dfd48..e9028ad97c 100644 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -14,6 +14,10 @@ however, it has to be formatted properly to pass verification tests. - Fixed unclosed profiler marker in `InvokeCallbacksSafe_AnyCallbackReturnsTrue` which would lead to eventually broken profiler traces in some cases like using `PlayerInput` (case ISXB-393). +### Added + +- Added `Erase(onlyRemoveCompositeParts: true)` to be able to remove only binding parts of the composite binding but not the composite binding itself. Based on the user contribution from [steinbitglis](https://github.com/steinbitglis) in [#1360](https://github.com/Unity-Technologies/InputSystem/pull/1360). + ## [1.5.0] - 2023-01-24 ### Added diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs index 48e3df3454..2f3cd13d0f 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs @@ -1564,19 +1564,26 @@ private BindingSyntax IteratePartBinding(bool next, string partName) /// that got erased was the last one in the array). /// /// The instance is not . - public void Erase() + public void Erase(bool onlyRemoveCompositeParts = false) { if (!valid) throw new InvalidOperationException("Instance not valid"); var isComposite = m_ActionMap.m_Bindings[m_BindingIndexInMap].isComposite; - ArrayHelpers.EraseAt(ref m_ActionMap.m_Bindings, m_BindingIndexInMap); + if (onlyRemoveCompositeParts && !isComposite) + throw new InvalidOperationException("Binding should be a composite binding"); + + var index = m_BindingIndexInMap; + if (!onlyRemoveCompositeParts) + ArrayHelpers.EraseAt(ref m_ActionMap.m_Bindings, index); + else + index++; // If it's a composite, also erase part bindings. if (isComposite) { - while (m_BindingIndexInMap < m_ActionMap.m_Bindings.LengthSafe() && m_ActionMap.m_Bindings[m_BindingIndexInMap].isPartOfComposite) - ArrayHelpers.EraseAt(ref m_ActionMap.m_Bindings, m_BindingIndexInMap); + while (index < m_ActionMap.m_Bindings.LengthSafe() && m_ActionMap.m_Bindings[index].isPartOfComposite) + ArrayHelpers.EraseAt(ref m_ActionMap.m_Bindings, index); } m_ActionMap.OnBindingModified();