diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index 10fd9c4724..6a9a909a41 100644 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -12,6 +12,10 @@ however, it has to be formatted properly to pass verification tests. ### Fixed - Fixed an issue causing the Action context menu to not show on right click when right clicking an action in the Input Action Editor [ISXB-1134](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1134). +- 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) + +### Changed +- Added back the InputManager to InputSystem project-wide asset migration code with performance improvement (ISX-2086) ## [1.11.2] - 2024-10-16 diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsAsset.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsAsset.cs index 027faf6e5f..848af6320a 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsAsset.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsAsset.cs @@ -17,14 +17,25 @@ internal static class ProjectWideActionsAsset internal static class ProjectSettingsProjectWideActionsAssetConverter { + private const string kAssetPathInputManager = "ProjectSettings/InputManager.asset"; + private const string kAssetNameProjectWideInputActions = "ProjectWideInputActions"; + class ProjectSettingsPostprocessor : AssetPostprocessor { + private static bool migratedInputActionAssets = false; + #if UNITY_2021_2_OR_NEWER private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths, bool didDomainReload) #else private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) #endif { + if (!migratedInputActionAssets && importedAssets.Contains(kAssetPathInputManager)) + { + MoveInputManagerAssetActionsToProjectWideInputActionAsset(); + migratedInputActionAssets = true; + } + if (!Application.isPlaying) { // If the Library folder is deleted, InputSystem will fail to retrieve the assigned Project-wide Asset because this look-up occurs @@ -35,6 +46,103 @@ private static void OnPostprocessAllAssets(string[] importedAssets, string[] del } } } + + private static void MoveInputManagerAssetActionsToProjectWideInputActionAsset(bool allowRetry = true) + { + var objects = AssetDatabase.LoadAllAssetsAtPath(EditorHelpers.GetPhysicalPath(kAssetPathInputManager)); + if (objects == null) + return; + + var inputActionsAssets = objects.Where(o => o != null && o.name == kAssetNameProjectWideInputActions && o is InputActionAsset); + + if (!inputActionsAssets.Any()) return; + + Debug.Log("Migrating Project-wide Input Actions from InputManager.asset to InputSystem_Actions.inputactions asset"); + + // workarround for serialization bug with ScriptableObject in ProjectSettings during reimporting all asset, it should not be null + if (allowRetry) + { + foreach (InputActionAsset inputActionsAsset in inputActionsAssets) + { + if (inputActionsAsset.m_ActionMaps == null) + { + // unload asset to avoid serialization bug and will try again later + Resources.UnloadAsset(inputActionsAsset); + Debug.Log($"Unexpected null action map encounted during the migration, will try again once later"); + EditorApplication.delayCall += () => { MoveInputManagerAssetActionsToProjectWideInputActionAsset(allowRetry: false); }; + return; + } + } + } + + foreach (InputActionAsset inputActionsAsset in inputActionsAssets) + { + if (inputActionsAsset != default) + { + // sanity check to avoid saving a badly serialized asset or empty asset + if (inputActionsAsset.m_ActionMaps.LengthSafe() == 0) + { + continue; + } + string path = ProjectWideActionsAsset.kDefaultAssetPath; + + if (File.Exists(EditorHelpers.GetPhysicalPath(path))) + { + // We already have a path containing inputactions, find a new unique filename + // + // eg Assets/InputSystem_Actions.inputactions -> + // Assets/InputSystem_Actions (1).inputactions -> + // Assets/InputSystem_Actions (2).inputactions ... + // + string[] files = Directory.GetFiles("Assets", "*.inputactions"); + List names = new List(); + for (int i = 0; i < files.Length; i++) + { + names.Add(System.IO.Path.GetFileNameWithoutExtension(files[i])); + } + string unique = ObjectNames.GetUniqueName(names.ToArray(), kDefaultAssetName); + path = "Assets/" + unique + ".inputactions"; + } + + var json = inputActionsAsset.ToJson(); + InputActionAssetManager.SaveAsset(EditorHelpers.GetPhysicalPath(path), json); + + Debug.Log($"Migrated Project-wide Input Actions from '{kAssetPathInputManager}' to '{path}' asset"); + + // Update current project-wide settings if needed (don't replace if already set to something else) + // + if (InputSystem.actions == null || InputSystem.actions.name == kAssetNameProjectWideInputActions) + { + InputSystem.actions = (InputActionAsset)AssetDatabase.LoadAssetAtPath(path, typeof(InputActionAsset)); + Debug.Log($"Loaded Project-wide Input Actions from '{path}' asset"); + } + } + } + + + bool hasChanged = false; + // Handle deleting all InputActionAssets as older 1.8.0 pre release could create more than one project wide input asset in the file + foreach (var obj in objects) + { + if (obj is InputActionReference) + { + var actionReference = obj as InputActionReference; + AssetDatabase.RemoveObjectFromAsset(obj); + Object.DestroyImmediate(actionReference); + hasChanged = true; + } + else if (obj is InputActionAsset) + { + AssetDatabase.RemoveObjectFromAsset(obj); + hasChanged = true; + } + } + + if (hasChanged == true) + { + AssetDatabase.SaveAssets(); + } + } } // Returns the default asset path for where to create project-wide actions asset.