ui: add action blendshape editor

This commit is contained in:
bd_ 2023-05-05 17:09:34 +09:00
parent 1175e43bfd
commit 5a36db7b7f
3 changed files with 202 additions and 0 deletions

View File

@ -112,6 +112,17 @@ namespace nadena.dev.modular_avatar.core.editor
if (_columns.Count == 0)
{
if (_elementWidth < 1.0f)
{
if (rect.width < 1.0f)
{
return;
}
_elementWidth = rect.width - 10f;
Repaint();
}
_columnPos = 0;
_remainingWidth = _elementWidth;
OnGenerateColumns(_elementWidth);

View File

@ -0,0 +1,188 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace nadena.dev.modular_avatar.core.editor
{
[CustomEditor(typeof(ActionBlendshape))]
internal class ActionBlendshapeEditor : MAEditorBase
{
private ColumnReorderableList _list;
private SerializedProperty _listProp;
private Dictionary<Mesh, string[]> _blendshapeNamesCache = new Dictionary<Mesh, string[]>();
private Transform _avatarRoot;
private void OnEnable()
{
_listProp = serializedObject.FindProperty(nameof(ActionBlendshape.Blendshapes));
_list = new ColumnReorderableList(
serializedObject,
_listProp,
true,
true,
true,
true
);
_list.Repaint = Repaint;
_list.OnGenerateColumns = BuildColumns;
_list.onRemoveCallback += OnRemoveElement;
_list.onAddCallback += OnAddElement;
_list.elementHeight += 2;
if (targets.Length == 1)
{
_avatarRoot = RuntimeUtil.FindAvatarInParents(((Component) target).transform).transform;
}
}
private void OnAddElement(ReorderableList list)
{
_listProp.arraySize++;
}
private void OnRemoveElement(ReorderableList reorderableList)
{
if (reorderableList.index < _listProp.arraySize)
{
_listProp.DeleteArrayElementAtIndex(reorderableList.index);
}
}
private void RenderBlendshapeColumn(Rect rect, SerializedProperty elem)
{
var prop_obj = elem.FindPropertyRelative(nameof(ActionBlendshape.BlendshapeSpec.target))
?.FindPropertyRelative(nameof(AvatarObjectReference.referencePath));
var prop_blendshape = elem.FindPropertyRelative(nameof(ActionBlendshape.BlendshapeSpec.blendshape));
SkinnedMeshRenderer targetRenderer = null;
if (_avatarRoot != null)
{
var targetObj = _avatarRoot.Find(prop_obj.stringValue);
if (targetObj != null)
{
targetRenderer = targetObj.GetComponent<SkinnedMeshRenderer>();
}
}
if (targetRenderer == null || targetRenderer.sharedMesh == null)
{
EditorGUI.PropertyField(rect, prop_blendshape, GUIContent.none);
return;
}
var sharedMesh = targetRenderer.sharedMesh;
if (!_blendshapeNamesCache.TryGetValue(sharedMesh, out var names))
{
names = new string[sharedMesh.blendShapeCount + 1];
names[0] = "";
for (var i = 1; i < sharedMesh.blendShapeCount; i++)
{
names[i] = sharedMesh.GetBlendShapeName(i - 1);
}
_blendshapeNamesCache[sharedMesh] = names;
}
var blendshapeIndex = Array.IndexOf(names, prop_blendshape.stringValue);
var style = new GUIStyle(EditorStyles.popup);
EditorGUI.BeginChangeCheck();
blendshapeIndex = EditorGUI.Popup(rect, blendshapeIndex, names, style);
if (EditorGUI.EndChangeCheck())
{
prop_blendshape.stringValue = names[blendshapeIndex];
}
else if (blendshapeIndex < 0)
{
var toDisplay = prop_blendshape.stringValue;
UpdateAllStates(style, s => s.textColor = Color.Lerp(s.textColor, Color.red, 0.85f));
GUI.Label(rect, toDisplay, style);
}
}
private static void UpdateAllStates(GUIStyle style, Action<GUIStyleState> action)
{
var state = style.normal;
action(state);
style.normal = state;
state = style.hover;
action(state);
style.hover = state;
state = style.active;
action(state);
style.active = state;
state = style.focused;
action(state);
style.focused = state;
state = style.onNormal;
action(state);
style.onNormal = state;
state = style.onHover;
action(state);
style.onHover = state;
state = style.onActive;
action(state);
style.onActive = state;
state = style.onFocused;
action(state);
style.onFocused = state;
}
private void BuildColumns(float width)
{
GUIContent testValueContent = new GUIContent("100");
var valueFieldSize = EditorStyles.textField.CalcSize(testValueContent);
var remainingWidth = width - valueFieldSize.x - _list.margin;
var fieldWidth = (remainingWidth - _list.margin) / 2;
_list.AddColumn(fieldWidth, "action.blendshape.header.object", (rect, elem) =>
{
var targetProp = elem.FindPropertyRelative(nameof(ActionBlendshape.BlendshapeSpec.target));
EditorGUI.PropertyField(rect, targetProp, GUIContent.none);
});
_list.AddColumn(fieldWidth, "action.blendshape.header.blendshape", RenderBlendshapeColumn);
_list.AddColumn(valueFieldSize.x, "action.blendshape.header.value", (rect, elem) =>
{
var valueProp = elem.FindPropertyRelative(nameof(ActionBlendshape.BlendshapeSpec.value));
EditorGUI.PropertyField(rect, valueProp, GUIContent.none);
});
}
protected override void OnInnerInspectorGUI()
{
serializedObject.Update();
Rect rect = GUILayoutUtility.GetRect(
10f,
_list.headerHeight + _list.elementHeight * Math.Max(1, _list.serializedProperty.arraySize) +
_list.footerHeight,
GUILayout.ExpandWidth(true)
);
_list.DoList(rect);
EditorGUILayout.Space(8);
Localization.ShowLanguageUI();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 78859e260e8e426bb4673c9077ed5d7b
timeCreated: 1683272729