Skip to content

Commit a521b32

Browse files
committed
Implement migrator for the old input action asset as we now serialize the enums by value in the processors.
1 parent 7c7b927 commit a521b32

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ public string ToJson()
298298
{
299299
return JsonUtility.ToJson(new WriteFileJson
300300
{
301+
version = m_Version,
301302
name = name,
302303
maps = InputActionMap.WriteFileJson.FromMaps(m_ActionMaps).maps,
303304
controlSchemes = InputControlScheme.SchemeJson.ToJson(m_ControlSchemes),
@@ -946,10 +947,12 @@ private void OnDestroy()
946947
[NonSerialized] internal InputActionRebindingExtensions.ParameterOverride[] m_ParameterOverrides;
947948

948949
[NonSerialized] internal InputActionMap.DeviceArray m_Devices;
950+
[SerializeField] internal int m_Version;
949951

950952
[Serializable]
951953
internal struct WriteFileJson
952954
{
955+
public int version;
953956
public string name;
954957
public InputActionMap.WriteMapJson[] maps;
955958
public InputControlScheme.SchemeJson[] controlSchemes;
@@ -965,12 +968,14 @@ internal struct WriteFileJsonNoName
965968
[Serializable]
966969
internal struct ReadFileJson
967970
{
971+
public int version;
968972
public string name;
969973
public InputActionMap.ReadMapJson[] maps;
970974
public InputControlScheme.SchemeJson[] controlSchemes;
971975

972976
public void ToAsset(InputActionAsset asset)
973977
{
978+
asset.m_Version = version;
974979
asset.name = name;
975980
asset.m_ActionMaps = new InputActionMap.ReadFileJson {maps = maps}.ToMaps();
976981
asset.m_ControlSchemes = InputControlScheme.SchemeJson.ToSchemes(controlSchemes);

Packages/com.unity.inputsystem/InputSystem/Editor/AssetImporter/InputActionImporter.cs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.IO;
55
using System.Linq;
6+
using System.Reflection;
67
using UnityEditor;
78
#if UNITY_2020_2_OR_NEWER
89
using UnityEditor.AssetImporters;
@@ -29,6 +30,8 @@ namespace UnityEngine.InputSystem.Editor
2930
internal class InputActionImporter : ScriptedImporter
3031
{
3132
private const int kVersion = 13;
33+
// Bump this whenever you make a breaking change to the on-disk JSON format
34+
private const int kJsonFormatVersion = 1;
3235

3336
[SerializeField] private bool m_GenerateWrapperCode;
3437
[SerializeField] private string m_WrapperCodePath;
@@ -67,6 +70,19 @@ private static InputActionAsset CreateFromJson(AssetImportContext context)
6770
// Attempt to parse JSON
6871
asset.LoadFromJson(content);
6972

73+
// If this JSON was authored before we switched to enum-by-value, migrate it now
74+
if (asset.m_Version < kJsonFormatVersion)
75+
{
76+
MigrateAllEnumParams(asset);
77+
asset.m_Version = kJsonFormatVersion;
78+
79+
if (!EditorHelpers.WriteAsset(context.assetPath, asset.ToJson()))
80+
context.LogImportError($"Could not write migrated JSON to '{context.assetPath}'");
81+
82+
EditorUtility.SetDirty(asset);
83+
return null;
84+
}
85+
7086
// Make sure action map names are unique within JSON file
7187
var names = new HashSet<string>();
7288
foreach (var map in asset.actionMaps)
@@ -117,6 +133,76 @@ private static InputActionAsset CreateFromJson(AssetImportContext context)
117133
return asset;
118134
}
119135

136+
static void MigrateAllEnumParams(InputActionAsset asset)
137+
{
138+
foreach (var map in asset.actionMaps)
139+
{
140+
foreach (var action in map.actions)
141+
{
142+
var raw = action.processors;
143+
if (string.IsNullOrEmpty(raw))
144+
continue;
145+
146+
var rebuilt = new List<string>();
147+
foreach (var entry in raw.Split(';'))
148+
{
149+
var e = entry.Trim();
150+
if (e.Length == 0)
151+
{
152+
rebuilt.Add(e);
153+
continue;
154+
}
155+
156+
var paren = e.IndexOf('(');
157+
string procName = paren >= 0 ? e.Substring(0, paren) : e;
158+
string args = paren >= 0
159+
? e.Substring(paren + 1, e.Length - paren - 2)
160+
: null;
161+
162+
var procType = InputSystem.TryGetProcessor(procName);
163+
if (procType != null && args != null)
164+
{
165+
var patched = PatchEnumArgs(procType, args);
166+
rebuilt.Add($"{procName}({patched})");
167+
}
168+
else
169+
{
170+
rebuilt.Add(e);
171+
}
172+
}
173+
174+
action.m_Processors = string.Join(";", rebuilt);
175+
}
176+
}
177+
}
178+
179+
static string PatchEnumArgs(Type procType, string args)
180+
{
181+
var dict = args.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Split('=')).ToDictionary(kv => kv[0], kv => kv[1]);
182+
var anyChanged = false;
183+
var enumFields = procType.GetFields(BindingFlags.Public | BindingFlags.Instance).Where(f => f.FieldType.IsEnum);
184+
185+
foreach (var field in enumFields)
186+
{
187+
if (dict.TryGetValue(field.Name, out var raw) && int.TryParse(raw, out var ordinal))
188+
{
189+
var values = Enum.GetValues(field.FieldType).Cast<object>().ToArray();
190+
191+
if (ordinal >= 0 && ordinal < values.Length)
192+
{
193+
var real = Convert.ToInt32(values[ordinal]);
194+
dict[field.Name] = real.ToString();
195+
anyChanged = true;
196+
}
197+
}
198+
}
199+
200+
if (!anyChanged)
201+
return args;
202+
203+
return string.Join(",", dict.Select(kv => $"{kv.Key}={kv.Value}"));
204+
}
205+
120206
public override void OnImportAsset(AssetImportContext ctx)
121207
{
122208
if (ctx == null)

0 commit comments

Comments
 (0)