Ensure scriptable objects with an empty name get exported

* Resolves #1795
* Resolves #831
* Closes #1069
This commit is contained in:
ds5678 2025-05-31 22:41:36 -07:00
parent 0cda960407
commit 4e771ef41b
7 changed files with 74 additions and 16 deletions

View File

@ -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");

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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,

View File

@ -6,14 +6,9 @@ namespace AssetRipper.SourceGenerated.Extensions;
public static class MonoBehaviourExtensions
{
/// <summary>
/// Does this MonoBehaviour belongs to scene/prefab hierarchy? In other words, is <see cref="IMonoBehaviour.GameObject"/> a non-null pptr?
/// Does this MonoBehaviour belong to scene/prefab hierarchy? In other words, is <see cref="IMonoBehaviour.GameObject"/> a non-null pptr?
/// </summary>
public static bool IsSceneObject(this IMonoBehaviour monoBehaviour) => !monoBehaviour.GameObject.IsNull();
/// <summary>
/// Does this MonoBehaviour have a name?
/// </summary>
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)
{

View File

@ -0,0 +1,9 @@
namespace AssetRipper.SourceGenerated.Extensions;
public static class UnityVersionExtensions
{
extension(UnityVersion)
{
public static UnityVersion V_2022 => new UnityVersion(2022);
}
}

View File

@ -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);
}
}