diff --git a/Packages/net.fushizen.modular-avatar/Editor/AvatarProcessor.cs b/Packages/net.fushizen.modular-avatar/Editor/AvatarProcessor.cs index 7480733b..0aa62054 100644 --- a/Packages/net.fushizen.modular-avatar/Editor/AvatarProcessor.cs +++ b/Packages/net.fushizen.modular-avatar/Editor/AvatarProcessor.cs @@ -23,9 +23,12 @@ */ using System; +using System.IO; using UnityEditor; using UnityEngine; +using VRC.SDK3.Avatars.Components; using VRC.SDKBase.Editor.BuildPipeline; +using Object = UnityEngine.Object; namespace net.fushizen.modular_avatar.core.editor { @@ -41,6 +44,34 @@ namespace net.fushizen.modular_avatar.core.editor EditorApplication.playModeStateChanged += OnPlayModeStateChanged; } + [MenuItem("Tools/Modular Avatar/Apply to current avatar", false)] + private static void ApplyToCurrentAvatar() + { + var avatar = Selection.activeGameObject; + if (avatar == null || avatar.GetComponent() == null) return; + var savePath = "Assets/ModularAvatarOutput/" + avatar.name; + + int extension = 0; + + while (File.Exists(savePath) || Directory.Exists(savePath)) + { + savePath = savePath + " " + (++extension); + } + + try + { + Util.OverridePath = savePath; + + avatar = Object.Instantiate(avatar); + avatar.transform.position += Vector3.forward * 2; + ProcessAvatar(avatar); + } + finally + { + Util.OverridePath = null; + } + } + private static void OnPlayModeStateChanged(PlayModeStateChange obj) { if (obj == PlayModeStateChange.EnteredEditMode) diff --git a/Packages/net.fushizen.modular-avatar/Editor/Util.cs b/Packages/net.fushizen.modular-avatar/Editor/Util.cs index 031e59ee..a021a3f8 100644 --- a/Packages/net.fushizen.modular-avatar/Editor/Util.cs +++ b/Packages/net.fushizen.modular-avatar/Editor/Util.cs @@ -22,6 +22,7 @@ * SOFTWARE. */ +using JetBrains.Annotations; using UnityEditor; using UnityEditor.Animations; using UnityEngine; @@ -45,6 +46,8 @@ namespace net.fushizen.modular_avatar.core.editor private const string generatedAssetsSubdirectory = "999_Modular_Avatar_Generated"; private const string generatedAssetsPath = "Assets/" + generatedAssetsSubdirectory; + [CanBeNull] public static string OverridePath; + static Util() { RuntimeUtil.delayCall = (cb) => EditorApplication.delayCall += cb.Invoke; @@ -61,6 +64,7 @@ namespace net.fushizen.modular_avatar.core.editor { controller = new AnimatorController(); } + AssetDatabase.CreateAsset(controller, GenerateAssetPath()); return controller; @@ -73,12 +77,20 @@ namespace net.fushizen.modular_avatar.core.editor private static string GetGeneratedAssetsFolder() { - if (!AssetDatabase.IsValidFolder(generatedAssetsPath)) + var path = OverridePath ?? generatedAssetsPath; + + var pathParts = path.Split('/'); + + for (int i = 1; i < pathParts.Length; i++) { - AssetDatabase.CreateFolder("Assets", generatedAssetsSubdirectory); + var subPath = string.Join("/", pathParts, 0, i + 1); + if (!AssetDatabase.IsValidFolder(subPath)) + { + AssetDatabase.CreateFolder(string.Join("/", pathParts, 0, i), pathParts[i]); + } } - return generatedAssetsPath; + return path; } internal static void DeleteTemporaryAssets()