private static Vector2 GetWantedAnchorPosition(AnchoredJoint2D anchoredJoint2D, JointHelpers.AnchorBias bias, Vector2 position) { var wheelJoint2D = (WheelJoint2D)anchoredJoint2D; var otherBias = JointHelpers.GetOppositeBias(bias); var worldAngle = wheelJoint2D.transform.eulerAngles.z + wheelJoint2D.suspension.angle; var slideRay = new Ray(JointHelpers.GetAnchorPosition(wheelJoint2D, otherBias), Helpers2D.GetDirection(worldAngle)); var wantedAnchorPosition = Helpers2D.ClosestPointToRay(slideRay, position); return(wantedAnchorPosition); }
protected override IEnumerable <Vector2> GetSnapPositions(AnchoredJoint2D joint2D, AnchorInfo anchorInfo, JointHelpers.AnchorBias bias, Vector2 anchorPosition) { var sliderJoint2D = (SliderJoint2D)joint2D; var lockAnchors = SettingsHelper.GetOrCreate(sliderJoint2D).lockAnchors; var oppositeBias = JointHelpers.GetOppositeBias(bias); var oppositeAnchorPosition = JointHelpers.GetAnchorPosition(sliderJoint2D, oppositeBias); var snapPositions = new List <Vector2>(); Vector2[] targetPositions; if (joint2D.connectedBody) { targetPositions = new[] { GetTargetPosition(joint2D, JointHelpers.AnchorBias.Main), GetTargetPosition(joint2D, JointHelpers.AnchorBias.Connected) }; } else { targetPositions = new[] { GetTargetPosition(joint2D, JointHelpers.AnchorBias.Main) }; } if (sliderJoint2D.useLimits) { Ray slideRay; var min = sliderJoint2D.limits.min; var max = sliderJoint2D.limits.max; if (lockAnchors) { slideRay = new Ray(oppositeAnchorPosition, (anchorPosition - oppositeAnchorPosition).normalized); foreach (var targetPosition in targetPositions) { if (Vector2.Distance(oppositeAnchorPosition, targetPosition) <= AnchorEpsilon) { continue; } var fromConnectedToTarget = new Ray(oppositeAnchorPosition, (targetPosition - oppositeAnchorPosition).normalized); var closestPointToRay = Helpers2D.ClosestPointToRay(fromConnectedToTarget, anchorPosition); var ray = new Ray(oppositeAnchorPosition, (closestPointToRay - oppositeAnchorPosition).normalized); Vector2 wantedMinPosition = ray.GetPoint(min); Vector2 wantedMaxPosition = ray.GetPoint(max); snapPositions.Add(wantedMinPosition); snapPositions.Add(wantedMaxPosition); } } else { var worldAngle = sliderJoint2D.transform.eulerAngles.z + sliderJoint2D.angle; if (bias == JointHelpers.AnchorBias.Main) { worldAngle += 180; } slideRay = new Ray(oppositeAnchorPosition, Helpers2D.GetDirection(worldAngle)); } Vector2 minPos = slideRay.GetPoint(min); snapPositions.Add(minPos); Vector2 maxPos = slideRay.GetPoint(max); snapPositions.Add(maxPos); } if (lockAnchors) { //align onto the rays from either target towards the opposite bias foreach (var targetPosition in targetPositions) { if (Vector2.Distance(targetPosition, oppositeAnchorPosition) <= AnchorEpsilon) { continue; } var fromConnectedToTarget = new Ray(oppositeAnchorPosition, (targetPosition - oppositeAnchorPosition).normalized); // if (Helpers2D.DistanceToLine(fromConnectedToTarget, anchorPosition) < snapDistance) { var closestPointToRay = Helpers2D.ClosestPointToRay(fromConnectedToTarget, anchorPosition); snapPositions.Add(closestPointToRay); } } } if (!lockAnchors && !(Vector2.Distance(JointHelpers.GetMainAnchorPosition(joint2D), JointHelpers.GetConnectedAnchorPosition(joint2D)) <= AnchorEpsilon)) { var wantedAnchorPosition = GetWantedAnchorPosition(sliderJoint2D, bias, anchorPosition); snapPositions.Add(wantedAnchorPosition); } return(snapPositions); }
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); }