public static float AngleFromAnchor(Vector2 anchorPosition, Vector2 targetPosition, float targetRotation) { float angle; if (Vector3.Distance(targetPosition, anchorPosition) > AnchorEpsilon) { Vector3 towardsTarget = (targetPosition - anchorPosition).normalized; angle = Helpers2D.GetAngle(towardsTarget); } else { angle = targetRotation; } return(angle); }
protected override void ReAlignAnchors(AnchoredJoint2D joint2D, JointHelpers.AnchorBias alignmentBias) { var sliderJoint2D = (SliderJoint2D)joint2D; //align the angle to the connected anchor var direction = JointHelpers.GetConnectedAnchorPosition(joint2D) - JointHelpers.GetMainAnchorPosition(joint2D); if (direction.magnitude > AnchorEpsilon) { var wantedAngle = Helpers2D.GetAngle(direction); EditorHelpers.RecordUndo("Realign angle", sliderJoint2D); sliderJoint2D.angle = wantedAngle - sliderJoint2D.transform.eulerAngles.z; } }
private void DrawLinesAndDiscs(HingeJoint2D hingeJoint2D, AnchorInfo anchorInfo, JointHelpers.AnchorBias bias) { var center = JointHelpers.GetAnchorPosition(hingeJoint2D, bias); var scale = editorSettings.anchorScale; var handleSize = HandleUtility.GetHandleSize(center) * scale; var mainBodyPosition = GetTargetPosition(hingeJoint2D, JointHelpers.AnchorBias.Main); var connectedBodyPosition = GetTargetPosition(hingeJoint2D, JointHelpers.AnchorBias.Connected); var settings = SettingsHelper.GetOrCreate <HingeJoint2DSettings>(hingeJoint2D); if (bias == JointHelpers.AnchorBias.Main) { float angleToMain; if (Vector2.Distance(mainBodyPosition, center) > AnchorEpsilon) { angleToMain = Helpers2D.GetAngle(mainBodyPosition - center); } else { angleToMain = JointHelpers.GetTargetRotation(hingeJoint2D, JointHelpers.AnchorBias.Main); } using (new HandleColor(GetAdjustedColor(editorSettings.anchorsToMainBodyColor))) { Handles.DrawLine(center, center + Helpers2D.GetDirection(angleToMain + settings.mainAngleOffset) * handleSize); } } else if (bias == JointHelpers.AnchorBias.Connected) { if (hingeJoint2D.connectedBody) { float angleToConnected; if (Vector2.Distance(connectedBodyPosition, center) > AnchorEpsilon) { angleToConnected = Helpers2D.GetAngle(connectedBodyPosition - center); } else { angleToConnected = JointHelpers.GetTargetRotation(hingeJoint2D, JointHelpers.AnchorBias.Connected); } using (new HandleColor(GetAdjustedColor(editorSettings.anchorsToConnectedBodyColor))) { Handles.DrawLine(center, center + Helpers2D.GetDirection(angleToConnected + settings.connectedAngleOffset) * handleSize); } } else { using (new HandleColor(GetAdjustedColor(editorSettings.anchorsToConnectedBodyColor))) { Handles.DrawLine(center, center + Helpers2D.GetDirection(settings.connectedAngleOffset) * handleSize); } } } if (settings.showDiscs) { var sliderControlID = anchorInfo.GetControlID("slider"); if (editorSettings.ringDisplayMode == JointEditorSettings.RingDisplayMode.Always || (editorSettings.ringDisplayMode == JointEditorSettings.RingDisplayMode.Hover && //if nothing else is hot and we are being hovered, or the anchor's widgets are hot ((GUIUtility.hotControl == 0 && HandleUtility.nearestControl == sliderControlID) || GUIUtility.hotControl == sliderControlID)) ) { using (new HandleColor(GetAdjustedColor(editorSettings.mainRingColor))) { Handles.DrawWireDisc(center, Vector3.forward, Vector2.Distance(center, mainBodyPosition)); } if (hingeJoint2D.connectedBody) { using (new HandleColor((editorSettings.connectedRingColor))) { Handles.DrawWireDisc(center, Vector3.forward, Vector2.Distance(center, connectedBodyPosition)); } } } } HandleUtility.Repaint(); }
private void DrawDistance(T jointWithDistance, AnchorInfo anchorInfo, JointHelpers.AnchorBias bias) { if (jointWithDistance == null) { return; } var otherBias = bias == JointHelpers.AnchorBias.Main ? JointHelpers.AnchorBias.Connected : JointHelpers.AnchorBias.Main; var anchorPosition = JointHelpers.GetAnchorPosition(jointWithDistance, bias); var otherAnchorPosition = JointHelpers.GetAnchorPosition(jointWithDistance, otherBias); var diff = anchorPosition - otherAnchorPosition; if (diff.magnitude <= Mathf.Epsilon) { diff = Vector2.up * (bias == JointHelpers.AnchorBias.Connected ? 1 : -1); } var normalizedDiff = diff.normalized; JointHelpers.AnchorBias wantedBias; switch (GetSettings(jointWithDistance).anchorPriority) { case JointSettingsWithBias.AnchorPriority.Main: wantedBias = JointHelpers.AnchorBias.Main; break; case JointSettingsWithBias.AnchorPriority.Connected: wantedBias = JointHelpers.AnchorBias.Connected; break; default: throw new ArgumentOutOfRangeException(); } if (bias == wantedBias && EditorGUI.actionKey && GUIUtility.hotControl == anchorInfo.GetControlID("slider")) { Handles.DrawWireDisc(otherAnchorPosition, Vector3.forward, GetDistance(jointWithDistance)); } if (bias != wantedBias) { var distanceControlID = anchorInfo.GetControlID("distance"); EditorGUI.BeginChangeCheck(); float newDistance; using ( new HandleColor(isCreatedByTarget ? new Color(1, 1, 1, editorSettings.connectedJointTransparency) : Color.white)) { newDistance = EditorHelpers.LineSlider(distanceControlID, otherAnchorPosition, GetDistance(jointWithDistance), Helpers2D.GetAngle(normalizedDiff), 0.125f, true); EditorHelpers.DrawThickLine(anchorPosition, otherAnchorPosition + normalizedDiff * newDistance, Vector2.Distance(anchorPosition, otherAnchorPosition) > newDistance ? 2 : 1, true); } if (Event.current.type == EventType.repaint) { if (EditorHelpers.IsWarm(distanceControlID) && DragAndDrop.objectReferences.Length == 0) { var labelContent = new GUIContent(string.Format("Distance: {0:0.00}", GetDistance(jointWithDistance))); var sliderPosition = otherAnchorPosition + normalizedDiff * GetDistance(jointWithDistance); var fontSize = HandleUtility.GetHandleSize(sliderPosition) * (1f / 64f); var labelOffset = fontSize * EditorHelpers.FontWithBackgroundStyle.CalcSize(labelContent).y + fontSize * 20 * Mathf.Abs(Mathf.Cos(Mathf.Deg2Rad * Helpers2D.GetAngle(normalizedDiff))); EditorHelpers.OverlayLabel((Vector3)sliderPosition + (Camera.current.transform.up * labelOffset), labelContent, EditorHelpers.FontWithBackgroundStyle); } } if (EditorGUI.EndChangeCheck()) { using (new Modification("Change Distance", jointWithDistance)) { if (newDistance < 0) { SetDistance(jointWithDistance, 0f); } else { var distanceBetweenAnchors = Vector2.Distance(otherAnchorPosition, anchorPosition); SetDistance(jointWithDistance, EditorGUI.actionKey && Mathf.Abs(newDistance - distanceBetweenAnchors) < HandleUtility.GetHandleSize(anchorPosition) * 0.125f ? distanceBetweenAnchors : newDistance); } } } DistanceContext(jointWithDistance, distanceControlID); } }
private static void DrawLimitSlider(SliderJoint2D sliderJoint2D, int limitControlID, Vector2 anchorPosition, Vector2 direction, IEnumerable <Vector2> snapList, Limit limit) { EditorGUI.BeginChangeCheck(); float val; var limits2D = sliderJoint2D.limits; switch (limit) { case Limit.Min: val = limits2D.min; break; case Limit.Max: val = limits2D.max; break; default: throw new ArgumentOutOfRangeException("limit"); } var newLimit = EditorHelpers.LineSlider(limitControlID, anchorPosition, val, Helpers2D.GetAngle(direction), 0.125f, false, limit == Limit.Min); if (!EditorGUI.EndChangeCheck()) { return; } if (snapList != null) { var limitSnapList = new List <Vector2>(snapList); switch (limit) { case Limit.Min: limitSnapList.Add(anchorPosition + direction * limits2D.max); break; case Limit.Max: limitSnapList.Add(anchorPosition + direction * limits2D.min); break; default: throw new ArgumentOutOfRangeException("limit"); } var limitGUIPosition = HandleUtility.WorldToGUIPoint(anchorPosition + direction * newLimit); foreach ( var snapPosition in from snapPosition in limitSnapList let snapGUIPosition = HandleUtility.WorldToGUIPoint(snapPosition) where Vector2.Distance(limitGUIPosition, snapGUIPosition) < 10 select snapPosition) { newLimit = Helpers2D.DistanceAlongLine(new Ray(anchorPosition, direction), snapPosition); } } EditorHelpers.RecordUndo("Change slider limit", sliderJoint2D); switch (limit) { case Limit.Min: limits2D.min = newLimit; break; case Limit.Max: limits2D.max = newLimit; break; default: throw new ArgumentOutOfRangeException("limit"); } sliderJoint2D.limits = limits2D; }
private void LimitWidget(SliderJoint2D sliderJoint2D, AnchorInfo anchorInfo, JointHelpers.AnchorBias bias, float worldAngle) { var anchorPosition = JointHelpers.GetAnchorPosition(sliderJoint2D, bias); var oppositeBias = JointHelpers.GetOppositeBias(bias); var oppositeAnchorPosition = JointHelpers.GetAnchorPosition(sliderJoint2D, oppositeBias); var direction = Helpers2D.GetDirection(worldAngle); if (bias == JointHelpers.AnchorBias.Connected) { direction *= -1f; } var delta = oppositeAnchorPosition - anchorPosition; var angleDiff = Mathf.DeltaAngle(Helpers2D.GetAngle(delta), worldAngle); Vector2 rotatedDelta = Helpers2D.Rotate(angleDiff) * delta; var wantedOppositeAnchorPosition = anchorPosition + rotatedDelta; var wantedOppositeAnchorPosition2 = anchorPosition - rotatedDelta; var minLimitControlID = anchorInfo.GetControlID("minLimit"); var maxLimitControlID = anchorInfo.GetControlID("maxLimit"); LimitContext(sliderJoint2D, minLimitControlID, Limit.Min); LimitContext(sliderJoint2D, maxLimitControlID, Limit.Max); var limitColor = sliderJoint2D.limits.min > sliderJoint2D.limits.max ? editorSettings.incorrectLimitsColor : editorSettings.correctLimitsColor; if (isCreatedByTarget) { limitColor.a *= editorSettings.connectedJointTransparency; } using (new HandleColor(limitColor)) { Handles.DrawLine(anchorPosition + direction * sliderJoint2D.limits.min, anchorPosition + direction * sliderJoint2D.limits.max); if (Event.current.type == EventType.repaint) { float fontSize; if (EditorHelpers.IsWarm(minLimitControlID) && DragAndDrop.objectReferences.Length == 0) { var labelContent = new GUIContent(string.Format("Min: {0:0.00}", sliderJoint2D.limits.min)); var sliderPosition = anchorPosition + (direction) * (sliderJoint2D.limits.min); fontSize = HandleUtility.GetHandleSize(sliderPosition) * ONE_OVER64; var labelOffset = fontSize * EditorHelpers.FontWithBackgroundStyle.CalcSize(labelContent).y + fontSize * 20 * Mathf.Abs(Mathf.Cos(Mathf.Deg2Rad * Helpers2D.GetAngle(direction))); EditorHelpers.OverlayLabel((Vector3)sliderPosition + (Camera.current.transform.up * labelOffset), labelContent, EditorHelpers.FontWithBackgroundStyle); } if (EditorHelpers.IsWarm(maxLimitControlID) && DragAndDrop.objectReferences.Length == 0) { var labelContent = new GUIContent(string.Format("Max: {0:0.00}", sliderJoint2D.limits.max)); var sliderPosition = anchorPosition + (direction) * (sliderJoint2D.limits.max); fontSize = HandleUtility.GetHandleSize(sliderPosition) * ONE_OVER64; var labelOffset = fontSize * EditorHelpers.FontWithBackgroundStyle.CalcSize(labelContent).y + fontSize * 20 * Mathf.Abs(Mathf.Cos(Mathf.Deg2Rad * Helpers2D.GetAngle(direction))); EditorHelpers.OverlayLabel((Vector3)sliderPosition + (Camera.current.transform.up * labelOffset), labelContent, EditorHelpers.FontWithBackgroundStyle); } } if (GUIUtility.hotControl == minLimitControlID || GUIUtility.hotControl == maxLimitControlID) { using ( new HandleColor(new Color(1, 1, 1, 0.25f * (isCreatedByTarget ? editorSettings.connectedJointTransparency : 1.0f)))) { var handleSize = HandleUtility.GetHandleSize(wantedOppositeAnchorPosition) * ONE_OVER16; Handles.DrawLine(wantedOppositeAnchorPosition - direction * handleSize, wantedOppositeAnchorPosition + direction * handleSize); handleSize = HandleUtility.GetHandleSize(wantedOppositeAnchorPosition2) * ONE_OVER16; Handles.DrawLine(wantedOppositeAnchorPosition2 - direction * handleSize, wantedOppositeAnchorPosition2 + direction * handleSize); Handles.DrawWireArc(anchorPosition, Vector3.forward, wantedOppositeAnchorPosition, 360, Vector2.Distance(wantedOppositeAnchorPosition, anchorPosition)); } } var actionKey = EditorGUI.actionKey; List <Vector2> snapList = null; if (actionKey) { snapList = new List <Vector2> { anchorPosition, wantedOppositeAnchorPosition, wantedOppositeAnchorPosition2 }; } var minLimitColor = editorSettings.minLimitColor; var maxLimitColor = editorSettings.maxLimitColor; if (isCreatedByTarget) { minLimitColor.a *= editorSettings.connectedJointTransparency; maxLimitColor.a *= editorSettings.connectedJointTransparency; } using (new HandleColor(minLimitColor)) { DrawLimitSlider(sliderJoint2D, minLimitControlID, anchorPosition, direction, snapList, Limit.Min); } using (new HandleColor(maxLimitColor)) { DrawLimitSlider(sliderJoint2D, maxLimitControlID, anchorPosition, direction, snapList, Limit.Max); } } }
protected void DrawAngleWidget(TJointType joint2D, int controlID) { var joint2DSettings = GetSettings(joint2D); var worldAngle = joint2D.transform.eulerAngles.z + GetAngle(joint2D); HandleDragDrop(controlID, joint2D, joint2DSettings); EditorGUI.BeginChangeCheck(); JointHelpers.AnchorBias bias; if (joint2DSettings.anchorPriority == JointSettingsWithBias.AnchorPriority.Main) { bias = JointHelpers.AnchorBias.Main; } else { bias = JointHelpers.AnchorBias.Connected; } var oppositeBias = JointHelpers.GetOppositeBias(bias); var angleWidgetPosition = JointHelpers.GetAnchorPosition(joint2D, bias); var otherAnchorPosition = JointHelpers.GetAnchorPosition(joint2D, oppositeBias); var offsetToOther = otherAnchorPosition - angleWidgetPosition; var newAngle = LineAngleHandle(controlID, worldAngle, angleWidgetPosition, 0.5f, 2); var mousePosition = Event.current.mousePosition; EditorHelpers.ContextClick(controlID, () => { var menu = new GenericMenu(); AddEditAngleMenuItem(joint2D, menu, mousePosition); menu.ShowAsContext(); }); if (!EditorGUI.EndChangeCheck()) { return; } var snapped = false; if (EditorGUI.actionKey) { var handleSize = HandleUtility.GetHandleSize(angleWidgetPosition); var mousePosition2D = Helpers2D.GUIPointTo2DPosition(Event.current.mousePosition); var currentAngleRay = new Ray(angleWidgetPosition, Helpers2D.GetDirection(newAngle)); var mousePositionProjectedToAngle = Helpers2D.ClosestPointToRay(currentAngleRay, mousePosition2D); var directionsToSnapTo = new List <Vector2> { (GetTargetPosition(joint2D, bias) - angleWidgetPosition).normalized }; if (!joint2DSettings.lockAnchors) { directionsToSnapTo.Insert(0, offsetToOther.normalized); } if (joint2D.connectedBody) { directionsToSnapTo.Add( (GetTargetPosition(joint2D, oppositeBias) - angleWidgetPosition) .normalized); } foreach (var direction in directionsToSnapTo) { var rayTowardsDirection = new Ray(angleWidgetPosition, direction); var closestPointTowardsDirection = Helpers2D.ClosestPointToRay(rayTowardsDirection, mousePositionProjectedToAngle); if (Vector2.Distance(closestPointTowardsDirection, mousePositionProjectedToAngle) < handleSize * 0.125f) { var currentDirection = Helpers2D.GetDirection(newAngle); var closestPositionToDirection = Helpers2D.ClosestPointToRay(rayTowardsDirection, angleWidgetPosition + currentDirection); snapped = true; newAngle = Helpers2D.GetAngle(closestPositionToDirection - angleWidgetPosition); break; } } } var wantedAngle = newAngle - joint2D.transform.eulerAngles.z; if (!snapped) { wantedAngle = Handles.SnapValue(wantedAngle, editorSettings.snapAngle); } EditorHelpers.RecordUndo("Alter Angle", joint2D); if (joint2DSettings.lockAnchors) { var angleDelta = Mathf.DeltaAngle(GetAngle(joint2D), wantedAngle); JointHelpers.SetWorldAnchorPosition(joint2D, angleWidgetPosition + (Vector2)(Helpers2D.Rotate(angleDelta) * offsetToOther), oppositeBias); } SetAngle(joint2D, wantedAngle); }