mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2025-01-30 10:12:59 +08:00
parent
5325c809a4
commit
d91c69835c
@ -33,6 +33,29 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
|
||||
private Dictionary<VRCExpressionsMenu, List<ModularAvatarMenuInstaller>> _menuInstallersMap;
|
||||
|
||||
private static Editor _cachedEditor;
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
private static void Init()
|
||||
{
|
||||
ModularAvatarMenuInstaller._openSelectMenu = OpenSelectInstallTargetMenu;
|
||||
}
|
||||
|
||||
private static void OpenSelectInstallTargetMenu(ModularAvatarMenuInstaller installer)
|
||||
{
|
||||
CreateCachedEditor(installer, typeof(MenuInstallerEditor), ref _cachedEditor);
|
||||
|
||||
var editor = (MenuInstallerEditor)_cachedEditor;
|
||||
editor.OnEnable();
|
||||
|
||||
var serializedObject = editor.serializedObject;
|
||||
var installTo = serializedObject.FindProperty(nameof(ModularAvatarMenuInstaller.installTargetMenu));
|
||||
|
||||
var root = editor.FindCommonAvatar();
|
||||
|
||||
editor.OpenSelectMenu(root, installTo);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_installer = (ModularAvatarMenuInstaller) target;
|
||||
@ -215,74 +238,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
var avatar = commonAvatar;
|
||||
if (avatar != null && InstallTargets.Count == 1 && GUILayout.Button(G("menuinstall.selectmenu")))
|
||||
{
|
||||
AvMenuTreeViewWindow.Show(avatar, _installer, menu =>
|
||||
{
|
||||
if (InstallTargets.Count != 1 || menu == InstallTargets[0]) return;
|
||||
|
||||
if (InstallTargets[0] is ModularAvatarMenuInstallTarget oldTarget && oldTarget != null)
|
||||
{
|
||||
DestroyInstallTargets();
|
||||
}
|
||||
|
||||
if (menu is ValueTuple<object, object> vt) // TODO: This should be a named type...
|
||||
{
|
||||
// Menu, ContextCallback
|
||||
menu = vt.Item1;
|
||||
}
|
||||
|
||||
if (menu is ModularAvatarMenuItem item)
|
||||
{
|
||||
if (item.MenuSource == SubmenuSource.MenuAsset)
|
||||
{
|
||||
menu = item.Control.subMenu;
|
||||
}
|
||||
else
|
||||
{
|
||||
var menuParent = item.menuSource_otherObjectChildren != null
|
||||
? item.menuSource_otherObjectChildren
|
||||
: item.gameObject;
|
||||
|
||||
menu = new MenuNodesUnder(menuParent);
|
||||
}
|
||||
}
|
||||
else if (menu is ModularAvatarMenuGroup group)
|
||||
{
|
||||
if (group.targetObject != null) menu = new MenuNodesUnder(group.targetObject);
|
||||
else menu = new MenuNodesUnder(group.gameObject);
|
||||
}
|
||||
|
||||
if (menu is VRCExpressionsMenu expMenu)
|
||||
{
|
||||
if (expMenu == avatar.expressionsMenu) installTo.objectReferenceValue = null;
|
||||
else installTo.objectReferenceValue = expMenu;
|
||||
}
|
||||
else if (menu is RootMenu)
|
||||
{
|
||||
installTo.objectReferenceValue = null;
|
||||
}
|
||||
else if (menu is MenuNodesUnder nodesUnder)
|
||||
{
|
||||
installTo.objectReferenceValue = null;
|
||||
|
||||
foreach (var target in targets.Cast<Component>().OrderBy(ObjectHierarchyOrder))
|
||||
{
|
||||
var installer = (ModularAvatarMenuInstaller) target;
|
||||
var child = new GameObject();
|
||||
Undo.RegisterCreatedObjectUndo(child, "Set install target");
|
||||
child.transform.SetParent(nodesUnder.root.transform, false);
|
||||
child.name = installer.gameObject.name;
|
||||
|
||||
var targetComponent = child.AddComponent<ModularAvatarMenuInstallTarget>();
|
||||
targetComponent.installer = installer;
|
||||
|
||||
EditorGUIUtility.PingObject(child);
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
VirtualMenu.InvalidateCaches();
|
||||
Repaint();
|
||||
});
|
||||
OpenSelectMenu(avatar, installTo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -371,6 +327,78 @@ namespace nadena.dev.modular_avatar.core.editor
|
||||
ShowLanguageUI();
|
||||
}
|
||||
|
||||
private void OpenSelectMenu(VRCAvatarDescriptor avatar, SerializedProperty installTo)
|
||||
{
|
||||
AvMenuTreeViewWindow.Show(avatar, _installer, menu =>
|
||||
{
|
||||
if (InstallTargets.Count != 1 || menu == InstallTargets[0]) return;
|
||||
|
||||
if (InstallTargets[0] is ModularAvatarMenuInstallTarget oldTarget && oldTarget != null)
|
||||
{
|
||||
DestroyInstallTargets();
|
||||
}
|
||||
|
||||
if (menu is ValueTuple<object, object> vt) // TODO: This should be a named type...
|
||||
{
|
||||
// Menu, ContextCallback
|
||||
menu = vt.Item1;
|
||||
}
|
||||
|
||||
if (menu is ModularAvatarMenuItem item)
|
||||
{
|
||||
if (item.MenuSource == SubmenuSource.MenuAsset)
|
||||
{
|
||||
menu = item.Control.subMenu;
|
||||
}
|
||||
else
|
||||
{
|
||||
var menuParent = item.menuSource_otherObjectChildren != null
|
||||
? item.menuSource_otherObjectChildren
|
||||
: item.gameObject;
|
||||
|
||||
menu = new MenuNodesUnder(menuParent);
|
||||
}
|
||||
}
|
||||
else if (menu is ModularAvatarMenuGroup group)
|
||||
{
|
||||
if (group.targetObject != null) menu = new MenuNodesUnder(group.targetObject);
|
||||
else menu = new MenuNodesUnder(group.gameObject);
|
||||
}
|
||||
|
||||
if (menu is VRCExpressionsMenu expMenu)
|
||||
{
|
||||
if (expMenu == avatar.expressionsMenu) installTo.objectReferenceValue = null;
|
||||
else installTo.objectReferenceValue = expMenu;
|
||||
}
|
||||
else if (menu is RootMenu)
|
||||
{
|
||||
installTo.objectReferenceValue = null;
|
||||
}
|
||||
else if (menu is MenuNodesUnder nodesUnder)
|
||||
{
|
||||
installTo.objectReferenceValue = null;
|
||||
|
||||
foreach (var target in targets.Cast<Component>().OrderBy(ObjectHierarchyOrder))
|
||||
{
|
||||
var installer = (ModularAvatarMenuInstaller)target;
|
||||
var child = new GameObject();
|
||||
Undo.RegisterCreatedObjectUndo(child, "Set install target");
|
||||
child.transform.SetParent(nodesUnder.root.transform, false);
|
||||
child.name = installer.gameObject.name;
|
||||
|
||||
var targetComponent = child.AddComponent<ModularAvatarMenuInstallTarget>();
|
||||
targetComponent.installer = installer;
|
||||
|
||||
EditorGUIUtility.PingObject(child);
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
VirtualMenu.InvalidateCaches();
|
||||
Repaint();
|
||||
});
|
||||
}
|
||||
|
||||
private string ObjectHierarchyOrder(Component arg)
|
||||
{
|
||||
var list = new List<int>();
|
||||
|
@ -1,5 +1,7 @@
|
||||
#if MA_VRCSDK3_AVATARS
|
||||
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using UnityEngine;
|
||||
using VRC.SDK3.Avatars.ScriptableObjects;
|
||||
|
||||
@ -12,6 +14,16 @@ namespace nadena.dev.modular_avatar.core
|
||||
public VRCExpressionsMenu menuToAppend;
|
||||
public VRCExpressionsMenu installTargetMenu;
|
||||
|
||||
internal static Action<ModularAvatarMenuInstaller> _openSelectMenu = _ => { };
|
||||
|
||||
/// <summary>
|
||||
/// Opens the "Select Menu" window, as if the user had clicked this button in the inspector.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public void OpenSelectMenu()
|
||||
{
|
||||
_openSelectMenu(this);
|
||||
}
|
||||
|
||||
// ReSharper disable once Unity.RedundantEventFunction
|
||||
void Start()
|
||||
|
Loading…
Reference in New Issue
Block a user