Skip to content

Commit 9427975

Browse files
AswinRajGopalekcohLeoUnityPauliusd01
authored
FIX: ISXB-1674 - Input actions asset not converted correctly when upgrading from 1.14.1 (Regression) (#2244)
Co-authored-by: Håkan Sidenvall <hakan.sidenvall@unity3d.com> Co-authored-by: Leonardo Carneiro <leonardo@unity3d.com> Co-authored-by: Paulius Dervinis <54306142+Pauliusd01@users.noreply.github.com>
1 parent 85b57c7 commit 9427975

File tree

5 files changed

+122
-38
lines changed

5 files changed

+122
-38
lines changed

Assets/Tests/InputSystem.Editor/CustomProcessorEnumTest.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using UnityEngine;
99
using UnityEngine.InputSystem;
1010
using UnityEngine.InputSystem.Editor;
11+
using UnityEngine.InputSystem.Processors;
1112
using UnityEngine.TestTools;
1213
using UnityEngine.UIElements;
1314

@@ -108,5 +109,69 @@ public IEnumerator ProcessorEnum_ShouldSerializeByValue_WhenSerializedToAsset()
108109

109110
yield return null;
110111
}
112+
113+
[Test]
114+
[Description("Regression test for case ISXB-1674")]
115+
public void Migration_ShouldProduceValidActionAsset_WithEnumProcessorConverted()
116+
{
117+
const string k_Json = @"
118+
{
119+
""name"": ""InputSystem_Actions"",
120+
""maps"": [
121+
{
122+
""name"": ""Player"",
123+
""id"": ""df70fa95-8a34-4494-b137-73ab6b9c7d37"",
124+
""actions"": [
125+
{
126+
""name"": ""Move"",
127+
""type"": ""Value"",
128+
""id"": ""938a78a0-f8c6-4b2e-b8a7-d3c26d83a4e9"",
129+
""expectedControlType"": ""Vector2"",
130+
""processors"": ""StickDeadzone,InvertVector2(invertX=false),Custom(SomeEnum=1)"",
131+
""interactions"": """",
132+
""initialStateCheck"": true
133+
}
134+
],
135+
""bindings"": [
136+
{
137+
""name"": """",
138+
""id"": ""c9a175a0-a5ed-4e2c-b3a9-1d4d3d3a7a9a"",
139+
""path"": ""<Gamepad>/leftStick"",
140+
""interactions"": """",
141+
""processors"": """",
142+
""groups"": """",
143+
""action"": ""Move"",
144+
""isComposite"": false,
145+
""isPartOfComposite"": false
146+
}
147+
]
148+
}
149+
],
150+
""controlSchemes"": []
151+
}";
152+
153+
var asset = InputActionAsset.FromJson(k_Json);
154+
155+
// Enable the action to call rebinding
156+
asset.FindAction("Move").Enable();
157+
158+
var map = asset.FindActionMap("Player");
159+
160+
// Directly tests the outcome of the migration and parsing logic, which is the core goal.
161+
var instantiatedProcessors = map.m_State.processors;
162+
Assert.That(map.m_State.totalProcessorCount, Is.EqualTo(3), "Should create exactly three processors.");
163+
164+
// Verify the order and type of each processor.
165+
Assert.That(instantiatedProcessors[0], Is.TypeOf<StickDeadzoneProcessor>(), "First processor should be StickDeadzone.");
166+
Assert.That(instantiatedProcessors[1], Is.TypeOf<InvertVector2Processor>(), "Second processor should be InvertVector2.");
167+
Assert.That(instantiatedProcessors[2], Is.TypeOf<CustomProcessor>(), "Third processor should be the custom type.");
168+
169+
// Verify the specific data for processors with parameters.
170+
var invertProcessor = (InvertVector2Processor)instantiatedProcessors[1];
171+
Assert.That(invertProcessor.invertX, Is.False, "invertX parameter should be false.");
172+
173+
var customProcessor = (CustomProcessor)instantiatedProcessors[2];
174+
Assert.That(customProcessor.SomeEnum, Is.EqualTo(SomeEnum.OptionB), "Enum parameter should be parsed correctly to OptionB.");
175+
}
111176
}
112177
#endif

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ however, it has to be formatted properly to pass verification tests.
3535
- Fix usage of correct data format for stick axes in HID Layout Builder ([User contribution](https://github.com/Unity-Technologies/InputSystem/pull/2245))
3636
- Fixed InputSystemUIInputModule calling pointer events on parent objects even when the "Send Pointer Hover To Parent" is off on 2022.3.XX. This was was previously only available on Unity 6 versions since 1.11.0. [ISXB-1296]
3737
- Fixed an issue where the action icon would shrink or disappear from UI when an action has a very long name. [ISXB-1650](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1650).
38+
- Fixed upgrading input actions containing multiple processors [ISXB-1674](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1674).
3839

3940
## [1.15.0] - 2025-10-03
4041

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

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,11 @@ internal void MigrateJson(ref ReadFileJson parsedJson)
10161016
return;
10171017
if ((parsedJson.maps?.Length ?? 0) > 0 && (parsedJson.version) < JsonVersion.Version1)
10181018
{
1019+
List<NameAndParameters> parsedList = null;
1020+
var converted = new List<NameAndParameters>(8);
1021+
var updatedParameters = new List<NamedValue>(4);
1022+
var enumValuesCache = new Dictionary<Type, Array>(8);
1023+
10191024
for (var mi = 0; mi < parsedJson.maps.Length; ++mi)
10201025
{
10211026
var mapJson = parsedJson.maps[mi];
@@ -1026,44 +1031,49 @@ internal void MigrateJson(ref ReadFileJson parsedJson)
10261031
if (string.IsNullOrEmpty(raw))
10271032
continue;
10281033

1029-
var list = NameAndParameters.ParseMultiple(raw).ToList();
1030-
var rebuilt = new List<string>(list.Count);
1031-
foreach (var nap in list)
1034+
if (!NameAndParameters.ParseMultiple(raw, ref parsedList))
1035+
continue;
1036+
1037+
converted.Clear();
1038+
1039+
for (int i = 0; i < parsedList.Count; ++i)
10321040
{
1041+
var nap = parsedList[i];
10331042
var procType = InputSystem.TryGetProcessor(nap.name);
10341043
if (nap.parameters.Count == 0 || procType == null)
10351044
{
1036-
rebuilt.Add(nap.ToString());
1045+
converted.Add(nap);
10371046
continue;
10381047
}
1039-
1040-
var dict = nap.parameters.ToDictionary(p => p.name, p => p.value.ToString());
1041-
var anyChanged = false;
1042-
foreach (var field in procType.GetFields(BindingFlags.Public | BindingFlags.Instance).Where(f => f.FieldType.IsEnum))
1048+
updatedParameters.Clear();
1049+
for (int k = 0; k < nap.parameters.Count; ++k)
10431050
{
1044-
if (dict.TryGetValue(field.Name, out var ordS) && int.TryParse(ordS, out var ord))
1051+
var param = nap.parameters[k];
1052+
var updatedPar = param;
1053+
1054+
var fieldInfo = procType.GetField(param.name, BindingFlags.Public | BindingFlags.Instance);
1055+
if (fieldInfo != null && fieldInfo.FieldType.IsEnum)
10451056
{
1046-
var values = Enum.GetValues(field.FieldType).Cast<object>().ToArray();
1047-
if (ord >= 0 && ord < values.Length)
1057+
var index = param.value.ToInt32();
1058+
if (index >= 0)
10481059
{
1049-
dict[field.Name] = Convert.ToInt32(values[ord]).ToString();
1050-
anyChanged = true;
1060+
if (!enumValuesCache.TryGetValue(fieldInfo.FieldType, out var values))
1061+
{
1062+
values = Enum.GetValues(fieldInfo.FieldType);
1063+
enumValuesCache[fieldInfo.FieldType] = values;
1064+
}
1065+
if (index < values.Length)
1066+
{
1067+
var convertedValue = Convert.ToInt32(values.GetValue(index));
1068+
updatedPar = NamedValue.From(param.name, convertedValue);
1069+
}
10511070
}
10521071
}
1072+
updatedParameters.Add(updatedPar);
10531073
}
1054-
1055-
if (!anyChanged)
1056-
{
1057-
rebuilt.Add(nap.ToString());
1058-
}
1059-
else
1060-
{
1061-
var paramText = string.Join(",", dict.Select(kv => $"{kv.Key}={kv.Value}"));
1062-
rebuilt.Add($"{nap.name}({paramText})");
1063-
}
1074+
converted.Add(NameAndParameters.Create(nap.name, updatedParameters));
10641075
}
1065-
1066-
actionJson.processors = string.Join(";", rebuilt);
1076+
actionJson.processors = NameAndParameters.ToSerializableString(converted);
10671077
mapJson.actions[ai] = actionJson;
10681078
}
10691079
parsedJson.maps[mi] = mapJson;

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/NameAndParametersListView.cs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void OnAddElement(string name)
3737
var newElement = new NameAndParameters() { name = name};
3838
interactionsOrProcessorsList.Add(newElement);
3939

40-
m_ListProperty.stringValue = ToSerializableString(interactionsOrProcessorsList);
40+
m_ListProperty.stringValue = NameAndParameters.ToSerializableString(interactionsOrProcessorsList);
4141
m_ListProperty.serializedObject.ApplyModifiedProperties();
4242
}
4343

@@ -61,35 +61,26 @@ private void SwapElement(int oldIndex, int newIndex)
6161
if (interactionsOrProcessors.Length == 0 || !newIndexIsValid || !oldIndexIsValid)
6262
return;
6363
MemoryHelpers.Swap(ref interactionsOrProcessors[oldIndex], ref interactionsOrProcessors[newIndex]);
64-
m_ListProperty.stringValue = ToSerializableString(interactionsOrProcessors);
64+
m_ListProperty.stringValue = NameAndParameters.ToSerializableString(interactionsOrProcessors);
6565
m_ListProperty.serializedObject.ApplyModifiedProperties();
6666
}
6767

6868
private void DeleteElement(int index)
6969
{
7070
var interactionsOrProcessorsList = NameAndParameters.ParseMultiple(m_ListProperty.stringValue).ToList();
7171
interactionsOrProcessorsList.RemoveAt(index);
72-
m_ListProperty.stringValue = ToSerializableString(interactionsOrProcessorsList);
72+
m_ListProperty.stringValue = NameAndParameters.ToSerializableString(interactionsOrProcessorsList);
7373
m_ListProperty.serializedObject.ApplyModifiedProperties();
7474
}
7575

7676
private void OnParametersChanged(ParameterListView listView, int index)
7777
{
7878
var interactionsOrProcessorsList = NameAndParameters.ParseMultiple(m_ListProperty.stringValue).ToList();
7979
interactionsOrProcessorsList[index] = new NameAndParameters { name = interactionsOrProcessorsList[index].name, parameters = listView.GetParameters() };
80-
m_ListProperty.stringValue = ToSerializableString(interactionsOrProcessorsList);
80+
m_ListProperty.stringValue = NameAndParameters.ToSerializableString(interactionsOrProcessorsList);
8181
m_ListProperty.serializedObject.ApplyModifiedProperties();
8282
}
8383

84-
private static string ToSerializableString(IEnumerable<NameAndParameters> parametersForEachListItem)
85-
{
86-
if (parametersForEachListItem == null)
87-
return string.Empty;
88-
89-
return string.Join(NamedValue.Separator,
90-
parametersForEachListItem.Select(x => x.ToString()).ToArray());
91-
}
92-
9384
public override void RedrawUI(InputActionsEditorState state)
9485
{
9586
if (m_ContentContainer != null)

Packages/com.unity.inputsystem/InputSystem/Utilities/NameAndParameters.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@ public override string ToString()
2727
return $"{name}({parameterString})";
2828
}
2929

30+
internal static string ToSerializableString(IEnumerable<NameAndParameters> list)
31+
{
32+
if (list == null)
33+
return string.Empty;
34+
35+
return string.Join(NamedValue.Separator, list.Select(x => x.ToString()).ToArray());
36+
}
37+
38+
internal static NameAndParameters Create(string name, IList<NamedValue> parameters)
39+
{
40+
return new NameAndParameters
41+
{
42+
name = name,
43+
parameters = new ReadOnlyArray<NamedValue>(parameters.ToArray())
44+
};
45+
}
46+
3047
public static IEnumerable<NameAndParameters> ParseMultiple(string text)
3148
{
3249
List<NameAndParameters> list = null;

0 commit comments

Comments
 (0)