3
3
using System . Collections . Generic ;
4
4
using System . IO ;
5
5
using System . Linq ;
6
+ using System . Reflection ;
6
7
using UnityEditor ;
7
8
#if UNITY_2020_2_OR_NEWER
8
9
using UnityEditor . AssetImporters ;
@@ -29,6 +30,8 @@ namespace UnityEngine.InputSystem.Editor
29
30
internal class InputActionImporter : ScriptedImporter
30
31
{
31
32
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 ;
32
35
33
36
[ SerializeField ] private bool m_GenerateWrapperCode ;
34
37
[ SerializeField ] private string m_WrapperCodePath ;
@@ -67,6 +70,19 @@ private static InputActionAsset CreateFromJson(AssetImportContext context)
67
70
// Attempt to parse JSON
68
71
asset . LoadFromJson ( content ) ;
69
72
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
+
70
86
// Make sure action map names are unique within JSON file
71
87
var names = new HashSet < string > ( ) ;
72
88
foreach ( var map in asset . actionMaps )
@@ -117,6 +133,76 @@ private static InputActionAsset CreateFromJson(AssetImportContext context)
117
133
return asset ;
118
134
}
119
135
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
+
120
206
public override void OnImportAsset ( AssetImportContext ctx )
121
207
{
122
208
if ( ctx == null )
0 commit comments