diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index a6a60d0769..a771fcba2f 100644 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -38,6 +38,7 @@ however, it has to be formatted properly to pass verification tests. - Limited the Add Control Scheme popup window max size to be its parent window, so that it won't resize beyond the visible area. [ISXB-1733](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1733) - Fixed an issue where the action icon would shrink or disappear from UI when an action has a very long name. [ISXB-1650](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1650). - Fixed upgrading input actions containing multiple processors [ISXB-1674](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1674). +- Fixed an issue that led to non-deterministic behaviour during `.inputaction` asset imports that could lead to corrupted assets or Unity hanging during asset import when "Generate C# Scripts" was active in importer settings. [ISXB-1746](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1746) ## [1.15.0] - 2025-10-03 diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/AssetImporter/InputActionImporter.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/AssetImporter/InputActionImporter.cs index 9aa690b466..27211e519d 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/AssetImporter/InputActionImporter.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/AssetImporter/InputActionImporter.cs @@ -124,8 +124,12 @@ public override void OnImportAsset(AssetImportContext ctx) if (asset == null) return; - if (m_GenerateWrapperCode) - GenerateWrapperCode(ctx, asset, m_WrapperCodeNamespace, m_WrapperClassName, m_WrapperCodePath); + if (m_GenerateWrapperCode && HasMapWithSameNameAsAsset(asset, m_WrapperClassName)) + { + ctx.LogImportError( + $"{asset.name}: An action map in an .inputactions asset cannot be named the same as the asset itself if 'Generate C# Class' is used. " + + "You can rename the action map in the asset, rename the asset itself or assign a different C# class name in the import settings."); + } } internal static void SetupAsset(InputActionAsset asset) @@ -201,26 +205,25 @@ private static void CreateInputActionReferences(InputActionAsset asset, AddObjec } } - private static void GenerateWrapperCode(AssetImportContext ctx, InputActionAsset asset, string codeNamespace, string codeClassName, string codePath) + private static bool HasMapWithSameNameAsAsset(InputActionAsset asset, string codeClassName) { - var maps = asset.actionMaps; // When using code generation, it is an error for any action map to be named the same as the asset itself. // https://fogbugz.unity3d.com/f/cases/1212052/ var className = !string.IsNullOrEmpty(codeClassName) ? codeClassName : CSharpCodeHelpers.MakeTypeName(asset.name); - if (maps.Any(x => - CSharpCodeHelpers.MakeTypeName(x.name) == className || CSharpCodeHelpers.MakeIdentifier(x.name) == className)) - { - ctx.LogImportError( - $"{asset.name}: An action map in an .inputactions asset cannot be named the same as the asset itself if 'Generate C# Class' is used. " - + "You can rename the action map in the asset, rename the asset itself or assign a different C# class name in the import settings."); + return (asset.actionMaps.Any(x => + CSharpCodeHelpers.MakeTypeName(x.name) == className || + CSharpCodeHelpers.MakeIdentifier(x.name) == className)); + } + + private static void GenerateWrapperCode(string assetPath, InputActionAsset asset, string codeNamespace, string codeClassName, string codePath) + { + if (HasMapWithSameNameAsAsset(asset, codeClassName)) return; - } var wrapperFilePath = codePath; if (string.IsNullOrEmpty(wrapperFilePath)) { // Placed next to .inputactions file. - var assetPath = ctx.assetPath; var directory = Path.GetDirectoryName(assetPath); var fileName = Path.GetFileNameWithoutExtension(assetPath); wrapperFilePath = Path.Combine(directory, fileName) + ".cs"; @@ -229,7 +232,6 @@ private static void GenerateWrapperCode(AssetImportContext ctx, InputActionAsset wrapperFilePath.StartsWith("../") || wrapperFilePath.StartsWith("..\\")) { // User-specified file relative to location of .inputactions file. - var assetPath = ctx.assetPath; var directory = Path.GetDirectoryName(assetPath); wrapperFilePath = Path.Combine(directory, wrapperFilePath); } @@ -258,11 +260,12 @@ private static void GenerateWrapperCode(AssetImportContext ctx, InputActionAsset var options = new InputActionCodeGenerator.Options { - sourceAssetPath = ctx.assetPath, + sourceAssetPath = assetPath, namespaceName = codeNamespace, className = codeClassName, }; + if (InputActionCodeGenerator.GenerateWrapperCode(wrapperFilePath, asset, options)) { // This isn't ideal and may have side effects, but we cannot avoid compiling again. @@ -378,13 +381,30 @@ private static bool ContainsInputActionAssetPath(string[] assetPaths) private class InputActionJsonNameModifierAssetProcessor : AssetPostprocessor { private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, - string[] movedAssets, string[] movedFromAssetPaths, bool didDomainReload) + string[] movedAssets, string[] movedFromAssetPaths) { var needToInvalidate = false; foreach (var assetPath in importedAssets) { if (IsInputActionAssetPath(assetPath)) { + // Generate C# code from asset if configured via importer settings. + // We generate from a parsed temporary asset here since loading the asset won't work here. + var importer = GetAtPath(assetPath) as InputActionImporter; + if (importer != null && importer.m_GenerateWrapperCode) + { + try + { + var asset = InputActionAsset.FromJson(File.ReadAllText(assetPath)); + GenerateWrapperCode(assetPath, asset, importer.m_WrapperCodeNamespace, + importer.m_WrapperClassName, importer.m_WrapperCodePath); + } + catch (Exception e) + { + Debug.LogException(e); + } + } + needToInvalidate = true; CheckAndRenameJsonNameIfDifferent(assetPath); }