internal static void DoBoneHandle(Transform target, Dictionary <Transform, bool> validBones) { int id = target.name.GetHashCode(); Event evt = Event.current; bool hasValidChildBones = false; if (validBones != null) { foreach (Transform child in target) { if (validBones.ContainsKey(child)) { hasValidChildBones = true; break; } } } Vector3 basePoint = target.position; List <Vector3> endPoints = new List <Vector3>(); // [case 525602] do not draw root. if (!hasValidChildBones && target.parent != null) { endPoints.Add(target.position + (target.position - target.parent.position) * 0.4f); } else { foreach (Transform child in target) { // Only render bone connections to valid bones // (except if no child bones are valid - then draw all connections) if (validBones != null && !validBones.ContainsKey(child)) { continue; } endPoints.Add(child.position); } } for (int i = 0; i < endPoints.Count; i++) { Vector3 endPoint = endPoints[i]; switch (evt.GetTypeForControl(id)) { case EventType.Layout: { float len = Vector3.Magnitude(endPoint - basePoint); float size = len * k_BoneThickness; Vector3[] vertices = GetBoneVertices(endPoint, basePoint, size); HandleUtility.AddControl(id, DistanceToPolygone(vertices)); break; } case EventType.MouseMove: if (id == HandleUtility.nearestControl) { HandleUtility.Repaint(); } break; case EventType.MouseDown: { // am I closest to the thingy? if (!evt.alt && HandleUtility.nearestControl == id && evt.button == 0) { GUIUtility.hotControl = id; // Grab mouse focus if (evt.shift) { Object[] selected = Selection.objects; if (ArrayUtility.Contains(selected, target) == false) { ArrayUtility.Add(ref selected, target); Selection.objects = selected; } } else { Selection.activeObject = target; } EditorGUIUtility.PingObject(target); evt.Use(); } break; } case EventType.MouseDrag: { if (!evt.alt && GUIUtility.hotControl == id) { DragAndDrop.PrepareStartDrag(); DragAndDrop.objectReferences = new UnityEngine.Object[] { target }; DragAndDrop.StartDrag(ObjectNames.GetDragAndDropTitle(target)); // having a hot control set during drag makes the control eat the drag events // and dragging of bones no longer works over the avatar configure window // see case 912016 GUIUtility.hotControl = 0; evt.Use(); } break; } case EventType.MouseUp: { if (GUIUtility.hotControl == id && (evt.button == 0 || evt.button == 2)) { GUIUtility.hotControl = 0; evt.Use(); } break; } case EventType.Repaint: { float len = Vector3.Magnitude(endPoint - basePoint); if (len > 0) { color = GUIUtility.hotControl == 0 && HandleUtility.nearestControl == id ? Handles.preselectionColor : color; // size used to be based on sqrt of length but that makes bones for // huge creatures hair-thin and bones for tiny creatures bulky. // So base on a fixed proportion instead. float size = len * k_BoneThickness; if (hasValidChildBones) { Handles.DrawBone(endPoint, basePoint, size); } else { Handles.SphereHandleCap(id, basePoint, target.rotation, size * .2f, EventType.Repaint); } } break; } } } }