diff --git a/Packages/nadena.dev.modular-avatar/Editor/Inspector/Menu/MenuPreviewGUI.cs b/Packages/nadena.dev.modular-avatar/Editor/Inspector/Menu/MenuPreviewGUI.cs index d3879178..9fc0b23d 100644 --- a/Packages/nadena.dev.modular-avatar/Editor/Inspector/Menu/MenuPreviewGUI.cs +++ b/Packages/nadena.dev.modular-avatar/Editor/Inspector/Menu/MenuPreviewGUI.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using nadena.dev.modular_avatar.core.menu; +using static nadena.dev.modular_avatar.core.editor.Localization; using UnityEditor; using UnityEngine; using VRC.SDK3.Avatars.ScriptableObjects; @@ -168,6 +169,14 @@ namespace nadena.dev.modular_avatar.core.editor public void PushNode(MenuSource source) { + var originalSource = source; + if (source is ModularAvatarMenuGroup group) + { + // Avoid calling source.Visit as this results in an extra MenuObjectHeader + // TODO: Avoid this unnecessary header in a cleaner way? + source = new MenuNodesUnder(group.targetObject != null ? group.targetObject : group.gameObject); + } + if (source is ModularAvatarMenuItem item) { _gui.PushGuiNode(item, () => @@ -186,12 +195,24 @@ namespace nadena.dev.modular_avatar.core.editor } else { - using (new MenuObjectHeader(source as UnityEngine.Object).Scope()) + using (new MenuObjectHeader(originalSource as UnityEngine.Object).Scope()) { - if (_visited.Contains(source)) return; - _visited.Add(source); + if (_visited.Contains(originalSource)) return; + _visited.Add(originalSource); source.Visit(this); + + if (source is MenuNodesUnder nodesUnder) + { + if (GUILayout.Button(G("menuitem.misc.add_item"))) + { + var newChild = new GameObject(); + newChild.name = "New item"; + newChild.transform.SetParent(nodesUnder.root.transform, false); + newChild.AddComponent(); + Undo.RegisterCreatedObjectUndo(newChild, "Added menu item"); + } + } } } } diff --git a/Packages/nadena.dev.modular-avatar/Editor/Localization/en.json b/Packages/nadena.dev.modular-avatar/Editor/Localization/en.json index 36dfedc7..1c311c9e 100644 --- a/Packages/nadena.dev.modular-avatar/Editor/Localization/en.json +++ b/Packages/nadena.dev.modular-avatar/Editor/Localization/en.json @@ -118,5 +118,6 @@ "menuitem.prop.control_group.tooltip": "Only one toggle in a given group can be selected at the same time", "menuitem.prop.is_default": "Is Group Default", "animation_gen.duplicate_binding": "Controls from different control groups are trying to animate the same parameter. Parameter: {0}", - "animation_gen.multiple_defaults": "Multiple default menu items were found in the same control group." + "animation_gen.multiple_defaults": "Multiple default menu items were found in the same control group.", + "menuitem.misc.add_item": "Add menu item" } \ No newline at end of file diff --git a/Packages/nadena.dev.modular-avatar/Editor/Localization/ja.json b/Packages/nadena.dev.modular-avatar/Editor/Localization/ja.json index c0d33b40..4fcc194c 100644 --- a/Packages/nadena.dev.modular-avatar/Editor/Localization/ja.json +++ b/Packages/nadena.dev.modular-avatar/Editor/Localization/ja.json @@ -115,5 +115,6 @@ "menuitem.prop.control_group.tooltip": "同じグループ内では、一つのトグルしか起動できません", "menuitem.prop.is_default": "グループの初期設定にする", "animation_gen.duplicate_binding": "別々のコントロールグループから、同じパラメーターが操作されています。パラメーター:{0}", - "animation_gen.multiple_defaults": "同じコントロールグループに初期設定に指定されたメニューアイテムが複数あります。" + "animation_gen.multiple_defaults": "同じコントロールグループに初期設定に指定されたメニューアイテムが複数あります。", + "menuitem.misc.add_item": "メニューアイテムを追加" } diff --git a/Packages/nadena.dev.modular-avatar/Runtime/ModularAvatarMenuItem.cs b/Packages/nadena.dev.modular-avatar/Runtime/ModularAvatarMenuItem.cs index 051fa26b..2010e88f 100644 --- a/Packages/nadena.dev.modular-avatar/Runtime/ModularAvatarMenuItem.cs +++ b/Packages/nadena.dev.modular-avatar/Runtime/ModularAvatarMenuItem.cs @@ -24,8 +24,23 @@ namespace nadena.dev.modular_avatar.core [FormerlySerializedAs("toggleGroup")] public ControlGroup controlGroup; public bool isDefault; + protected override void OnValidate() + { + base.OnValidate(); + + if (Control == null) + { + Control = new VRCExpressionsMenu.Control(); + } + } + public override void Visit(NodeContext context) { + if (Control == null) + { + Control = new VRCExpressionsMenu.Control(); + } + var cloned = new VirtualControl(Control); cloned.subMenu = null; cloned.name = gameObject.name;