using System.Text.RegularExpressions; using System.Collections.Generic; using System.Linq; using System.Reflection; using System; using UnityEditor; using UnityEngine; namespace UDE_HAND_INTERACTION { [CustomEditor(typeof(DollHand))] public class DollHandEditor : UnityEditor.Editor { public override void OnInspectorGUI() { DrawDefaultInspector(); DollHand Doll = target as DollHand; if (GUILayout.Button("Auto-Assign Bones")) { //SkinnedMeshRenderer skinnedHand = Doll.GetComponentInChildren(); //if (skinnedHand != null) //{ // SetPrivateValue(Doll, "_jointSets", AutoAsignBones(skinnedHand)); //} foreach(var item in Doll.JointSets) { item.rotationOffset = item.transform.localEulerAngles; } } } private List AutoAsignBones(SkinnedMeshRenderer skinnedHand) { List Sets = new List(); Transform root = skinnedHand.rootBone; Regex regEx = new Regex(@"Hand(\w*)(\d)"); foreach (var bone in FingersData.HAND_JOINT_IDS) { Match match = regEx.Match(bone.ToString()); if (match != Match.Empty) { string boneName = match.Groups[1].Value.ToLower(); string boneNumber = match.Groups[2].Value; Transform skinnedBone = RecursiveSearchForChildrenContainingPattern(root, "col", boneName, boneNumber); if (skinnedBone != null) { Sets.Add(new HandJointsSet() { id = bone, transform = skinnedBone, rotationOffset = Vector3.zero }); } } } return Sets; } private Transform RecursiveSearchForChildrenContainingPattern(Transform root, string ignorePattern, params string[] args) { if (root == null) { return null; } for (int i = 0; i < root.childCount; i++) { Transform child = root.GetChild(i); string childName = child.name.ToLower(); bool shouldCheck = string.IsNullOrEmpty(ignorePattern) || !childName.Contains(ignorePattern); if (shouldCheck) { bool containsAllArgs = args.All(a => childName.Contains(a)); Transform result = containsAllArgs ? child : RecursiveSearchForChildrenContainingPattern(child, ignorePattern, args); if (result != null) { return result; } } } return null; } private static void SetPrivateValue(object instance, string fieldName, object value) { FieldInfo fieldData = GetPrivateField(instance, fieldName); fieldData.SetValue(instance, value); } private static FieldInfo GetPrivateField(object instance, string fieldName) { Type type = instance.GetType(); FieldInfo fieldData = null; while (type != null && fieldData == null) { fieldData = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); type = type.BaseType; } return fieldData; } } }