diff --git a/Source/AssetRipper.Export.UnityProjects/ExportHandler.cs b/Source/AssetRipper.Export.UnityProjects/ExportHandler.cs index e38a8c42b..428f42c40 100644 --- a/Source/AssetRipper.Export.UnityProjects/ExportHandler.cs +++ b/Source/AssetRipper.Export.UnityProjects/ExportHandler.cs @@ -91,7 +91,8 @@ public class ExportHandler yield return new ScriptableObjectProcessor(); } - public void Export(GameData gameData, string outputPath) + public void Export(GameData gameData, string outputPath) => Export(gameData, outputPath, LocalFileSystem.Instance); + public void Export(GameData gameData, string outputPath, FileSystem fileSystem) { Logger.Info(LogCategory.Export, "Starting export"); Logger.Info(LogCategory.Export, $"Attempting to export assets to {outputPath}..."); @@ -104,13 +105,13 @@ public class ExportHandler ProjectExporter projectExporter = new(Settings, gameData.AssemblyManager); BeforeExport(projectExporter); projectExporter.DoFinalOverrides(Settings); - projectExporter.Export(gameData.GameBundle, Settings, LocalFileSystem.Instance); + projectExporter.Export(gameData.GameBundle, Settings, fileSystem); Logger.Info(LogCategory.Export, "Finished exporting assets"); foreach (IPostExporter postExporter in GetPostExporters()) { - postExporter.DoPostExport(gameData, Settings, LocalFileSystem.Instance); + postExporter.DoPostExport(gameData, Settings, fileSystem); } Logger.Info(LogCategory.Export, "Finished post-export"); diff --git a/Source/AssetRipper.Export.UnityProjects/Project/ScriptableObjectExporter.cs b/Source/AssetRipper.Export.UnityProjects/Project/ScriptableObjectExporter.cs index 37afd7921..936a66b1a 100644 --- a/Source/AssetRipper.Export.UnityProjects/Project/ScriptableObjectExporter.cs +++ b/Source/AssetRipper.Export.UnityProjects/Project/ScriptableObjectExporter.cs @@ -8,14 +8,13 @@ namespace AssetRipper.Export.UnityProjects.Project { private IExportCollection CreateCollection(IMonoBehaviour monoBehaviour) { - if (monoBehaviour.IsScriptableObject()) + if (monoBehaviour.IsComponentOnGameObject()) { - return new ScriptableObjectExportCollection(this, monoBehaviour); + return EmptyExportCollection.Instance; } else { - // such MonoBehaviours as StateMachineBehaviour in AnimatorController - return EmptyExportCollection.Instance; + return new ScriptableObjectExportCollection(this, monoBehaviour); } } diff --git a/Source/AssetRipper.Processing/Prefabs/SceneHierarchyObject.cs b/Source/AssetRipper.Processing/Prefabs/SceneHierarchyObject.cs index 74a7ab785..5bec635c4 100644 --- a/Source/AssetRipper.Processing/Prefabs/SceneHierarchyObject.cs +++ b/Source/AssetRipper.Processing/Prefabs/SceneHierarchyObject.cs @@ -87,7 +87,7 @@ public sealed class SceneHierarchyObject : GameObjectHierarchyObject, INamed sceneHierarchy.GameObjects.Add(gameObject); break; case IMonoBehaviour monoBehaviour: - if (monoBehaviour.IsSceneObject()) + if (monoBehaviour.IsComponentOnGameObject()) { sceneHierarchy.Components.Add(monoBehaviour); } diff --git a/Source/AssetRipper.Processing/Scenes/SceneHelpers.cs b/Source/AssetRipper.Processing/Scenes/SceneHelpers.cs index 8c20973af..0048e7baf 100644 --- a/Source/AssetRipper.Processing/Scenes/SceneHelpers.cs +++ b/Source/AssetRipper.Processing/Scenes/SceneHelpers.cs @@ -50,7 +50,7 @@ namespace AssetRipper.Processing.Scenes { IGameObject => true, ILevelGameManager => true, - IMonoBehaviour monoBeh => monoBeh.IsSceneObject(), + IMonoBehaviour monoBeh => monoBeh.IsComponentOnGameObject(), IComponent => true, IPrefabInstance => true, _ => false, diff --git a/Source/AssetRipper.SourceGenerated.Extensions/MonoBehaviourExtensions.cs b/Source/AssetRipper.SourceGenerated.Extensions/MonoBehaviourExtensions.cs index 2194f2484..40466d419 100644 --- a/Source/AssetRipper.SourceGenerated.Extensions/MonoBehaviourExtensions.cs +++ b/Source/AssetRipper.SourceGenerated.Extensions/MonoBehaviourExtensions.cs @@ -6,14 +6,9 @@ namespace AssetRipper.SourceGenerated.Extensions; public static class MonoBehaviourExtensions { /// - /// Does this MonoBehaviour belongs to scene/prefab hierarchy? In other words, is a non-null pptr? + /// Does this MonoBehaviour belong to scene/prefab hierarchy? In other words, is a non-null pptr? /// - public static bool IsSceneObject(this IMonoBehaviour monoBehaviour) => !monoBehaviour.GameObject.IsNull(); - - /// - /// Does this MonoBehaviour have a name? - /// - public static bool IsScriptableObject(this IMonoBehaviour monoBehaviour) => !monoBehaviour.Name.IsEmpty; + public static bool IsComponentOnGameObject(this IMonoBehaviour monoBehaviour) => !monoBehaviour.GameObject.IsNull(); public static bool TryGetScript(this IMonoBehaviour monoBehaviour, [NotNullWhen(true)] out IMonoScript? script) { diff --git a/Source/AssetRipper.SourceGenerated.Extensions/UnityVersionExtensions.cs b/Source/AssetRipper.SourceGenerated.Extensions/UnityVersionExtensions.cs new file mode 100644 index 000000000..7af78de9a --- /dev/null +++ b/Source/AssetRipper.SourceGenerated.Extensions/UnityVersionExtensions.cs @@ -0,0 +1,9 @@ +namespace AssetRipper.SourceGenerated.Extensions; + +public static class UnityVersionExtensions +{ + extension(UnityVersion) + { + public static UnityVersion V_2022 => new UnityVersion(2022); + } +} diff --git a/Source/AssetRipper.Tests/ExportTests.cs b/Source/AssetRipper.Tests/ExportTests.cs new file mode 100644 index 000000000..94ab59a5b --- /dev/null +++ b/Source/AssetRipper.Tests/ExportTests.cs @@ -0,0 +1,54 @@ +using AssetRipper.Assets.Bundles; +using AssetRipper.Assets.Collections; +using AssetRipper.Export.UnityProjects; +using AssetRipper.Import.Structure.Assembly.Managers; +using AssetRipper.IO.Files; +using AssetRipper.Primitives; +using AssetRipper.Processing; +using AssetRipper.SourceGenerated.Classes.ClassID_114; +using AssetRipper.SourceGenerated.Extensions; +using NUnit.Framework.Internal; + +namespace AssetRipper.Tests; + +internal class ExportTests +{ + [Test] + public void NamedScriptableObjectIsExported() + { + ProcessedAssetCollection collection = AssetCreator.CreateCollection(UnityVersion.V_2022); + + IMonoBehaviour monoBehaviour = collection.CreateMonoBehaviour(); + monoBehaviour.Name = "Name"; + + VirtualFileSystem fileSystem = new(); + + Export(collection, "output", fileSystem); + + Assert.That(fileSystem.File.Exists("/output/ExportedProject/Assets/MonoBehaviour/Name.asset")); + } + + [Test] + public void NamelessScriptableObjectIsExported() + { + ProcessedAssetCollection collection = AssetCreator.CreateCollection(UnityVersion.V_2022); + + collection.CreateMonoBehaviour(); + + VirtualFileSystem fileSystem = new(); + + Export(collection, "output", fileSystem); + + Assert.That(fileSystem.File.Exists("/output/ExportedProject/Assets/MonoBehaviour/MonoBehaviour.asset")); + } + + private static void Export(ProcessedAssetCollection collection, string outputPath, VirtualFileSystem fileSystem) + { + new ExportHandler(new()).Export(CreateGameData(collection), outputPath, fileSystem); + } + + private static GameData CreateGameData(ProcessedAssetCollection collection) + { + return new((GameBundle)collection.Bundle, collection.Version, new BaseManager((s) => { }), null); + } +}