using FIMSpace.FEditor; using UnityEditor; using UnityEngine; namespace FIMSpace.FProceduralAnimation { public partial class LegsAnimatorEditor { public bool IsSceneViewVisible { get { return SceneView.lastActiveSceneView != null; } } public SceneView ScView { get { return SceneView.lastActiveSceneView; } } public void SceneHelper_FocusOnInSceneView(Transform t, float scale = 1f) { if (t == null) return; SceneView.lastActiveSceneView.Frame(new Bounds(t.position, Vector3.one * scale * 0.6f), false); } public Transform SceneHelper_FocusOnBone = null; void SceneHelper_DrawBoneFocus() { if (SceneHelper_FocusOnBone == null) return; Vector3 bonePos = SceneHelper_FocusOnBone.position; Vector3 lookDir = ScView.camera.transform.position - bonePos; Quaternion cameraLook = Quaternion.identity; if (lookDir != Vector3.zero) cameraLook = Quaternion.LookRotation(lookDir); float sideOff = Get.Util_SideMul(SceneHelper_FocusOnBone); Handles.color = new Color(0.4f, 1f, 0.65f, 0.5f); float avLength = 0f; for (int c = 0; c < SceneHelper_FocusOnBone.childCount; c++) { Vector3 childPos = SceneHelper_FocusOnBone.GetChild(c).position; FGUI_Handles.DrawBoneHandle(bonePos, childPos, 1f); avLength += Vector3.Distance(childPos, bonePos); } if (SceneHelper_FocusOnBone.childCount > 0) avLength /= (float)SceneHelper_FocusOnBone.childCount; else avLength = 0.65f; //Handles.color = new Color(0.4f, 1f, 0.65f, 0.2f); Handles.DrawWireDisc(bonePos, cameraLook * Vector3.forward, avLength * 0.3f); // Draw children Handles.color = new Color(0.4f, 1f, 0.65f, 0.125f); for (int c = 0; c < SceneHelper_FocusOnBone.childCount; c++) { Transform child = SceneHelper_FocusOnBone.GetChild(c); for (int i = 0; i < child.childCount; i++) { Vector3 childPos = child.GetChild(i).position; FGUI_Handles.DrawBoneHandle(child.position, childPos, 0.2f); } } Handles.color = new Color(0.7f, 0.7f, 0.7f, 0.25f); float off = Mathf.Lerp(editorScaleRef, avLength, 0.4f); lookDir.y = 0f; lookDir.Normalize(); cameraLook = ScView.camera.transform.rotation; Vector3 helperPos = bonePos + cameraLook * Vector3.right * sideOff * off * 0.8f + Vector3.up * off * 0.2f; Handles.DrawLine(bonePos, helperPos); Handles.color = Color.white; Handles.Label(helperPos + Vector3.up * off * 0.08f, SceneHelper_FocusOnBone.name, FGUI_Resources.HeaderStyle); } void SceneHelper_DrawHipsHubs() { if (Get.Hips == null) return; if (Get.ExtraHipsHubs == null) return; if (Get.ExtraHipsHubs.Count == 0) return; for (int i = 0; i < Get.ExtraHipsHubs.Count; i++) { if (Get.ExtraHipsHubs[i] == null) continue; Handles.SphereHandleCap(0, Get.ExtraHipsHubs[i].position, Quaternion.identity, editorScaleRef * 0.1f, EventType.Repaint); if (!Get.LegsInitialized) { Handles.DrawAAPolyLine(2, Get.Hips.position, Get.ExtraHipsHubs[i].position); } else { if (Get.HipsHubs[i].HubBackBones?.Count > 0) { Handles.DrawAAPolyLine(2, Get.ExtraHipsHubs[i].position, Get.HipsHubs[i].HubBackBones[0].bone.position, Get.HipsHubs[i].HubBackBones[0].bone.position + Get.Up * editorScaleRef * 0.1f); for (int b = 1; b < Get.HipsHubs[i].HubBackBones.Count; b++) { Handles.DrawAAPolyLine(2, Get.HipsHubs[i].HubBackBones[b - 1].bone.position, Get.HipsHubs[i].HubBackBones[b].bone.position, Get.HipsHubs[i].HubBackBones[b].bone.position + Get.Up * editorScaleRef * 0.1f); } } } } } void SceneHelper_DrawLegStartBoneSelector(LegsAnimator.Leg leg, float drawScale, Transform legsHub) { if (legsHub == null) return; for (int c = 0; c < legsHub.childCount; c++) { Transform cc = legsHub.GetChild(c); bool should = Util_Leg_ShouldDraw(cc); if (should) Handles.color = new Color(0.4f, 1f, 0.65f, 0.225f); else Handles.color = new Color(0.4f, 0.4f, 0.4f, 0.225f); Vector3 childPos = cc.position; FGUI_Handles.DrawBoneHandle(legsHub.position, childPos, 1f); if (!should) continue; if (cc.childCount > 0) { float hSize = HandleUtility.GetHandleSize(childPos); if (hSize > 0.01f) { float scaler = 1f / hSize; float mouseOnDistance = Vector2.Distance(Event.current.mousePosition, HandleUtility.WorldToGUIPoint(childPos)); if (mouseOnDistance < 2.85f * scaler) FGUI_Handles.DrawBoneHandle(childPos, cc.GetChild(0).position, .7f); //if ( c == 0) UnityEngine.Debug.Log("scaler = " + hSize); //UnityEngine.Debug.Log("drawScale = " + editorScaleRef + " : mouse pos = " + Event.current.mousePosition + " : wpoint =" + HandleUtility.WorldToGUIPoint(childPos) + "mose distance = " + mouseOnDistance); } } if (Handles.Button(childPos, Quaternion.identity, drawScale, drawScale, Handles.CircleHandleCap)) { leg.BoneStart = cc; } Util_DrawBoneIndicator(cc, drawScale); } } void SceneHelper_DrawLegSelectorHelper() { if (Get.LegsInitialized) return; if (_selected_leg < 0) return; if (Get.Hips == null) return; //SceneHelper_FocusOnBone = null; Get.User_RefreshHelperVariablesOnParametersChange(); if (Get.Legs.ContainsIndex(_selected_leg) == false) { _selected_leg = -1; return; } Quaternion viewRot = ScView.camera.transform.rotation; var leg = Get.Legs[_selected_leg]; float drawScaleRaw = editorScaleRef * 0.06f; float drawScale = drawScaleRaw; if (leg.BoneStart == null) { #region Start bone selector Handles.BeginGUI(); GUI.Label(new Rect(0, 10, Screen.width, 40), "Select Start Leg Bone", FGUI_Resources.HeaderStyleBig); Handles.EndGUI(); SceneHelper_DrawLegStartBoneSelector(leg, drawScaleRaw, Get.Hips); for (int i = 0; i < Get.ExtraHipsHubs.Count; i++) { SceneHelper_DrawLegStartBoneSelector(leg, drawScaleRaw, Get.ExtraHipsHubs[i]); } #endregion } else { Handles.BeginGUI(); float sideWidth = Mathf.Max(180, Screen.width * 0.33f); GUI.Label(new Rect(0, 10, Screen.width, 40), leg.BoneStart.name.ToUpper() + " - Side: " + leg.Side.ToString(), FGUI_Resources.HeaderStyle); if (leg.BoneStart && leg.BoneMid && leg.BoneEnd) { GUI.color = Color.black; GUI.Box(new Rect(5, 8, sideWidth + 35, 124), GUIContent.none, FGUI_Resources.HeaderBoxStyleH); GUI.Box(new Rect(5, 8, sideWidth + 35, 124), GUIContent.none, FGUI_Resources.HeaderBoxStyleH); GUI.color = Color.white; //GUI.color = new Color(1f, 1f, 1f, 0.8f); GUI.color = Color.white * 1.4f; if (GUI.Button(new Rect(20, 22, 22, 19), new GUIContent(FGUI_Resources.TexTargetingIcon, "Ping start leg in the hierarchy to easily find other legs 'Top Bones'"), FGUI_Resources.ButtonStyle)) { PingObject(leg.BoneStart); } GUI.Label(new Rect(20, 12, sideWidth, 40), "Use " + leg.BoneStart.name + " setup for:", EditorStyles.centeredGreyMiniLabel); if (GUI.Button(new Rect(20, 46, sideWidth, 32), "Try Automatically Setup\nRest Of The Legs in Hips", FGUI_Resources.ButtonStyle)) { Get.Setup_TryAutoLegsSetup(leg, Get.Hips); _selected_leg = -1; } GUI.Label(new Rect(20, 72, sideWidth, 40), "Apply Auto-Setup for Selective Leg Bone:", EditorStyles.centeredGreyMiniLabel); EditorGUIUtility.labelWidth = 96; Transform toSetup = (Transform)EditorGUI.ObjectField(new Rect(20, 104, sideWidth, 20), new GUIContent("Leg Top Bone", "Drag & Drop there leg start/thigh bone from hierarchy window to try automatically set it up with the same patter as the first bone was set up."), null, typeof(Transform), true); if (toSetup != null) { Get.Setup_TryAutoLegSetup(leg, toSetup); _selected_leg = Get.Legs.Count - 1; } EditorGUIUtility.labelWidth = 0; GUI.color = Color.white; } Handles.EndGUI(); Vector3 buttonOff = ScView.camera.transform.rotation * Vector3.right * Get.Util_SideMul(leg.BoneStart) * drawScale * 0.8f; //Vector3.up * drawScale if (Util_DrawButton(new GUIContent(Tex_smLegStart), buttonOff + leg.BoneStart.position + 2f * LabelIndicatorHelperOffset(leg.BoneStart, drawScale, false, true), 1f, false)) { PingObject(leg.BoneStart); } Util_DrawBoneIndicator(leg.BoneStart, drawScale * 1.65f, true, "", false, true); Handles.color = new Color(0.5f, 1f, 0.55f, 0.75f); if (leg.BoneMid != null) FGUI_Handles.DrawBoneHandle(leg.BoneStart.position, leg.BoneMid.position, 1f); else Util_DrawChildBoneOf(leg.BoneStart, 0.6f); Transform legBone = leg.BoneStart; // Drawing buttons for target bones to be selected if (leg.BoneMid == null || leg.BoneEnd == null) { int i = 1; while (legBone.childCount > 0) { legBone = Get.Finders_GetRelevantChildOf(legBone); bool already = false; for (int l = 0; l < Get.Legs.Count; l++) { var lg = Get.Legs[l]; if (lg.BoneStart == legBone) { already = true; break; } if (lg.BoneMid == legBone) { already = true; break; } if (lg.BoneEnd == legBone) { already = true; break; } } if (already) continue; Util_DrawLegSegmentSelectorButton(leg, legBone, drawScale, i % 2 == 0, true); i += 1; } } // Drawing icons of already choosen leg bones if (leg.BoneMid != null) { Util_DrawBoneIndicator(leg.BoneMid, drawScale * 1.65f, true, "", true, true); Handles.color = new Color(0.35f, .925f, 0.65f, 0.65f); FGUI_Handles.DrawBoneHandle(leg.BoneMid.position, leg.BoneMid.position, 1f); if (Util_DrawButton(new GUIContent(Tex_smLegMid), buttonOff + leg.BoneMid.position + 1.7f * LabelIndicatorHelperOffset(leg.BoneMid, drawScale, true, true), 1f, false)) { PingObject(leg.BoneMid); } if (leg.BoneEnd != null) FGUI_Handles.DrawBoneHandle(leg.BoneMid.position, leg.BoneEnd.position, 1f); else Util_DrawChildBoneOf(leg.BoneMid, 0.6f); } if (leg.BoneEnd != null) { Util_DrawBoneIndicator(leg.BoneEnd, drawScale * 1.65f, true, "", false, true); Handles.color = new Color(0.1f, .8f, 0.9f, 0.65f); if (leg.BoneMid) FGUI_Handles.DrawBoneHandle(leg.BoneMid.position, leg.BoneEnd.position, 1f); if (Util_DrawButton(new GUIContent(Tex_smLegEnd), buttonOff + leg.BoneEnd.position + 2f * LabelIndicatorHelperOffset(leg.BoneEnd, drawScale, false, true), 1f, false)) { PingObject(leg.BoneEnd); } Util_DrawChildBoneOf(leg.BoneEnd, 0.6f); } //Transform lastP = AnimationTools.SkeletonRecognize.GetBottomMostChildTransform(leg.BoneStart); } if (leg.OppositeLegIndex != -1) if (Get.Legs.ContainsIndex(leg.OppositeLegIndex)) { var oppositeLeg = Get.Legs[leg.OppositeLegIndex]; if (oppositeLeg != null) { Handles.color = new Color(0.7f, 0.7f, 0.2f, 0.25f); SceneHelper_Leg_DrawBones(oppositeLeg); Handles.color = new Color(1f, 1f, 1f, 0.4f); SceneHelper_DrawLegAsLines(oppositeLeg); } } } void SceneHelper_DrawLegAsLines(LegsAnimator.Leg leg, float lineWidth = 4f) { if (leg.BoneStart == null) return; if (leg.BoneMid == null) return; Handles.DrawAAPolyLine(lineWidth, leg.BoneStart.position, leg.BoneMid.position); if (leg.BoneEnd == null) return; Handles.DrawAAPolyLine(lineWidth, leg.BoneMid.position, leg.BoneEnd.position); } void SceneHelper_DrawScaleReference() { float rScale = editorScaleRef; Handles.color = new Color(0.3f, 0.9f, 0.35f, 0.55f); Vector3 offsetSide = Get.transform.right * rScale * 0.8f; Vector3 offsetForw = Get.transform.forward * rScale * 0.2f; Vector3 sidePos = Get.transform.position + offsetSide; Vector3 sidePosU = Get.transform.position + offsetSide + Get.Up * editorScaleRef; Handles.DrawAAPolyLine(2f + rScale, sidePos + offsetForw, sidePos - offsetForw); Handles.DrawAAPolyLine(2f + rScale, sidePosU + offsetForw, sidePosU - offsetForw); Handles.DrawAAPolyLine(2f + rScale, sidePos, sidePosU); if (Application.isPlaying == false) Handles.Label(sidePos, new GUIContent(" [i]", "Scale reference height. It should be about half of the height of the chracter, if it's two-legs character.\nIf it's quadruped/spider, it should be around height of hips of the creature.")); } void SceneHelper_DrawRaycastingCastRange() { if (Get.RaycastStyle == LegsAnimator.ERaycastStyle.NoRaycasting) return; float rScale = Get.ScaleReference; Handles.color = new Color(0.3f, 0.9f, 0.35f, 0.65f); Vector3 offsetSide = -Get.transform.right * rScale * 0.8f; Vector3 offsetRight = Get.transform.right * rScale * 0.2f; Vector3 sidePos = Get.Hips.position + offsetSide; Vector3 grnd = Get.BaseTransform.position; if (Get.RaycastStartHeight == LegsAnimator.ERaycastStartHeight.StaticScaleReference) { sidePos = Get.transform.position + offsetSide + Get.transform.up * Get.ScaleReference * Get.RaycastStartHeightMul; } else { grnd = Get.Hips.position; grnd = Get.BaseTransform.InverseTransformPoint(grnd); grnd.y = 0f; grnd = Get.BaseTransform.TransformPoint(grnd); } Vector3 sidePosGrnd = grnd + offsetSide; Vector3 sidePosArr = Vector3.LerpUnclamped(sidePos, sidePosGrnd, 0.8f); if (Get.RaycastStyle != LegsAnimator.ERaycastStyle.AlongBones) { Handles.DrawDottedLine(sidePos, Get.Hips.position, 3f); Handles.DrawWireDisc(sidePos, Get.Up, rScale * 0.2f); Handles.DrawWireDisc(sidePosGrnd, Get.Up, rScale * 0.2f); } if (Get.RaycastStyle == LegsAnimator.ERaycastStyle.StraightDown) { Handles.DrawAAPolyLine(2f + rScale, sidePos, sidePosGrnd); Handles.DrawAAPolyLine(2f + rScale, sidePosGrnd, sidePosArr + offsetRight); Handles.DrawAAPolyLine(2f + rScale, sidePosGrnd, sidePosArr - offsetRight); } if (Get.RaycastStyle != LegsAnimator.ERaycastStyle.StraightDown && Get.RaycastStyle != LegsAnimator.ERaycastStyle.AlongBones) { Handles.DrawAAPolyLine(2f + rScale, Get.Hips.position, sidePosGrnd); Vector3 dir = sidePosGrnd - Get.Hips.position; Quaternion towards = Quaternion.LookRotation(dir, Get.Up); Handles.DrawAAPolyLine(2f + rScale, sidePosGrnd, sidePosGrnd - dir * 0.1f + towards * Vector3.up * Get.ScaleReference * 0.125f); Handles.DrawAAPolyLine(2f + rScale, sidePosGrnd, sidePosGrnd - dir * 0.1f + towards * Vector3.down * Get.ScaleReference * 0.125f); } Vector3 castEnd = sidePosGrnd; castEnd += -Get.Up * rScale * Get.CastDistance; if (Get.RaycastStyle != LegsAnimator.ERaycastStyle.OriginToFoot && Get.RaycastStyle != LegsAnimator.ERaycastStyle.AlongBones) { Handles.DrawDottedLine(sidePosGrnd, castEnd, 3f); Handles.DrawWireDisc(castEnd, Get.Up, rScale * 0.2f); } if (Get.RaycastStyle == LegsAnimator.ERaycastStyle.AlongBones) { if (Get.Legs.Count > 0) { for (int i = 0; i < Get.Legs.Count; i++) { if (Get.Legs[i].BoneStart && Get.Legs[i].BoneMid && Get.Legs[i].BoneEnd) { Handles.DrawAAPolyLine(Get.Legs[i].BoneStart.position, Get.Legs[i].BoneMid.position, Get.Legs[i].BoneEnd.position); Handles.DrawDottedLine(Get.Legs[i].BoneEnd.position, Get.Legs[i].BoneEnd.position - Get.Up * rScale * Get.CastDistance, 3f); } } } } } void SceneHelper_DrawGlueFloorLevel() { Handles.matrix = Get.BaseTransform.localToWorldMatrix; float f = Get.ScaleReferenceNoScale; float h = Get.GluingFloorLevelUseOnMoving ? Mathf.Lerp(Get.GluingFloorLevel, Get.GluingFloorLevelOnMoving, Get.IsMovingBlend) : Get.GluingFloorLevel; Vector3 a = new Vector3(f, h, f); Vector3 b = new Vector3(f, h, -f); Vector3 c = new Vector3(-f, h, -f); Vector3 d = new Vector3(-f, h, f); Handles.DrawAAPolyLine(3f, a, b, c, d, a); Handles.matrix = Matrix4x4.identity; } void SceneHelper_DrawRaycastingStepDown() { if (Get.RaycastStyle == LegsAnimator.ERaycastStyle.NoRaycasting) return; float rScale = Get.ScaleReference; Handles.color = new Color(0.6f, 0.4f, 0.1f, 0.4f); Vector3 hipsPos = Get.Hips.position; if (Get.LegsInitialized) { hipsPos = Get.RootToWorldSpace(Get.HipsSetup.InitHipsPositionRootSpace); } Vector3 offsetSide = Get.transform.right * rScale * 0.8f; Vector3 offsetRight = Get.transform.right * rScale * 0.2f; Vector3 offsetForw = Get.transform.forward * rScale * 0.2f; Vector3 sidePos = hipsPos + offsetSide; Vector3 bodyEnd = sidePos; bodyEnd += -Get.Up * rScale * Get.BodyStepDown; float hipsToGround = Get.HipsToGroundDistance(); if (Get.LegsInitialized) hipsToGround = Get.HipsSetup.InitialHipsHeightLocal * Get.BaseTransform.lossyScale.y; Vector3 bodyEndLeg = bodyEnd - Get.Up * hipsToGround; if (Get.BodyStepDown > 0f) { Handles.DrawDottedLine(sidePos, hipsPos, 3f); Handles.SphereHandleCap(0, sidePos, Quaternion.identity, rScale * 0.1f, EventType.Repaint); Handles.DrawAAPolyLine(2f + rScale, sidePos, bodyEnd); Handles.DrawWireDisc(bodyEnd, Get.Up, rScale * 0.2f); Handles.DrawAAPolyLine(3f + rScale, bodyEnd + offsetRight, bodyEndLeg + offsetRight, bodyEndLeg + offsetRight + offsetForw); Handles.DrawAAPolyLine(3f + rScale, bodyEnd - offsetRight, bodyEndLeg - offsetRight, bodyEndLeg - offsetRight + offsetForw); } if (Get.MaxBodyStepUp > 0f) { Vector3 bodyUpper = sidePos + offsetSide; bodyUpper += Get.Up * rScale * Get.MaxBodyStepUp; Handles.DrawDottedLine(bodyUpper, sidePos + offsetSide, 3f); Handles.DrawDottedLine(sidePos + offsetSide, sidePos, 3f); Handles.SphereHandleCap(0, bodyUpper, Quaternion.identity, rScale * 0.1f, EventType.Repaint); bodyEndLeg = bodyUpper - Get.Up * hipsToGround; Handles.DrawWireDisc(bodyUpper, Get.Up, rScale * 0.2f); Handles.DrawAAPolyLine(3f + rScale, bodyUpper + offsetRight, bodyEndLeg + offsetRight, bodyEndLeg + offsetRight + offsetForw); Handles.DrawAAPolyLine(3f + rScale, bodyUpper - offsetRight, bodyEndLeg - offsetRight, bodyEndLeg - offsetRight + offsetForw); } } protected void SceneHelper_DrawExtraControll() { Handles.matrix = Get.BaseTransform.localToWorldMatrix; //if (Get.FloorLevel != 0f) { float planeScale = Get.ScaleReference * 0.425f; float yl = Get.GluingFloorLevel; Handles.color = new Color(0.4f, 0.45f, 1f, 0.5f); Handles.DrawAAPolyLine(2, new Vector3(-planeScale, yl, -planeScale), new Vector3(planeScale, yl, -planeScale), new Vector3(planeScale, yl, planeScale), new Vector3(-planeScale, yl, planeScale), new Vector3(-planeScale, yl, -planeScale)); planeScale *= 0.5f; Handles.color *= 0.75f; Handles.DrawWireDisc(Vector3.zero, Get.Up, planeScale); Handles.DrawLine(new Vector3(0f, yl, planeScale), new Vector3(0f, yl, -planeScale)); Handles.DrawLine(new Vector3(planeScale, yl, 0f), new Vector3(-planeScale, yl, 0f)); } Handles.matrix = Matrix4x4.identity; } void SceneHelper_DrawRaycastingPreview(Color baseColor) { if (Application.isPlaying == false) return; float scaleRefSm = Get.ScaleReference * 0.1f; Handles.color = baseColor; for (int l = 0; l < Get.Legs.Count; l++) { var leg = Get.Legs[l]; if (!leg.RaycastHitted) { Handles.DrawWireDisc(leg.BoneEnd.position, Get.Up, scaleRefSm); break; } RaycastHit hit = leg.LastGroundHit; Handles.DrawWireDisc(hit.point, hit.normal, scaleRefSm); Handles.DrawLine(hit.point, hit.point + hit.normal * scaleRefSm); Handles.SphereHandleCap(0, hit.point + hit.normal * scaleRefSm, Quaternion.identity, scaleRefSm * 0.5f, EventType.Repaint); } } void SceneHelper_DrawFeetLength() { //if (_setupik_selected_leg < 0) // Handles.color = Color.green * 0.9f; //else // Handles.color = Color.green * 0.4f; //for (int l = 0; l < Get.Legs.Count; l++) //{ // var leg = Get.Legs[l]; // if (leg.BoneEnd == null) continue; // Vector3 heelStart = leg.BoneEnd.TransformPoint(leg.AnkleToHeel); // Vector3 footEnd = leg.BoneEnd.TransformPoint(leg.AnkleToFeetEnd); // Vector3 toEnd = footEnd - heelStart; // Vector3 right = leg.BoneEnd.TransformDirection(leg.AnkleRight).normalized * toEnd.magnitude * 0.4f; // Vector3 end = footEnd + toEnd * Get.FeetLengthAdjust; // Handles.DrawAAPolyLine(3f, heelStart + right, end + right, end - right, heelStart - right); //} } void SceneHelper_DrawIKSetup(Color mainColor, int selected) { float scaleRef = Get.ScaleReference; float scaleRefShort = Get.ScaleReference * 0.2f; float scaleRefShort2 = scaleRefShort * 0.25f; for (int i = 0; i < Get.Legs.Count; i++) { var leg = Get.Legs[i]; if (leg.HasAllBonesSet() == false) continue; bool isSel = selected == i; if (selected < -1) isSel = true; Handles.color = mainColor * (isSel ? 1f : 0.5f); Handles.DrawLine(leg.BoneStart.position, Get.Hips.position); FGUI_Handles.DrawBoneHandle(leg.BoneStart.position, leg.BoneMid.position, 0.6f); FGUI_Handles.DrawBoneHandle(leg.BoneMid.position, leg.BoneEnd.position, 0.6f); Vector3 heel = leg.BoneEnd.TransformPoint(leg.AnkleToHeel); if (Get.AnimateFeet) { Handles.color = mainColor * (isSel ? 0.8f : 0.3f); //Vector3 heelForw = heel + leg.BoneEnd.TransformDirection(leg.AnkleForward * scaleRefShort); Vector3 footEnd = leg.BoneEnd.TransformPoint(leg.AnkleToFeetEnd); Vector3 heelForw = footEnd + (footEnd - heel) * Get.FeetLengthAdjust; Vector3 heelUp = heelForw + leg.BoneEnd.TransformDirection(leg.AnkleUp * scaleRefShort2); Handles.DrawAAPolyLine(2 + scaleRef, leg.BoneEnd.position, heel, heelForw, heelUp, leg.BoneEnd.position); Handles.DrawAAPolyLine(2 + scaleRef, heelForw, heel + leg.BoneEnd.TransformDirection(leg.AnkleRight * scaleRefShort2), heel - leg.BoneEnd.TransformDirection(leg.AnkleRight * scaleRefShort2), heelForw); scaleRefShort2 *= 2f; Vector3 feetEnd = Vector3.LerpUnclamped(heel, heelForw, leg.FootMiddlePosition); Handles.DrawAAPolyLine(2 + scaleRef, feetEnd - Get.BaseTransform.right * scaleRefShort2, feetEnd + Get.BaseTransform.right * scaleRefShort2); Handles.DrawAAPolyLine(2 + scaleRef, feetEnd, heel); } else { Handles.DrawAAPolyLine(2 + scaleRef, leg.BoneEnd.position, heel); Handles.color *= 0.6f; Handles.DrawWireDisc(heel, Get.Up, scaleRefShort2); if (isSel && selected > -2) { Handles.color *= 0.7f; Handles.DrawWireDisc(leg.BoneEnd.position, Get.Up, scaleRefShort2); } } } } void SceneHelper_DrawDefinedBones(Color? customColor = null) { if (_selected_leg >= 0) return; if (Get.Hips == null) return; Handles.color = new Color(0.25f, 0.9f, 0.7f, 0.8f); if (customColor != null) Handles.color = customColor.Value; for (int i = 0; i < Get.Legs.Count; i++) { var leg = Get.Legs[i]; SceneHelper_Leg_DrawBones(leg); } if (SceneHelper_FocusOnBone == null) { Handles.SphereHandleCap(0, Get.Hips.position, Quaternion.identity, editorScaleRef * 0.07f, EventType.Repaint); } } void SceneHelper_DrawDefinedBonesHipsLink(Color? customColor = null) { if (_selected_leg >= 0) return; if (Get.Hips == null) return; Handles.color = new Color(0.3f, 0.9f, 0.75f, 0.4f); if (customColor != null) Handles.color = customColor.Value; for (int i = 0; i < Get.Legs.Count; i++) { var leg = Get.Legs[i]; if (leg.BoneEnd == null) continue; Handles.DrawDottedLine(leg.BoneEnd.position, Get.Hips.position, 3f); } } void SceneHelper_Leg_DrawBones(LegsAnimator.Leg leg) { if (leg.BoneStart) { if (leg.BoneMid) FGUI_Handles.DrawBoneHandle(leg.BoneStart.position, leg.BoneMid.position); else Util_DrawChildBoneOf(leg.BoneStart); Handles.DrawDottedLine(leg.BoneStart.position, Get.Hips.position, 2f); } if (leg.BoneMid) { if (leg.BoneEnd) FGUI_Handles.DrawBoneHandle(leg.BoneMid.position, leg.BoneEnd.position); else Util_DrawChildBoneOf(leg.BoneMid); } if (leg.BoneEnd) { Util_DrawChildBoneOf(leg.BoneEnd); } } void Util_DrawLegSegmentSelectorButton(LegsAnimator.Leg leg, Transform t, float drawScale, bool mirror = false, bool upMode = false) { Handles.color = new Color(0.4f, 1f, 0.65f, 0.3f); Util_DrawChildBoneOf(t.parent, 0.4f); float mul = 1f; if (leg.BoneMid == t || leg.BoneEnd == t) mul = -1f; Util_DrawBoneIndicator(t, drawScale * mul * 0.7f, false, mul == -1f ? "Change" : "", mirror, upMode); Vector3 off = LabelIndicatorHelperOffset(t, drawScale, mirror) * 0.6f; float hSize = HandleUtility.GetHandleSize(t.position); float scaler = 1f / hSize; if (leg.BoneMid == null) { Handles.color = new Color(1f, 1f, 1f, 1f); if (Util_DrawButton(new GUIContent(Tex_LegMid), t.position + off * 0.2f, 1f)) { leg.BoneMid = t; OnChange(); } } if (leg.BoneEnd == null && leg.BoneMid != null) { Handles.color = new Color(1f, 1f, 1f, 1f); if (Util_DrawButton(new GUIContent(Tex_LegEnd), t.position + off * 0.2f, 1f, true, new Vector2(1, 0))) { leg.BoneEnd = t; leg.DefineLegSide(Get); leg.RefreshLegAnkleToHeelAndFeetAndAxes(Get.BaseTransform); OnChange(); } } if (hSize > 0.01f) { float mouseOnDistance = 1000f; int sel = 0; if (leg.BoneMid == null) { mouseOnDistance = Vector2.Distance(Event.current.mousePosition, HandleUtility.WorldToGUIPoint(t.position /*+ off*/)); sel = 1; } else if (leg.BoneEnd == null) { float dist2 = Vector2.Distance(Event.current.mousePosition, HandleUtility.WorldToGUIPoint(t.position /*+ off + ScView.camera.transform.rotation * Vector3.right * drawScale * 1.25f*/)); if (dist2 < mouseOnDistance) { mouseOnDistance = dist2; sel = 2; } } if (mouseOnDistance < 1f * scaler) { Util_DrawChildBoneOf(t, .6f); if (t.childCount > 0) if (sel > 0) { string label = sel == 1 ? "? Is it Lower Leg ?" : "? IS it Foot Bone ?"; Vector3 labelPos = Vector3.Lerp(t.position, t.GetChild(0).position, 0.35f); labelPos += ScView.camera.transform.rotation * Vector3.right * drawScale * 0.15f; Handles.Label(labelPos, label, EditorStyles.boldLabel); } } } } void Util_DrawBoneIndicator(Transform b, float drawScale, bool drawSphere = false, string customString = "", bool mirror = false, bool upMode = false) { if (b == null) return; Handles.color = new Color(0.6f, 0.6f, 0.7f, 0.65f); if (drawSphere) { Handles.SphereHandleCap(0, b.position, Quaternion.identity, drawScale * 0.5f, EventType.Repaint); } Vector3 labelPos = b.position + LabelIndicatorHelperOffset(b, drawScale, mirror, upMode); labelPos += Vector3.up * drawScale * 0.4f; Handles.DrawLine(b.position, labelPos); Handles.color = Color.white; Handles.Label(labelPos + Vector3.up * drawScale * 0.5f, string.IsNullOrEmpty(customString) ? b.name : customString); } Vector3 LabelIndicatorHelperOffset(Transform b, float drawScale, bool mirror = false, bool upMode = false) { if (upMode) return ScView.camera.transform.rotation * new Vector3(mirror ? 0.2f : -.2f, mirror ? 0.8f : -0.8f, 0.3f) * Get.Util_SideMul(b) * drawScale * 3f; return ScView.camera.transform.rotation * new Vector3(mirror ? 0.9f : -.8f, 0.33f, 0f) * Get.Util_SideMul(b) * drawScale * 3f; } void Util_DrawChildBoneOf(Transform t, float fatness = 1f) { if (t.childCount <= 0) return; FGUI_Handles.DrawBoneHandle(t.position, Get.Finders_GetRelevantChildOf(t).position, fatness); } bool Util_Leg_ShouldDraw(Transform t) { //if (t == SceneHelper_FocusOnBone) return false; for (int i = 0; i < Get.Legs.Count; i++) { var leg = Get.Legs[i]; if (leg.BoneStart == t) return false; if (leg.BoneMid == t) return false; if (leg.BoneEnd == t) return false; } return true; } public static GUIStyle ButtonStyle { get { if (__buttStyleHard != null) return __buttStyleHard; __buttStyleHard = new GUIStyle(EditorStyles.miniButton); __buttStyleHard.fixedHeight = 0; __buttStyleHard.padding = new RectOffset(3, 3, 3, 3); __buttStyleHard.normal.background = Resources.Load("Fimp/Backgrounds/FbuttonH"); __buttStyleHard.hover.background = Resources.Load("Fimp/FbuttonHover"); __buttStyleHard.focused.background = __buttStyleHard.hover.background; __buttStyleHard.active.background = Resources.Load("Fimp/Backgrounds/ButtonStyle"); return __buttStyleHard; } } private static GUIStyle __buttStyleHard = null; bool Util_DrawButton(GUIContent content, Vector3 pos, float size, bool buttonBG = true, Vector2? rectOffset = null) { float sc = HandleUtility.GetHandleSize(pos); float hSize = Mathf.Sqrt(size) * 32 - sc * 16; if (hSize > 0f) { Handles.BeginGUI(); Vector2 pos2D = HandleUtility.WorldToGUIPoint(pos); float hhSize = hSize / 2f; GUIStyle style = buttonBG ? ButtonStyle : EditorStyles.label; if (rectOffset != null) pos2D += rectOffset.Value * hSize; if (GUI.Button(new Rect(pos2D.x - hhSize, pos2D.y - hhSize, hSize, hSize), content, style)) { Handles.EndGUI(); return true; } Handles.EndGUI(); } return false; } Color Util_IndexColor(int index, float s = 0.3f, float v = 0.45f, float hueOff = 0f, float hueMul = 1f) { float h = ((float)index * 0.1f * hueMul + 0.2f + hueOff) % 1; return Color.HSVToRGB(h, s, v); } void PingObject(UnityEngine.Object g) { EditorGUIUtility.PingObject(g); } } }