ui adjustments; added toggle creation shortcuts (#975)

* ui: adjustments to reactive object UI

* ui: toggle creation shortcuts
This commit is contained in:
bd_ 2024-08-10 19:16:57 -07:00 committed by GitHub
parent d998763fbe
commit 6b99b763a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 198 additions and 17 deletions

View File

@ -2,6 +2,8 @@
xmlns:ma="nadena.dev.modular_avatar.core.editor">
<ui:VisualElement name="root-box">
<ui:VisualElement name="group-box">
<ed:PropertyField binding-path="m_inverted" label="reactive_object.inverse" class="ndmf-tr"/>
<ui:VisualElement name="ListViewContainer">
<ui:ListView virtualization-method="DynamicHeight"
reorder-mode="Animated"
@ -17,8 +19,6 @@
</ui:VisualElement>
</ui:VisualElement>
<ed:PropertyField binding-path="m_inverted"/>
<ma:LanguageSwitcherElement/>
</ui:VisualElement>
</UXML>

View File

@ -32,4 +32,16 @@
#f-material-index-int {
display: none;
}
#f-material {
flex-grow: 1;
}
.horizontal > Label {
align-self: center;
}
#f-object > * {
margin-left: 0;
}

View File

@ -28,9 +28,43 @@ namespace nadena.dev.modular_avatar.core.editor.ShapeChanger
var f_material_index = uxml.Q<DropdownField>("f-material-index");
var f_object = uxml.Q<PropertyField>("f-object");
f_object.RegisterValueChangeCallback(evt => { UpdateMaterialDropdown(); });
var f_object = uxml.Q<ObjectField>("f-object");
f_object.objectType = typeof(Renderer);
f_object.allowSceneObjects = true;
var f_target_object = uxml.Q<ObjectField>("f-obj-target-object");
var f_reference_path = uxml.Q<TextField>("f-obj-ref-path");
f_object.RegisterValueChangedCallback(evt =>
{
var gameObj = (evt.newValue as Renderer)?.gameObject;
if (gameObj == null)
{
f_target_object.value = null;
f_reference_path.value = "";
}
else
{
var path = RuntimeUtil.AvatarRootPath(gameObj);
f_reference_path.value = path;
if (path == "")
{
f_target_object.value = null;
}
else
{
f_target_object.value = gameObj;
}
}
EditorApplication.delayCall += UpdateMaterialDropdown;
});
UpdateMaterialDropdown();
f_target_object.RegisterValueChangedCallback(_ => UpdateVisualTarget());
f_reference_path.RegisterValueChangedCallback(_ => UpdateVisualTarget());
// Link dropdown to material index field
var f_material_index_int = uxml.Q<IntegerField>("f-material-index-int");
@ -49,6 +83,23 @@ namespace nadena.dev.modular_avatar.core.editor.ShapeChanger
return uxml;
void UpdateVisualTarget()
{
var targetObject = AvatarObjectReference.Get(property.FindPropertyRelative("Object"));
Renderer targetRenderer;
try
{
targetRenderer = targetObject?.GetComponent<Renderer>();
}
catch (MissingComponentException e)
{
targetRenderer = null;
}
f_object.SetValueWithoutNotify(targetRenderer);
}
void UpdateMaterialDropdown()
{
var toggledObject = AvatarObjectReference.Get(property.FindPropertyRelative("Object"));

View File

@ -1,10 +1,19 @@
<UXML xmlns:ui="UnityEngine.UIElements" xmlns:ed="UnityEditor.UIElements">
<ui:VisualElement class="toggled-object-editor">
<ui:VisualElement class="horizontal">
<ed:PropertyField binding-path="Object" label="" name="f-object" class="f-object"/>
<!--<ed:PropertyField binding-path="Object" label="" name="f-object" class="f-object"/>-->
<ed:ObjectField label="" name="f-object" class="f-object"/>
<ui:DropdownField name="f-material-index" binding-path="MaterialIndex"/>
<ed:IntegerField binding-path="MaterialIndex" name="f-material-index-int"/>
<ui:VisualElement style="display:none">
<ui:TextField binding-path="Object.referencePath" label="" name="f-obj-ref-path"/>
<ed:ObjectField name="f-obj-target-object" binding-path="Object.targetObject"/>
<ed:IntegerField binding-path="MaterialIndex" name="f-material-index-int"/>
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement class="horizontal">
<ui:Label text="reactive_object.material-setter.set-to" class="ndmf-tr"/>
<ed:PropertyField binding-path="Material" label="" name="f-material"/>
</ui:VisualElement>
<ed:PropertyField binding-path="Material" label="" name="f-material"/>
</ui:VisualElement>
</UXML>

View File

@ -206,6 +206,7 @@ namespace nadena.dev.modular_avatar.core.editor
if (source is MenuNodesUnder nodesUnder)
{
GUILayout.BeginHorizontal();
if (GUILayout.Button(G("menuitem.misc.add_item")))
{
var newChild = new GameObject();
@ -214,6 +215,29 @@ namespace nadena.dev.modular_avatar.core.editor
newChild.AddComponent<ModularAvatarMenuItem>();
Undo.RegisterCreatedObjectUndo(newChild, "Added menu item");
}
if (GUILayout.Button(G("menuitem.misc.add_toggle")))
{
var newChild = new GameObject();
newChild.name = "New toggle";
newChild.transform.SetParent(nodesUnder.root.transform, false);
var mami = newChild.AddComponent<ModularAvatarMenuItem>();
mami.Control = new VRCExpressionsMenu.Control()
{
type = VRCExpressionsMenu.Control.ControlType.Toggle,
value = 1,
};
mami.isSaved = true;
mami.isSynced = true;
newChild.AddComponent<ModularAvatarObjectToggle>();
Selection.activeObject = newChild;
Undo.RegisterCreatedObjectUndo(newChild, "Added menu toggle");
}
GUILayout.EndHorizontal();
}
}
}

View File

@ -0,0 +1,62 @@
using nadena.dev.modular_avatar.ui;
using UnityEditor;
using UnityEngine;
using VRC.SDK3.Avatars.ScriptableObjects;
namespace nadena.dev.modular_avatar.core.editor
{
internal static class ToggleCreatorShortcut
{
[MenuItem(UnityMenuItems.GameObject_CreateToggle, false, UnityMenuItems.GameObject_CreateToggleOrder)]
private static void CreateToggle()
{
var selected = Selection.activeGameObject;
if (selected == null) return;
var avatarRoot = RuntimeUtil.FindAvatarTransformInParents(selected.transform);
if (avatarRoot == null) return;
bool createInstaller = true;
Transform parent = avatarRoot;
try
{
var selectedMenuItem = selected.GetComponent<ModularAvatarMenuItem>();
if (selectedMenuItem?.Control?.type == VRCExpressionsMenu.Control.ControlType.SubMenu
&& selectedMenuItem.MenuSource == SubmenuSource.Children
)
{
parent = selected.transform;
createInstaller = false;
}
}
catch (MissingComponentException e)
{
// ignore
}
var toggle = new GameObject("New Toggle");
var objToggle = toggle.AddComponent<ModularAvatarObjectToggle>();
toggle.transform.SetParent(parent, false);
toggle.AddComponent<ModularAvatarMenuItem>().Control = new VRCExpressionsMenu.Control
{
type = VRCExpressionsMenu.Control.ControlType.Toggle,
name = "New Toggle",
value = 1,
};
if (createInstaller)
{
toggle.AddComponent<ModularAvatarMenuInstaller>();
}
Selection.activeGameObject = toggle;
EditorGUIUtility.PingObject(objToggle);
Undo.RegisterCreatedObjectUndo(toggle, "Create Toggle");
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7e15fef260544783af5ff1fd5f13acd3
timeCreated: 1723341065

View File

@ -2,6 +2,8 @@
xmlns:ma="nadena.dev.modular_avatar.core.editor">
<ui:VisualElement name="root-box">
<ui:VisualElement name="group-box">
<ed:PropertyField binding-path="m_inverted" label="reactive_object.inverse" class="ndmf-tr"/>
<ui:VisualElement name="ListViewContainer">
<ui:ListView virtualization-method="DynamicHeight"
reorder-mode="Animated"
@ -17,8 +19,6 @@
</ui:VisualElement>
</ui:VisualElement>
<ed:PropertyField binding-path="m_inverted"/>
<ma:LanguageSwitcherElement/>
</ui:VisualElement>
</UXML>

View File

@ -2,8 +2,8 @@
xmlns:ma="nadena.dev.modular_avatar.core.editor">
<ui:VisualElement name="root-box">
<ui:VisualElement name="group-box">
<ed:PropertyField binding-path="m_targetRenderer"/>
<ed:PropertyField binding-path="m_inverted"/>
<ed:PropertyField binding-path="m_targetRenderer" label="reactive_object.shape-changer.target-renderer" class="ndmf-tr"/>
<ed:PropertyField binding-path="m_inverted" label="reactive_object.inverse" class="ndmf-tr"/>
<ui:VisualElement name="ListViewContainer">
<ui:ListView virtualization-method="DynamicHeight"
@ -20,8 +20,6 @@
</ui:VisualElement>
</ui:VisualElement>
<ed:PropertyField binding-path="m_inverted"/>
<ma:LanguageSwitcherElement/>
</ui:VisualElement>
</UXML>

View File

@ -247,5 +247,8 @@
"ma_info.param_usage_ui.other_objects": "Other objects on this avatar",
"ma_info.param_usage_ui.free_space": "Unused parameter space ({0} bits)",
"ma_info.param_usage_ui.bits_template": "{0} ({1} bits)",
"ma_info.param_usage_ui.no_data": "[ NO DATA ]"
"ma_info.param_usage_ui.no_data": "[ NO DATA ]",
"reactive_object.inverse": "Inverse Condition",
"reactive_object.material-setter.set-to": "Set material to: ",
"reactive_object.shape-changer.target-renderer": "Target Renderer"
}

View File

@ -243,5 +243,8 @@
"ma_info.param_usage_ui.other_objects": "このアバター内の他のオブジェクト",
"ma_info.param_usage_ui.free_space": "未使用領域 ({0} 個のビット)",
"ma_info.param_usage_ui.bits_template": "{0} ({1} 個のビットを使用中)",
"ma_info.param_usage_ui.no_data": "[ NO DATA ]"
"ma_info.param_usage_ui.no_data": "[ NO DATA ]",
"reactive_object.inverse": "条件を反転",
"reactive_object.material-setter.set-to": "変更先のマテリアル",
"reactive_object.shape-changer.target-renderer": "操作するレンダラー"
}

View File

@ -1,5 +1,6 @@
#if MA_VRCSDK3_AVATARS
using System;
using System.Linq;
using nadena.dev.modular_avatar.core.menu;
using UnityEngine;
@ -42,6 +43,18 @@ namespace nadena.dev.modular_avatar.core
/// </summary>
public bool isDefault;
private void Reset()
{
Control = new VRCExpressionsMenu.Control();
Control.type = VRCExpressionsMenu.Control.ControlType.Toggle;
Control.value = 1;
isSaved = true;
isSynced = true;
isDefault = false;
MenuSource = SubmenuSource.Children;
}
protected override void OnValidate()
{
base.OnValidate();

View File

@ -4,9 +4,12 @@
{
internal const string GameObject_SetupOutfit = "GameObject/Modular Avatar/Setup Outfit";
internal const int GameObject_SetupOutfitOrder = -1000;
internal const string GameObject_CreateToggle = "GameObject/Modular Avatar/Create Toggle";
internal const int GameObject_CreateToggleOrder = GameObject_SetupOutfitOrder + 1;
internal const string GameObject_ManualBake = "GameObject/Modular Avatar/Manual Bake Avatar";
internal const int GameObject_ManualBakeOrder = GameObject_SetupOutfitOrder + 1;
internal const int GameObject_ManualBakeOrder = GameObject_CreateToggleOrder + 1;
// <separator>
@ -14,7 +17,7 @@
internal const int GameObject_EnableInfoOrder = -799;
internal const string GameObject_ExtractMenu = "GameObject/Modular Avatar/Extract Menu";
internal const int GameObject_ExtractMenuOrder = GameObject_EnableInfoOrder + 1;
internal const int GameObject_ExtractMenuOrder = GameObject_EnableInfoOrder + 100;