diff --git a/Editor/UI/GeneratedAssetsEditor.cs b/Editor/UI/GeneratedAssetsEditor.cs
new file mode 100644
index 00000000..66e23156
--- /dev/null
+++ b/Editor/UI/GeneratedAssetsEditor.cs
@@ -0,0 +1,287 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using nadena.dev.ndmf.runtime;
+using UnityEditor;
+using UnityEngine;
+using VRC.SDK3.Avatars.ScriptableObjects;
+using Object = UnityEngine.Object;
+
+namespace nadena.dev.ndmf.ui
+{
+ [CustomEditor(typeof(GeneratedAssets))]
+ class MAAssetBundleEditor : Editor
+ {
+ public override void OnInspectorGUI()
+ {
+ if (GUILayout.Button("Unpack"))
+ {
+ foreach (var target in targets)
+ {
+ GeneratedAssets bundle = (GeneratedAssets) target;
+ bundle.Extract();
+ }
+ }
+ }
+ }
+
+ public static class GeneratedAssetBundleExtension
+ {
+ ///
+ /// Extracts a generated assets bundle into separate asset files
+ ///
+ ///
+ public static void Extract(this GeneratedAssets bundle)
+ {
+ new GeneratedAssetBundleExtractor(bundle).Extract();
+ }
+ }
+
+ internal class GeneratedAssetBundleExtractor
+ {
+ private static readonly ISet RootAssets = new HashSet()
+ {
+ typeof(Mesh),
+ typeof(AnimationClip),
+ typeof(RuntimeAnimatorController),
+ typeof(VRCExpressionParameters),
+ typeof(VRCExpressionsMenu),
+ };
+
+ private Dictionary _assets;
+ private GeneratedAssets Bundle;
+ private HashSet