diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneDrawer.cs b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneDrawer.cs new file mode 100644 index 0000000000..bc9bbbfaad --- /dev/null +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneDrawer.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace UniVRM10 +{ + using static Vrm10InstanceSpringBone; + + [CustomPropertyDrawer(typeof(Spring))] + public class VRM10SpringBoneDrawer : PropertyDrawer + { + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return EditorGUIUtility.singleLineHeight * 3 + + EditorGUI.GetPropertyHeight(property.FindPropertyRelative(nameof(Spring.ColliderGroups))) + + EditorGUI.GetPropertyHeight(property.FindPropertyRelative(nameof(Spring.Joints))) + ; + } + + static float DrawProp(Rect rect, SerializedProperty prop) + { + rect.height = EditorGUI.GetPropertyHeight(prop); + EditorGUI.PropertyField(rect, prop); + return rect.height; + } + + struct GuiEnable : IDisposable + { + bool Backup; + public static GuiEnable Enter(bool enable) + { + var value = new GuiEnable + { + Backup = GUI.enabled, + }; + GUI.enabled = enable; + return value; + } + + public void Dispose() + { + GUI.enabled = Backup; + } + } + + static IEnumerable MakeJointsRecursive(VRM10SpringBoneJoint parent) + { + if (parent.transform.childCount > 0) + { + var child = parent.transform.GetChild(0); + var joint = child.GetComponent(); + if (joint == null) + { + joint = child.gameObject.AddComponent(); + } + if (joint != null) + { + // set params + joint.m_dragForce = parent.m_dragForce; + joint.m_gravityDir = parent.m_gravityDir; + joint.m_gravityPower = parent.m_gravityPower; + joint.m_jointRadius = parent.m_jointRadius; + joint.m_stiffnessForce = parent.m_stiffnessForce; + + yield return joint; + foreach (var x in MakeJointsRecursive(joint)) + { + yield return x; + } + } + } + } + + public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label) + { + var x = rect.x; + var y = rect.y; + var w = rect.width; + var h = EditorGUIUtility.singleLineHeight; + y += DrawProp(new Rect(x, y, w, h), property.FindPropertyRelative(nameof(Spring.Name))); + y += DrawProp(new Rect(x, y, w, h), property.FindPropertyRelative(nameof(Spring.ColliderGroups))); + + var joints = property.FindPropertyRelative(nameof(Spring.Joints)); + y += DrawProp(new Rect(x, y, w, h), joints); + + var enable = joints.arraySize > 0 && joints.GetArrayElementAtIndex(0).objectReferenceValue != null; + using (GuiEnable.Enter(enable)) + { + if (GUI.Button(new Rect(x, y, w, h), "create joints to children")) + { + if (EditorUtility.DisplayDialog("auto joints", + "先頭の joint の子孫をリストに追加します。\n既存のリストは上書きされます。", + "ok", + "cancel")) + { + var root = (VRM10SpringBoneJoint)joints.GetArrayElementAtIndex(0).objectReferenceValue; + joints.ClearArray(); + int i = 0; + // 0 + joints.InsertArrayElementAtIndex(i); + joints.GetArrayElementAtIndex(i).objectReferenceValue = root; + ++i; + // 1... + foreach (var joint in MakeJointsRecursive(root)) + { + joints.InsertArrayElementAtIndex(i); + joints.GetArrayElementAtIndex(i).objectReferenceValue = joint; + ++i; + } + } + } + } + y += EditorGUIUtility.singleLineHeight; + + y += DrawProp(new Rect(x, y, w, h), property.FindPropertyRelative(nameof(Spring.Center))); + } + } +} \ No newline at end of file diff --git a/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneDrawer.cs.meta b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneDrawer.cs.meta new file mode 100644 index 0000000000..f13927d83f --- /dev/null +++ b/Assets/VRM10/Editor/Components/SpringBone/VRM10SpringBoneDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15a1d8924f711fd46b54b597ff553333 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: