ScriptableObject grouping for PostProcessProfile

This commit is contained in:
ds5678 2025-02-05 17:18:58 -08:00
parent 54664db447
commit 481a067bb2
6 changed files with 68 additions and 24 deletions

View File

@ -12,7 +12,7 @@ using AssetRipper.Processing.AnimatorControllers;
using AssetRipper.Processing.Assemblies;
using AssetRipper.Processing.AudioMixers;
using AssetRipper.Processing.Editor;
using AssetRipper.Processing.Playable;
using AssetRipper.Processing.ScriptableObject;
using AssetRipper.Processing.PrefabOutlining;
using AssetRipper.Processing.Scenes;
using AssetRipper.Processing.Textures;
@ -75,7 +75,7 @@ public class ExportHandler
yield return new LightingDataProcessor();//Needs to be after static mesh separation
yield return new PrefabProcessor();
yield return new SpriteProcessor();
yield return new PlayableProcessor();
yield return new ScriptableObjectProcessor();
}
public void Export(GameData gameData, string outputPath)

View File

@ -1,17 +1,17 @@
using AssetRipper.Assets;
using AssetRipper.Processing.Playable;
using AssetRipper.Processing.ScriptableObject;
using AssetRipper.SourceGenerated.Classes.ClassID_114;
namespace AssetRipper.Export.UnityProjects.Project;
public class PlayableAssetYamlExporter : YamlExporterBase
public class ScriptableObjectGroupExporter : YamlExporterBase
{
public override bool TryCreateCollection(IUnityObjectBase asset, [NotNullWhen(true)] out IExportCollection? exportCollection)
{
switch (asset.MainAsset)
{
case PlayableAssetGroup playableAssetGroup:
exportCollection = new PlayableAssetExportCollection(this, playableAssetGroup);
case ScriptableObjectGroup playableAssetGroup:
exportCollection = new ScriptableObjectGroupExportCollection(this, playableAssetGroup);
return true;
default:
exportCollection = null;
@ -19,10 +19,10 @@ public class PlayableAssetYamlExporter : YamlExporterBase
}
}
private sealed class PlayableAssetExportCollection : AssetsExportCollection<IMonoBehaviour>
private sealed class ScriptableObjectGroupExportCollection : AssetsExportCollection<IMonoBehaviour>
{
public PlayableAssetGroup Group { get; }
public PlayableAssetExportCollection(PlayableAssetYamlExporter exporter, PlayableAssetGroup group) : base(exporter, group.Root)
public ScriptableObjectGroup Group { get; }
public ScriptableObjectGroupExportCollection(ScriptableObjectGroupExporter exporter, ScriptableObjectGroup group) : base(exporter, group.Root)
{
Group = group;
AddAssets(group.Children);
@ -30,7 +30,7 @@ public class PlayableAssetYamlExporter : YamlExporterBase
protected override string GetExportExtension(IUnityObjectBase asset)
{
return "playable";
return Group.FileExtension ?? base.GetExportExtension(asset);
}
public override IEnumerable<IUnityObjectBase> Assets => base.Assets.Prepend(Group);

View File

@ -16,7 +16,7 @@ using AssetRipper.Export.UnityProjects.Textures;
using AssetRipper.Import.AssetCreation;
using AssetRipper.Import.Structure.Assembly.Managers;
using AssetRipper.Mining.PredefinedAssets;
using AssetRipper.Processing.Playable;
using AssetRipper.Processing.ScriptableObject;
using AssetRipper.Processing.Textures;
using AssetRipper.SourceGenerated;
using AssetRipper.SourceGenerated.Classes.ClassID_1;
@ -171,9 +171,9 @@ partial class ProjectExporter
OverrideExporter<IUnityObjectBase>(new AnimatorControllerExporter());
//Playable assets
PlayableAssetYamlExporter playableAssetExporter = new();
OverrideExporter<IMonoBehaviour>(playableAssetExporter);
OverrideExporter<PlayableAssetGroup>(playableAssetExporter);
ScriptableObjectGroupExporter scriptableObjectGroupExporter = new();
OverrideExporter<IMonoBehaviour>(scriptableObjectGroupExporter);
OverrideExporter<ScriptableObjectGroup>(scriptableObjectGroupExporter);
}
//These need to be absolutely last

View File

@ -2,11 +2,11 @@
using AssetRipper.Assets.Metadata;
using AssetRipper.SourceGenerated.Classes.ClassID_114;
namespace AssetRipper.Processing.Playable;
namespace AssetRipper.Processing.ScriptableObject;
public sealed class PlayableAssetGroup : UnityObjectBase, INamed
public sealed class ScriptableObjectGroup : UnityObjectBase, INamed
{
public PlayableAssetGroup(AssetInfo assetInfo, IMonoBehaviour root) : base(assetInfo)
public ScriptableObjectGroup(AssetInfo assetInfo, IMonoBehaviour root) : base(assetInfo)
{
Root = root;
}
@ -18,6 +18,8 @@ public sealed class PlayableAssetGroup : UnityObjectBase, INamed
public Utf8String Name { get => Root.Name; set => throw new NotSupportedException(); }
public string? FileExtension { get; set; }
public void SetMainAssets()
{
MainAsset = this;

View File

@ -5,26 +5,38 @@ using AssetRipper.Import.Structure.Assembly.Serializable;
using AssetRipper.SourceGenerated.Classes.ClassID_114;
using AssetRipper.SourceGenerated.Extensions;
namespace AssetRipper.Processing.Playable;
namespace AssetRipper.Processing.ScriptableObject;
public class PlayableProcessor : IAssetProcessor
public class ScriptableObjectProcessor : IAssetProcessor
{
public void Process(GameData gameData)
{
Logger.Info(LogCategory.Processing, "Processing Playable Assets");
ProcessedAssetCollection collection = gameData.AddNewProcessedCollection("Generated Playable Asset Groups");
Logger.Info(LogCategory.Processing, "Processing Scriptable Object Groups");
ProcessedAssetCollection collection = gameData.AddNewProcessedCollection("Generated Scriptable Object Groups");
foreach (IMonoBehaviour monoBehaviour in gameData.GameBundle.FetchAssets().OfType<IMonoBehaviour>())
{
if (monoBehaviour.IsTimelineAsset())
{
PlayableAssetGroup group = collection.CreateAsset(-1, monoBehaviour, static (assetInfo, root) => new PlayableAssetGroup(assetInfo, root));
group.Children.AddRange(FindChildren(monoBehaviour));
ScriptableObjectGroup group = CreateGroup(collection, monoBehaviour);
group.FileExtension = "playable";
group.Children.AddRange(FindTimelineAssetChildren(monoBehaviour));
group.SetMainAssets();
}
else if (monoBehaviour.IsPostProcessProfile())
{
ScriptableObjectGroup group = CreateGroup(collection, monoBehaviour);
group.Children.AddRange(FindPostProcessProfileChildren(monoBehaviour));
group.SetMainAssets();
}
}
}
private static IEnumerable<IMonoBehaviour> FindChildren(IMonoBehaviour root)
private static ScriptableObjectGroup CreateGroup(ProcessedAssetCollection collection, IMonoBehaviour root)
{
return collection.CreateAsset(-1, root, static (assetInfo, root) => new ScriptableObjectGroup(assetInfo, root));
}
private static IEnumerable<IMonoBehaviour> FindTimelineAssetChildren(IMonoBehaviour root)
{
SerializableStructure? structure = LoadStructure(root);
if (structure is null)
@ -84,6 +96,31 @@ public class PlayableProcessor : IAssetProcessor
return children;
}
private static IEnumerable<IMonoBehaviour> FindPostProcessProfileChildren(IMonoBehaviour root)
{
SerializableStructure? structure = LoadStructure(root);
if (structure is null)
{
return [];
}
HashSet<IMonoBehaviour> children = [];
if (structure.TryGetField("settings", out SerializableValue settings))
{
foreach (IPPtr pptr in settings.AsAssetArray.Cast<IPPtr>())
{
if (!root.Collection.TryGetAsset(pptr.FileID, pptr.PathID, out IMonoBehaviour? child))
{
continue;
}
children.Add(child);
}
}
return children;
}
private static SerializableStructure? LoadStructure(IMonoBehaviour monoBehaviour)
{
if (monoBehaviour.Structure is SerializableStructure structure)

View File

@ -50,6 +50,11 @@ public static class MonoBehaviourExtensions
return monoBehaviour.IsType("UnityEngine.Timeline", "TimelineAsset");
}
public static bool IsPostProcessProfile(this IMonoBehaviour monoBehaviour)
{
return monoBehaviour.IsType("UnityEngine.Rendering.PostProcessing", "PostProcessProfile");
}
private static bool IsType(this IMonoBehaviour monoBehaviour, string @namespace, string name)
{
return TryGetScript(monoBehaviour, out IMonoScript? script) && script.IsType(@namespace, name);