Skip to content

Commit 6056972

Browse files
committed
Fixed ArgumentNullException during the migration of Project-wide Input Actions
1 parent 89a370c commit 6056972

File tree

2 files changed

+69
-31
lines changed

2 files changed

+69
-31
lines changed

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ however, it has to be formatted properly to pass verification tests.
1010

1111
## [Unreleased] - yyyy-mm-dd
1212

13+
### Fixed
14+
- Fixed `ArgumentNullException: Value cannot be null.` during the migration of Project-wide Input Actions from `InputManager.asset` to `InputSystem_Actions.inputactions` asset which lead do the lost of the configuration [ISXB-1105](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1105)
1315

16+
### Changed
17+
- Added back the InputManager to InputSystem project-wide asset migration code with performance improvement (ISX-2086)
1418

1519
## [1.11.2] - 2024-10-16
1620

Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsAsset.cs

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ private static void OnPostprocessAllAssets(string[] importedAssets, string[] del
3030
private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
3131
#endif
3232
{
33-
if (!migratedInputActionAssets)
33+
if (!migratedInputActionAssets && importedAssets.Contains(kAssetPathInputManager))
3434
{
3535
MoveInputManagerAssetActionsToProjectWideInputActionAsset();
3636
migratedInputActionAssets = true;
@@ -47,51 +47,80 @@ private static void OnPostprocessAllAssets(string[] importedAssets, string[] del
4747
}
4848
}
4949

50-
private static void MoveInputManagerAssetActionsToProjectWideInputActionAsset()
50+
private static void MoveInputManagerAssetActionsToProjectWideInputActionAsset(bool allowRetry = true)
5151
{
5252
var objects = AssetDatabase.LoadAllAssetsAtPath(EditorHelpers.GetPhysicalPath(kAssetPathInputManager));
5353
if (objects == null)
5454
return;
5555

56-
var inputActionsAsset = objects.FirstOrDefault(o => o != null && o.name == kAssetNameProjectWideInputActions) as InputActionAsset;
57-
if (inputActionsAsset != default)
58-
{
59-
// Found some actions in the InputManager.asset file
60-
//
61-
string path = ProjectWideActionsAsset.kDefaultAssetPath;
56+
var inputActionsAssets = objects.Where(o => o != null && o.name == kAssetNameProjectWideInputActions && o is InputActionAsset);
57+
58+
if (!inputActionsAssets.Any()) return;
59+
60+
Debug.Log("Migrating Project-wide Input Actions from InputManager.asset to InputSystem_Actions.inputactions asset");
6261

63-
if (File.Exists(EditorHelpers.GetPhysicalPath(path)))
62+
// workarround for serialization bug with ScriptableObject in ProjectSettings during reimporting all asset, it should not be null
63+
if (allowRetry)
64+
{
65+
foreach (InputActionAsset inputActionsAsset in inputActionsAssets)
6466
{
65-
// We already have a path containing inputactions, find a new unique filename
66-
//
67-
// eg Assets/InputSystem_Actions.inputactions ->
68-
// Assets/InputSystem_Actions (1).inputactions ->
69-
// Assets/InputSystem_Actions (2).inputactions ...
70-
//
71-
string[] files = Directory.GetFiles("Assets", "*.inputactions");
72-
List<string> names = new List<string>();
73-
for (int i = 0; i < files.Length; i++)
67+
if (inputActionsAsset.m_ActionMaps == null)
7468
{
75-
names.Add(System.IO.Path.GetFileNameWithoutExtension(files[i]));
69+
// unload asset to avoid serialization bug and will try again later
70+
Resources.UnloadAsset(inputActionsAsset);
71+
Debug.Log($"Unexpected null action map encounted during the migration, will try again once later");
72+
EditorApplication.delayCall += () => { MoveInputManagerAssetActionsToProjectWideInputActionAsset(allowRetry: false); };
73+
return;
7674
}
77-
string unique = ObjectNames.GetUniqueName(names.ToArray(), kDefaultAssetName);
78-
path = "Assets/" + unique + ".inputactions";
7975
}
76+
}
77+
78+
foreach (InputActionAsset inputActionsAsset in inputActionsAssets)
79+
{
80+
if (inputActionsAsset != default)
81+
{
82+
// sanity check to avoid saving a badly serialized asset or empty asset
83+
if (inputActionsAsset.m_ActionMaps.LengthSafe() == 0)
84+
{
85+
continue;
86+
}
87+
string path = ProjectWideActionsAsset.kDefaultAssetPath;
88+
89+
if (File.Exists(EditorHelpers.GetPhysicalPath(path)))
90+
{
91+
// We already have a path containing inputactions, find a new unique filename
92+
//
93+
// eg Assets/InputSystem_Actions.inputactions ->
94+
// Assets/InputSystem_Actions (1).inputactions ->
95+
// Assets/InputSystem_Actions (2).inputactions ...
96+
//
97+
string[] files = Directory.GetFiles("Assets", "*.inputactions");
98+
List<string> names = new List<string>();
99+
for (int i = 0; i < files.Length; i++)
100+
{
101+
names.Add(System.IO.Path.GetFileNameWithoutExtension(files[i]));
102+
}
103+
string unique = ObjectNames.GetUniqueName(names.ToArray(), kDefaultAssetName);
104+
path = "Assets/" + unique + ".inputactions";
105+
}
80106

81-
var json = inputActionsAsset.ToJson();
82-
InputActionAssetManager.SaveAsset(EditorHelpers.GetPhysicalPath(path), json);
107+
var json = inputActionsAsset.ToJson();
108+
InputActionAssetManager.SaveAsset(EditorHelpers.GetPhysicalPath(path), json);
83109

84-
Debug.Log($"Migrated Project-wide Input Actions from '{kAssetPathInputManager}' to '{path}' asset");
110+
Debug.Log($"Migrated Project-wide Input Actions from '{kAssetPathInputManager}' to '{path}' asset");
85111

86-
// Update current project-wide settings if needed (don't replace if already set to something else)
87-
//
88-
if (InputSystem.actions == null || InputSystem.actions.name == kAssetNameProjectWideInputActions)
89-
{
90-
InputSystem.actions = (InputActionAsset)AssetDatabase.LoadAssetAtPath(path, typeof(InputActionAsset));
91-
Debug.Log($"Loaded Project-wide Input Actions from '{path}' asset");
112+
// Update current project-wide settings if needed (don't replace if already set to something else)
113+
//
114+
if (InputSystem.actions == null || InputSystem.actions.name == kAssetNameProjectWideInputActions)
115+
{
116+
InputSystem.actions = (InputActionAsset)AssetDatabase.LoadAssetAtPath(path, typeof(InputActionAsset));
117+
Debug.Log($"Loaded Project-wide Input Actions from '{path}' asset");
118+
}
92119
}
93120
}
94121

122+
123+
bool hasChanged = false;
95124
// Handle deleting all InputActionAssets as older 1.8.0 pre release could create more than one project wide input asset in the file
96125
foreach (var obj in objects)
97126
{
@@ -100,14 +129,19 @@ private static void MoveInputManagerAssetActionsToProjectWideInputActionAsset()
100129
var actionReference = obj as InputActionReference;
101130
AssetDatabase.RemoveObjectFromAsset(obj);
102131
Object.DestroyImmediate(actionReference);
132+
hasChanged = true;
103133
}
104134
else if (obj is InputActionAsset)
105135
{
106136
AssetDatabase.RemoveObjectFromAsset(obj);
137+
hasChanged = true;
107138
}
108139
}
109140

110-
AssetDatabase.SaveAssets();
141+
if (hasChanged == true)
142+
{
143+
AssetDatabase.SaveAssets();
144+
}
111145
}
112146
}
113147

0 commit comments

Comments
 (0)