Skip to content

Commit 81958b2

Browse files
FIX: Renaming a control scheme doesn't correct the bindings to come with it (ISX-1567) (#1740)
* Rename bindings control scheme's when control scheme is renamed Also refactors this renaming into a helper method. * Select the updated control scheme or the new one saved This fixes one failing test for the Editor
1 parent 1fdfa3c commit 81958b2

1 file changed

Lines changed: 38 additions & 4 deletions

File tree

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/ControlSchemeCommands.cs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System;
33
using System.Collections.Generic;
44
using System.Linq;
5+
using UnityEditor;
56
using UnityEngine.InputSystem.Utilities;
67

78
namespace UnityEngine.InputSystem.Editor
@@ -32,7 +33,7 @@ public static Command RemoveDeviceRequirement(int selectedDeviceIndex)
3233
};
3334
}
3435

35-
public static Command SaveControlScheme(string newName = "", bool updateExisting = false)
36+
public static Command SaveControlScheme(string newControlSchemeName = "", bool updateExisting = false)
3637
{
3738
return (in InputActionsEditorState state) =>
3839
{
@@ -42,7 +43,9 @@ public static Command SaveControlScheme(string newName = "", bool updateExisting
4243
var controlScheme = controlSchemesArray
4344
.FirstOrDefault(sp => sp.FindPropertyRelative(nameof(InputControlScheme.m_Name)).stringValue == controlSchemeName);
4445

45-
// if the control scheme is null, we're saving a new control scheme, otherwise editing an existing one
46+
var actionMaps = state.serializedObject.FindProperty(nameof(InputActionAsset.m_ActionMaps));
47+
48+
// If the control scheme is null, we're saving a new control scheme, otherwise editing an existing one
4649
if (controlScheme == null && updateExisting)
4750
throw new InvalidOperationException("Tried to update a non-existent control scheme.");
4851

@@ -52,8 +55,15 @@ public static Command SaveControlScheme(string newName = "", bool updateExisting
5255
controlSchemesArray.InsertArrayElementAtIndex(controlSchemesArray.arraySize);
5356
controlScheme = controlSchemesArray.GetArrayElementAtIndex(controlSchemesArray.arraySize - 1);
5457
}
58+
// If we're renaming a control scheme, we need to update the bindings that use it and make a unique name
59+
if (!string.IsNullOrEmpty(newControlSchemeName))
60+
{
61+
newControlSchemeName = MakeUniqueControlSchemeName(state, newControlSchemeName);
62+
RenameBindingsControlSchemeHelper(controlScheme, actionMaps, controlSchemeName, newControlSchemeName);
63+
}
5564

56-
controlScheme.FindPropertyRelative(nameof(InputControlScheme.m_Name)).stringValue = string.IsNullOrEmpty(newName) ? controlSchemeName : newName;
65+
controlScheme.FindPropertyRelative(nameof(InputControlScheme.m_Name)).stringValue = string.IsNullOrEmpty(newControlSchemeName) ? controlSchemeName : newControlSchemeName;
66+
controlScheme.FindPropertyRelative(nameof(InputControlScheme.m_BindingGroup)).stringValue = string.IsNullOrEmpty(newControlSchemeName) ? controlSchemeName : newControlSchemeName;
5767

5868
var serializedDeviceRequirements = controlScheme.FindPropertyRelative(nameof(InputControlScheme.m_DeviceRequirements));
5969
serializedDeviceRequirements.ClearArray();
@@ -71,10 +81,34 @@ public static Command SaveControlScheme(string newName = "", bool updateExisting
7181
}
7282

7383
state.serializedObject.ApplyModifiedProperties();
74-
return state.With(selectedControlScheme: new InputControlScheme(controlScheme));
84+
return state.With(
85+
selectedControlScheme: new InputControlScheme(controlScheme),
86+
// Select the control scheme updated, otherwise select the new one it was added
87+
selectedControlSchemeIndex: updateExisting? state.selectedControlSchemeIndex: controlSchemesArray.arraySize - 1);
7588
};
7689
}
7790

91+
static void RenameBindingsControlSchemeHelper(SerializedProperty controlScheme, SerializedProperty actionMaps, string controlSchemeName, string newName)
92+
{
93+
foreach (SerializedProperty actionMap in actionMaps)
94+
{
95+
var bindings = actionMap
96+
.FindPropertyRelative(nameof(InputActionMap.m_Bindings))
97+
.Select(sp => new SerializedInputBinding(sp))
98+
.ToList();
99+
100+
var bindingsToRename = bindings.Where(b => b.controlSchemes.Contains(controlSchemeName)).ToList();
101+
102+
foreach (var binding in bindingsToRename)
103+
{
104+
var bindingGroups = binding.controlSchemes.ToList();
105+
bindingGroups.Remove(controlSchemeName);
106+
bindingGroups.Add(newName);
107+
binding.wrappedProperty.FindPropertyRelative(nameof(InputBinding.m_Groups)).stringValue = bindingGroups.Join(InputBinding.kSeparatorString);
108+
}
109+
}
110+
}
111+
78112
public static Command SelectControlScheme(int controlSchemeIndex)
79113
{
80114
return (in InputActionsEditorState state) =>

0 commit comments

Comments
 (0)