Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Packages/com.unity.inputsystem/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ however, it has to be formatted properly to pass verification tests.

## [Unreleased] - yyyy-mm-dd

### Fixed
- 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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<string> names = new List<string>();
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.
Expand Down