mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-14 14:29:52 -05:00
Separate SerializedBlendShapeClipEditor
This commit is contained in:
parent
cb905a7755
commit
411bd286df
|
|
@ -9,19 +9,9 @@ namespace VRM
|
|||
[CustomEditor(typeof(BlendShapeClip))]
|
||||
public class BlendShapeClipEditor : PreviewEditor
|
||||
{
|
||||
float m_previewSlider;
|
||||
|
||||
#region for Editor
|
||||
SerializedProperty m_BlendShapeNameProp;
|
||||
SerializedProperty m_PresetProp;
|
||||
SerializedProperty m_ValuesProp;
|
||||
ReorderableList m_ValuesList;
|
||||
SerializedProperty m_MaterialValuesProp;
|
||||
ReorderableList m_MaterialValuesList;
|
||||
#endregion
|
||||
SerializedBlendShapeEditor m_serializedEditor;
|
||||
|
||||
BlendShapeClip m_target;
|
||||
bool m_changed;
|
||||
|
||||
protected override GameObject GetPrefab()
|
||||
{
|
||||
|
|
@ -41,42 +31,8 @@ namespace VRM
|
|||
|
||||
base.OnEnable();
|
||||
|
||||
m_previewSlider = 1.0f;
|
||||
Bake(m_target.Values, m_target.MaterialValues, 1.0f);
|
||||
|
||||
Bake(m_target.Values, m_target.MaterialValues, m_previewSlider);
|
||||
|
||||
m_BlendShapeNameProp = serializedObject.FindProperty("BlendShapeName");
|
||||
m_PresetProp = serializedObject.FindProperty("Preset");
|
||||
m_ValuesProp = serializedObject.FindProperty("Values");
|
||||
|
||||
m_ValuesList = new ReorderableList(serializedObject, m_ValuesProp);
|
||||
m_ValuesList.elementHeight = BlendShapeBindingHeight;
|
||||
m_ValuesList.drawElementCallback =
|
||||
(rect, index, isActive, isFocused) =>
|
||||
{
|
||||
var element = m_ValuesProp.GetArrayElementAtIndex(index);
|
||||
rect.height -= 4;
|
||||
rect.y += 2;
|
||||
if (DrawBlendShapeBinding(rect, element, PreviewSceneManager))
|
||||
{
|
||||
m_changed = true;
|
||||
}
|
||||
};
|
||||
|
||||
m_MaterialValuesProp = serializedObject.FindProperty("MaterialValues");
|
||||
m_MaterialValuesList = new ReorderableList(serializedObject, m_MaterialValuesProp);
|
||||
m_MaterialValuesList.elementHeight = MaterialValueBindingHeight;
|
||||
m_MaterialValuesList.drawElementCallback =
|
||||
(rect, index, isActive, isFocused) =>
|
||||
{
|
||||
var element = m_MaterialValuesProp.GetArrayElementAtIndex(index);
|
||||
rect.height -= 4;
|
||||
rect.y += 2;
|
||||
if (DrawMaterialValueBinding(rect, element, PreviewSceneManager))
|
||||
{
|
||||
m_changed = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
|
|
@ -88,34 +44,16 @@ namespace VRM
|
|||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
m_changed = false;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
var previewSlider = EditorGUILayout.Slider("Preview Weight", m_previewSlider, 0, 1.0f);
|
||||
if (previewSlider != m_previewSlider)
|
||||
if (m_serializedEditor == null)
|
||||
{
|
||||
m_previewSlider = previewSlider;
|
||||
m_changed = true;
|
||||
m_serializedEditor = new SerializedBlendShapeEditor(serializedObject, PreviewSceneManager);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.PropertyField(m_BlendShapeNameProp, true);
|
||||
EditorGUILayout.PropertyField(m_PresetProp, true);
|
||||
|
||||
EditorGUILayout.LabelField("BlendShapeBindings", EditorStyles.boldLabel);
|
||||
m_ValuesList.DoLayoutList();
|
||||
|
||||
EditorGUILayout.LabelField("MaterialValueBindings", EditorStyles.boldLabel);
|
||||
m_MaterialValuesList.DoLayoutList();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
if (m_changed && PreviewSceneManager != null)
|
||||
var result = m_serializedEditor.Draw();
|
||||
if (result.Changed && PreviewSceneManager != null)
|
||||
{
|
||||
PreviewSceneManager.Bake(m_target.Values, m_target.MaterialValues, m_previewSlider);
|
||||
PreviewSceneManager.Bake(m_target.Values, m_target.MaterialValues, result.Weight);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -123,202 +61,5 @@ namespace VRM
|
|||
{
|
||||
return BlendShapeKey.CreateFrom((BlendShapeClip)target).ToString();
|
||||
}
|
||||
|
||||
public static int BlendShapeBindingHeight = 60;
|
||||
public static bool DrawBlendShapeBinding(Rect position, SerializedProperty property,
|
||||
PreviewSceneManager scene)
|
||||
{
|
||||
bool changed = false;
|
||||
if (scene != null)
|
||||
{
|
||||
var height = 16;
|
||||
|
||||
var y = position.y;
|
||||
var rect = new Rect(position.x, y, position.width, height);
|
||||
int pathIndex;
|
||||
if (StringPopup(rect, property.FindPropertyRelative("RelativePath"), scene.SkinnedMeshRendererPathList, out pathIndex))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
y += height;
|
||||
rect = new Rect(position.x, y, position.width, height);
|
||||
int blendShapeIndex;
|
||||
if (IntPopup(rect, property.FindPropertyRelative("Index"), scene.GetBlendShapeNames(pathIndex), out blendShapeIndex))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
y += height;
|
||||
rect = new Rect(position.x, y, position.width, height);
|
||||
if (FloatSlider(rect, property.FindPropertyRelative("Weight"), 100))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
public static int MaterialValueBindingHeight = 90;
|
||||
public static bool DrawMaterialValueBinding(Rect position, SerializedProperty property,
|
||||
PreviewSceneManager scene)
|
||||
{
|
||||
bool changed = false;
|
||||
if (scene != null)
|
||||
{
|
||||
var height = 16;
|
||||
|
||||
var y = position.y;
|
||||
var rect = new Rect(position.x, y, position.width, height);
|
||||
int materialIndex;
|
||||
if (StringPopup(rect, property.FindPropertyRelative("MaterialName"), scene.MaterialNames, out materialIndex))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (materialIndex >= 0)
|
||||
{
|
||||
var materialItem = scene.GetMaterialItem(scene.MaterialNames[materialIndex]);
|
||||
if (materialItem != null)
|
||||
{
|
||||
y += height;
|
||||
rect = new Rect(position.x, y, position.width, height);
|
||||
|
||||
// プロパティ名のポップアップ
|
||||
int propIndex;
|
||||
if (StringPopup(rect, property.FindPropertyRelative("ValueName"), materialItem.PropNames, out propIndex))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (propIndex >= 0)
|
||||
{
|
||||
// 有効なプロパティ名が選択された
|
||||
var propItem = materialItem.PropMap[materialItem.PropNames[propIndex]];
|
||||
{
|
||||
switch (propItem.PropertyType)
|
||||
{
|
||||
case ShaderUtil.ShaderPropertyType.Color:
|
||||
{
|
||||
property.FindPropertyRelative("BaseValue").vector4Value = propItem.DefaultValues;
|
||||
|
||||
// max
|
||||
y += height;
|
||||
rect = new Rect(position.x, y, position.width, height);
|
||||
if (ColorProp(rect, property.FindPropertyRelative("TargetValue")))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ShaderUtil.ShaderPropertyType.TexEnv:
|
||||
{
|
||||
property.FindPropertyRelative("BaseValue").vector4Value = propItem.DefaultValues;
|
||||
|
||||
// max
|
||||
y += height;
|
||||
rect = new Rect(position.x, y, position.width, height);
|
||||
if (OffsetProp(rect, property.FindPropertyRelative("TargetValue")))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool StringPopup(Rect rect, SerializedProperty prop, string[] options, out int newIndex)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
newIndex = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
var oldIndex = Array.IndexOf(options, prop.stringValue);
|
||||
newIndex = EditorGUI.Popup(rect, oldIndex, options);
|
||||
if (newIndex != oldIndex && newIndex >= 0 && newIndex < options.Length)
|
||||
{
|
||||
prop.stringValue = options[newIndex];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool IntPopup(Rect rect, SerializedProperty prop, string[] options, out int newIndex)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
newIndex = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
var oldIndex = prop.intValue;
|
||||
newIndex = EditorGUI.Popup(rect, oldIndex, options);
|
||||
if (newIndex != oldIndex && newIndex >= 0 && newIndex < options.Length)
|
||||
{
|
||||
prop.intValue = newIndex;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool FloatSlider(Rect rect, SerializedProperty prop, float maxValue)
|
||||
{
|
||||
var oldValue = prop.floatValue;
|
||||
var newValue = EditorGUI.Slider(rect, prop.floatValue, 0, 100f);
|
||||
if (newValue != oldValue)
|
||||
{
|
||||
prop.floatValue = newValue;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ColorProp(Rect rect, SerializedProperty prop)
|
||||
{
|
||||
var oldValue = (Color)prop.vector4Value;
|
||||
var newValue = EditorGUI.ColorField(rect, prop.displayName, oldValue);
|
||||
if (newValue != oldValue)
|
||||
{
|
||||
prop.vector4Value = newValue;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool OffsetProp(Rect rect, SerializedProperty prop)
|
||||
{
|
||||
var oldValue = prop.vector4Value;
|
||||
var newValue = EditorGUI.Vector4Field(rect, prop.displayName, oldValue);
|
||||
if (newValue != oldValue)
|
||||
{
|
||||
prop.vector4Value = newValue;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
301
Scripts/BlendShape/Editor/SerializedBlendShapeClipEditor.cs
Normal file
301
Scripts/BlendShape/Editor/SerializedBlendShapeClipEditor.cs
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public class SerializedBlendShapeEditor
|
||||
{
|
||||
public static int BlendShapeBindingHeight = 60;
|
||||
const int MaterialValueBindingHeight = 90;
|
||||
|
||||
SerializedObject serializedObject;
|
||||
|
||||
SerializedProperty m_BlendShapeNameProp;
|
||||
SerializedProperty m_PresetProp;
|
||||
SerializedProperty m_ValuesProp;
|
||||
ReorderableList m_ValuesList;
|
||||
SerializedProperty m_MaterialValuesProp;
|
||||
ReorderableList m_MaterialValuesList;
|
||||
|
||||
float m_previewSlider = 1.0f;
|
||||
|
||||
bool m_changed;
|
||||
|
||||
public SerializedBlendShapeEditor(SerializedObject serializedObject, PreviewSceneManager PreviewSceneManager)
|
||||
{
|
||||
this.serializedObject = serializedObject;
|
||||
|
||||
m_BlendShapeNameProp = serializedObject.FindProperty("BlendShapeName");
|
||||
m_PresetProp = serializedObject.FindProperty("Preset");
|
||||
m_ValuesProp = serializedObject.FindProperty("Values");
|
||||
|
||||
m_ValuesList = new ReorderableList(serializedObject, m_ValuesProp);
|
||||
m_ValuesList.elementHeight = BlendShapeBindingHeight;
|
||||
m_ValuesList.drawElementCallback =
|
||||
(rect, index, isActive, isFocused) =>
|
||||
{
|
||||
var element = m_ValuesProp.GetArrayElementAtIndex(index);
|
||||
rect.height -= 4;
|
||||
rect.y += 2;
|
||||
if (DrawBlendShapeBinding(rect, element, PreviewSceneManager))
|
||||
{
|
||||
m_changed = true;
|
||||
}
|
||||
};
|
||||
|
||||
m_MaterialValuesProp = serializedObject.FindProperty("MaterialValues");
|
||||
m_MaterialValuesList = new ReorderableList(serializedObject, m_MaterialValuesProp);
|
||||
m_MaterialValuesList.elementHeight = MaterialValueBindingHeight;
|
||||
m_MaterialValuesList.drawElementCallback =
|
||||
(rect, index, isActive, isFocused) =>
|
||||
{
|
||||
var element = m_MaterialValuesProp.GetArrayElementAtIndex(index);
|
||||
rect.height -= 4;
|
||||
rect.y += 2;
|
||||
if (DrawMaterialValueBinding(rect, element, PreviewSceneManager))
|
||||
{
|
||||
m_changed = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static bool DrawBlendShapeBinding(Rect position, SerializedProperty property,
|
||||
PreviewSceneManager scene)
|
||||
{
|
||||
bool changed = false;
|
||||
if (scene != null)
|
||||
{
|
||||
var height = 16;
|
||||
|
||||
var y = position.y;
|
||||
var rect = new Rect(position.x, y, position.width, height);
|
||||
int pathIndex;
|
||||
if (StringPopup(rect, property.FindPropertyRelative("RelativePath"), scene.SkinnedMeshRendererPathList, out pathIndex))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
y += height;
|
||||
rect = new Rect(position.x, y, position.width, height);
|
||||
int blendShapeIndex;
|
||||
if (IntPopup(rect, property.FindPropertyRelative("Index"), scene.GetBlendShapeNames(pathIndex), out blendShapeIndex))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
y += height;
|
||||
rect = new Rect(position.x, y, position.width, height);
|
||||
if (FloatSlider(rect, property.FindPropertyRelative("Weight"), 100))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
public static bool DrawMaterialValueBinding(Rect position, SerializedProperty property,
|
||||
PreviewSceneManager scene)
|
||||
{
|
||||
bool changed = false;
|
||||
if (scene != null)
|
||||
{
|
||||
var height = 16;
|
||||
|
||||
var y = position.y;
|
||||
var rect = new Rect(position.x, y, position.width, height);
|
||||
int materialIndex;
|
||||
if (StringPopup(rect, property.FindPropertyRelative("MaterialName"), scene.MaterialNames, out materialIndex))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (materialIndex >= 0)
|
||||
{
|
||||
var materialItem = scene.GetMaterialItem(scene.MaterialNames[materialIndex]);
|
||||
if (materialItem != null)
|
||||
{
|
||||
y += height;
|
||||
rect = new Rect(position.x, y, position.width, height);
|
||||
|
||||
// プロパティ名のポップアップ
|
||||
int propIndex;
|
||||
if (StringPopup(rect, property.FindPropertyRelative("ValueName"), materialItem.PropNames, out propIndex))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (propIndex >= 0)
|
||||
{
|
||||
// 有効なプロパティ名が選択された
|
||||
var propItem = materialItem.PropMap[materialItem.PropNames[propIndex]];
|
||||
{
|
||||
switch (propItem.PropertyType)
|
||||
{
|
||||
case ShaderUtil.ShaderPropertyType.Color:
|
||||
{
|
||||
property.FindPropertyRelative("BaseValue").vector4Value = propItem.DefaultValues;
|
||||
|
||||
// max
|
||||
y += height;
|
||||
rect = new Rect(position.x, y, position.width, height);
|
||||
if (ColorProp(rect, property.FindPropertyRelative("TargetValue")))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ShaderUtil.ShaderPropertyType.TexEnv:
|
||||
{
|
||||
property.FindPropertyRelative("BaseValue").vector4Value = propItem.DefaultValues;
|
||||
|
||||
// max
|
||||
y += height;
|
||||
rect = new Rect(position.x, y, position.width, height);
|
||||
if (OffsetProp(rect, property.FindPropertyRelative("TargetValue")))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
public struct DrawResult
|
||||
{
|
||||
public bool Changed;
|
||||
public float Weight;
|
||||
}
|
||||
|
||||
public DrawResult Draw()
|
||||
{
|
||||
m_changed = false;
|
||||
|
||||
//EditorGUILayout.Space();
|
||||
|
||||
var previewSlider = EditorGUILayout.Slider("Preview Weight", m_previewSlider, 0, 1.0f);
|
||||
if (previewSlider != m_previewSlider)
|
||||
{
|
||||
m_previewSlider = previewSlider;
|
||||
m_changed = true;
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.PropertyField(m_BlendShapeNameProp, true);
|
||||
EditorGUILayout.PropertyField(m_PresetProp, true);
|
||||
|
||||
EditorGUILayout.LabelField("BlendShapeBindings", EditorStyles.boldLabel);
|
||||
m_ValuesList.DoLayoutList();
|
||||
|
||||
EditorGUILayout.LabelField("MaterialValueBindings", EditorStyles.boldLabel);
|
||||
m_MaterialValuesList.DoLayoutList();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
return new DrawResult
|
||||
{
|
||||
Changed = m_changed,
|
||||
Weight = m_previewSlider
|
||||
};
|
||||
}
|
||||
|
||||
static bool StringPopup(Rect rect, SerializedProperty prop, string[] options, out int newIndex)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
newIndex = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
var oldIndex = Array.IndexOf(options, prop.stringValue);
|
||||
newIndex = EditorGUI.Popup(rect, oldIndex, options);
|
||||
if (newIndex != oldIndex && newIndex >= 0 && newIndex < options.Length)
|
||||
{
|
||||
prop.stringValue = options[newIndex];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool IntPopup(Rect rect, SerializedProperty prop, string[] options, out int newIndex)
|
||||
{
|
||||
if (options == null)
|
||||
{
|
||||
newIndex = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
var oldIndex = prop.intValue;
|
||||
newIndex = EditorGUI.Popup(rect, oldIndex, options);
|
||||
if (newIndex != oldIndex && newIndex >= 0 && newIndex < options.Length)
|
||||
{
|
||||
prop.intValue = newIndex;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool FloatSlider(Rect rect, SerializedProperty prop, float maxValue)
|
||||
{
|
||||
var oldValue = prop.floatValue;
|
||||
var newValue = EditorGUI.Slider(rect, prop.floatValue, 0, 100f);
|
||||
if (newValue != oldValue)
|
||||
{
|
||||
prop.floatValue = newValue;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ColorProp(Rect rect, SerializedProperty prop)
|
||||
{
|
||||
var oldValue = (Color)prop.vector4Value;
|
||||
var newValue = EditorGUI.ColorField(rect, prop.displayName, oldValue);
|
||||
if (newValue != oldValue)
|
||||
{
|
||||
prop.vector4Value = newValue;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool OffsetProp(Rect rect, SerializedProperty prop)
|
||||
{
|
||||
var oldValue = prop.vector4Value;
|
||||
var newValue = EditorGUI.Vector4Field(rect, prop.displayName, oldValue);
|
||||
if (newValue != oldValue)
|
||||
{
|
||||
prop.vector4Value = newValue;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: eaafa3ff7bf991642b922e6af7ecbbc0
|
||||
timeCreated: 1541081003
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Reference in New Issue
Block a user