From 4f9ccc75c598758d6e6ac375ac692bc87cabbf00 Mon Sep 17 00:00:00 2001 From: bd_ Date: Sat, 15 Oct 2022 18:43:21 -0700 Subject: [PATCH] UI for sync mode configuration --- .../Inspector/AvatarParametersEditor.cs | 124 ++++++++++++++++-- .../Editor/ParameterPolicy.cs | 21 ++- .../Runtime/ModularAvatarParameters.cs | 12 ++ 3 files changed, 144 insertions(+), 13 deletions(-) diff --git a/Packages/net.fushizen.modular-avatar/Editor/Inspector/AvatarParametersEditor.cs b/Packages/net.fushizen.modular-avatar/Editor/Inspector/AvatarParametersEditor.cs index 0a4c6614..3a3dc0b6 100644 --- a/Packages/net.fushizen.modular-avatar/Editor/Inspector/AvatarParametersEditor.cs +++ b/Packages/net.fushizen.modular-avatar/Editor/Inspector/AvatarParametersEditor.cs @@ -77,6 +77,9 @@ namespace net.fushizen.modular_avatar.core.editor internalParameter = false, isPrefix = param.IsPrefix, nameOrPrefix = param.OriginalName, + syncType = param.syncType, + defaultValue = param.defaultValue, + saved = param.saved, remapTo = "", }; @@ -172,20 +175,29 @@ namespace net.fushizen.modular_avatar.core.editor private float ElementHeight(int index) { + float baseHeight = _devMode ? elemHeight * 2 : elemHeight; + + var param = GetParamByIndex(_selectedIndices[index]); + var syncMode = param.FindPropertyRelative(nameof(ParameterConfig.syncType)); + if (syncMode.enumValueIndex != (int) ParameterSyncType.NotSynced) + { + baseHeight += elemHeight; + } + if (_selectedIndices[index] == -1) { - return elemHeight * 2; + return elemHeight + baseHeight; } else { - return elemHeight; + return baseHeight; } } private void DrawAutodetectHeader(ref Rect rect) { Rect top = rect; - top.height /= 2; + top.height = elemHeight; Rect bottom = rect; bottom.y += top.height; bottom.height -= top.height; @@ -217,15 +229,24 @@ namespace net.fushizen.modular_avatar.core.editor DrawAutodetectHeader(ref rect); } - var margin = 20; - var halfMargin = margin / 2; - var leftHalf = new Rect(rect.x, rect.y, rect.width / 2 - halfMargin, rect.height); - var rightHalf = new Rect(rect.x + leftHalf.width + halfMargin, rect.y, leftHalf.width, rect.height); - var nameOrPrefix = elem.FindPropertyRelative(nameof(ParameterConfig.nameOrPrefix)); var remapTo = elem.FindPropertyRelative(nameof(ParameterConfig.remapTo)); var internalParameter = elem.FindPropertyRelative(nameof(ParameterConfig.internalParameter)); var isPrefix = elem.FindPropertyRelative(nameof(ParameterConfig.isPrefix)); + var syncType = elem.FindPropertyRelative(nameof(ParameterConfig.syncType)); + + var isSynced = syncType.enumValueIndex != (int) ParameterSyncType.NotSynced; + + var margin = 20; + var halfMargin = margin / 2; + var leftHalf = new Rect(rect.x, rect.y, rect.width / 2 - halfMargin, elemHeight); + var rightHalf = new Rect(rect.x + leftHalf.width + halfMargin, rect.y, leftHalf.width, elemHeight); + var rightHalfTop = new Rect(rect.x + leftHalf.width + halfMargin, rect.y, leftHalf.width, elemHeight); + var rightHalfSyncControlField = rightHalfTop; + rightHalfSyncControlField.y += _devMode ? elemHeight : 0; + + var rightHalfDefaultValue = rightHalfSyncControlField; + rightHalfDefaultValue.y += elemHeight; var indentLevel = EditorGUI.indentLevel; try @@ -238,14 +259,29 @@ namespace net.fushizen.modular_avatar.core.editor EditorGUI.PropertyField(leftHalf, nameOrPrefix, GUIContent.none); var toggleInternalWidth = EditorStyles.toggle.CalcSize(new GUIContent("Internal")).x; - var toggleInternalRect = new Rect(rightHalf.x, rightHalf.y, toggleInternalWidth, rightHalf.height); + var toggleInternalRect = new Rect(rightHalfTop.x, rightHalfTop.y, toggleInternalWidth, + rightHalfTop.height); internalParameter.boolValue = EditorGUI.ToggleLeft(toggleInternalRect, "Internal", internalParameter.boolValue); - var isPrefixRect = new Rect(rightHalf.x + toggleInternalWidth + halfMargin, rightHalf.y, - rightHalf.width - toggleInternalWidth - halfMargin, rightHalf.height); + var isPrefixRect = new Rect(rightHalfTop.x + toggleInternalWidth + halfMargin, rightHalfTop.y, + rightHalfTop.width - toggleInternalWidth - halfMargin, rightHalfTop.height); isPrefix.boolValue = EditorGUI.ToggleLeft(isPrefixRect, "PhysBones Prefix", isPrefix.boolValue); + + var syncedContent = new GUIContent("Sync mode "); + var labelSize = EditorStyles.label.CalcSize(syncedContent); + var syncedWidth = labelSize.x; + + var syncedRect = new Rect(rightHalfSyncControlField.x, rightHalfSyncControlField.y, syncedWidth, + rightHalfSyncControlField.height); + + EditorGUI.LabelField(syncedRect, syncedContent); + + rightHalfSyncControlField.x += syncedWidth; + rightHalfSyncControlField.width -= syncedWidth; + + EditorGUI.PropertyField(rightHalfSyncControlField, syncType, GUIContent.none); } else { @@ -268,6 +304,72 @@ namespace net.fushizen.modular_avatar.core.editor } } + if (isSynced) + { + var saved = elem.FindPropertyRelative(nameof(ParameterConfig.saved)); + + var savedContents = new GUIContent("Saved"); + var savedStyle = EditorStyles.toggle; + var savedSize = savedStyle.CalcSize(savedContents); + var savedLabelWidth = EditorStyles.label.CalcSize(savedContents).x; + var checkboxPad = EditorStyles.toggle.margin.right; + + var savedPos = rightHalfDefaultValue; + savedPos.width = savedSize.x + checkboxPad * 2; + rightHalfDefaultValue.x += savedPos.width; + rightHalfDefaultValue.width -= savedPos.width; + //savedPos.x -= savedSize.x + checkboxPad * 2; + + + EditorGUI.LabelField(savedPos, savedContents); + savedPos.x += savedLabelWidth + checkboxPad; + savedPos.width -= savedLabelWidth - checkboxPad * 2; + saved.boolValue = EditorGUI.Toggle(savedPos, saved.boolValue); + + var defaultValueProp = elem.FindPropertyRelative(nameof(ParameterConfig.defaultValue)); + var label = new GUIContent("Default value "); + var labelSize = EditorStyles.label.CalcSize(label); + var labelWidth = labelSize.x; + + var labelRect = new Rect(rightHalfDefaultValue.x, rightHalfDefaultValue.y, labelWidth, + rightHalfDefaultValue.height); + + EditorGUI.LabelField(labelRect, label); + + rightHalfDefaultValue.x += labelWidth; + rightHalfDefaultValue.width -= labelWidth; + + switch ((ParameterSyncType) syncType.enumValueIndex) + { + case ParameterSyncType.Int: + { + int val = Mathf.RoundToInt(defaultValueProp.floatValue); + val = EditorGUI.IntField(rightHalfDefaultValue, val); + defaultValueProp.floatValue = val; + break; + } + case ParameterSyncType.Float: + { + float val = defaultValueProp.floatValue; + val = EditorGUI.FloatField(rightHalfDefaultValue, val); + defaultValueProp.floatValue = val; + break; + } + + case ParameterSyncType.Bool: + { + bool val = defaultValueProp.floatValue > 0.1f; + val = EditorGUI.Toggle(rightHalfDefaultValue, val); + defaultValueProp.floatValue = val ? 1.0f : 0.0f; + break; + } + + default: + // Maybe we just changed sync mode? + break; + } + } + if (EditorGUI.EndChangeCheck() && index < 0) { var target = (ModularAvatarParameters) this.target; diff --git a/Packages/net.fushizen.modular-avatar/Editor/ParameterPolicy.cs b/Packages/net.fushizen.modular-avatar/Editor/ParameterPolicy.cs index f985dc82..f064459f 100644 --- a/Packages/net.fushizen.modular-avatar/Editor/ParameterPolicy.cs +++ b/Packages/net.fushizen.modular-avatar/Editor/ParameterPolicy.cs @@ -14,6 +14,9 @@ namespace net.fushizen.modular_avatar.core.editor { public string OriginalName; public bool IsPrefix; + public ParameterSyncType syncType; + public float defaultValue; + public bool saved; public string MapKey => IsPrefix ? OriginalName + "*" : OriginalName; } @@ -229,6 +232,16 @@ namespace net.fushizen.modular_avatar.core.editor var dictKey = map.nameOrPrefix + (map.isPrefix ? "*" : ""); if (!parameters.ContainsKey(dictKey)) { + if (map.internalParameter || map.syncType == ParameterSyncType.NotSynced) continue; + var param = new DetectedParameter() + { + OriginalName = map.remapTo, + IsPrefix = map.isPrefix, + syncType = map.syncType, + defaultValue = map.defaultValue, + saved = map.saved, + }; + newParams[param.MapKey] = param; continue; } @@ -236,10 +249,14 @@ namespace net.fushizen.modular_avatar.core.editor { parameters.Remove(dictKey); } - else if (!string.IsNullOrWhiteSpace(map.remapTo)) + else { + var exposedName = !string.IsNullOrWhiteSpace(map.remapTo) ? map.remapTo : map.nameOrPrefix; var param = parameters[dictKey]; - param.OriginalName = map.remapTo; + param.OriginalName = exposedName; + param.syncType = map.syncType; + param.defaultValue = map.defaultValue; + param.saved = map.saved; newParams[param.MapKey] = param; parameters.Remove(dictKey); } diff --git a/Packages/net.fushizen.modular-avatar/Runtime/ModularAvatarParameters.cs b/Packages/net.fushizen.modular-avatar/Runtime/ModularAvatarParameters.cs index 8313813f..f123c9b1 100644 --- a/Packages/net.fushizen.modular-avatar/Runtime/ModularAvatarParameters.cs +++ b/Packages/net.fushizen.modular-avatar/Runtime/ModularAvatarParameters.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using UnityEngine; +using VRC.SDK3.Avatars.ScriptableObjects; namespace net.fushizen.modular_avatar.core { @@ -10,6 +11,17 @@ namespace net.fushizen.modular_avatar.core public string nameOrPrefix; public string remapTo; public bool internalParameter, isPrefix; + public ParameterSyncType syncType; + public float defaultValue; + public bool saved; + } + + public enum ParameterSyncType + { + NotSynced, + Int, + Float, + Bool, } [DisallowMultipleComponent]