protected override IEnumerable <Vector2> GetSnapPositions(AnchoredJoint2D joint2D, AnchorInfo anchorInfo,
                                                              JointHelpers.AnchorBias bias, Vector2 anchorPosition)
    {
        if (!EditorGUI.actionKey)
        {
            return(null);
        }

        var otherBias = bias == JointHelpers.AnchorBias.Main
            ? JointHelpers.AnchorBias.Connected
            : JointHelpers.AnchorBias.Main;

        var jointWithDistance = (T)joint2D;

        var anchorSliderState     = StateObject.Get <AnchorSliderState>(anchorInfo.GetControlID("slider"));
        var currentMousePosition  = Helpers2D.GUIPointTo2DPosition(Event.current.mousePosition);
        var currentAnchorPosition = currentMousePosition - anchorSliderState.mouseOffset;

        var otherAnchorPosition = JointHelpers.GetAnchorPosition(jointWithDistance, otherBias);
        var diff = otherAnchorPosition - currentAnchorPosition;

        if (diff.magnitude <= Mathf.Epsilon)
        {
            diff = -Vector2.up;
        }

        var normalizedDiff = diff.normalized;

        var wantedAnchorPosition = otherAnchorPosition - normalizedDiff * GetDistance(jointWithDistance);

        return(new[] { wantedAnchorPosition });
    }
Example #2
0
    protected override bool SingleAnchorGUI(AnchoredJoint2D joint2D, AnchorInfo anchorInfo, JointHelpers.AnchorBias bias)
    {
        var sliderJoint2D = (SliderJoint2D)joint2D;

        var mainAnchorPosition      = JointHelpers.GetMainAnchorPosition(sliderJoint2D);
        var connectedAnchorPosition = JointHelpers.GetConnectedAnchorPosition(sliderJoint2D);

        var sliderAngleControlID = anchorInfo.GetControlID("sliderAngle");

        if (bias != JointHelpers.AnchorBias.Connected &&
            (
                GUIUtility.hotControl == sliderAngleControlID ||
                GUIUtility.hotControl == anchorInfo.GetControlID("minLimit") ||
                GUIUtility.hotControl == anchorInfo.GetControlID("maxLimit") ||
                !Event.current.shift))
        {
            DrawAngleWidget(sliderJoint2D, sliderAngleControlID);

            if (sliderJoint2D.useLimits)
            {
                HandleLimits(sliderJoint2D, anchorInfo);
            }
        }

        if (GUIUtility.hotControl == anchorInfo.GetControlID("slider"))
        {
            var snap = GetWantedAnchorPosition(sliderJoint2D, bias);
            using (
                new HandleColor(new Color(1, 1, 1,
                                          isCreatedByTarget ? .5f * editorSettings.connectedJointTransparency : .5f))) {
                Handles.DrawLine(connectedAnchorPosition, snap);
                Handles.DrawLine(mainAnchorPosition, snap);
            }
        }

        using (
            new HandleColor(new Color(1, 1, 1,
                                      0.125f * (isCreatedByTarget ? editorSettings.connectedJointTransparency : 1.0f)))) {
            Handles.DrawLine(mainAnchorPosition, connectedAnchorPosition);
            if (sliderJoint2D.connectedBody && GUIUtility.hotControl == sliderAngleControlID)
            {
                Handles.DrawLine(mainAnchorPosition, GetTargetPosition(sliderJoint2D, JointHelpers.AnchorBias.Connected));
            }
        }
        return(false);
    }
Example #3
0
    protected override bool PostAnchorGUI(AnchoredJoint2D joint2D, AnchorInfo info, List <Vector2> otherAnchors,
                                          JointHelpers.AnchorBias bias)
    {
        var sliderJoint2D = joint2D as SliderJoint2D;

        if (sliderJoint2D == null)
        {
            return(false);
        }

        if (Event.current.type == EventType.repaint)
        {
            if (!EditorHelpers.IsWarm(info.GetControlID("sliderAngle")) || DragAndDrop.objectReferences.Length != 0)
            {
                return(false);
            }
            var suspensionAngle = sliderJoint2D.angle;

            var     labelContent       = new GUIContent(String.Format("{0:0.00}", suspensionAngle));
            Vector3 mainAnchorPosition = Helpers2D.GUIPointTo2DPosition(Event.current.mousePosition);

            var fontSize = HandleUtility.GetHandleSize(mainAnchorPosition) * ONE_OVER64;

            var labelOffset = fontSize * EditorHelpers.FontWithBackgroundStyle.CalcSize(labelContent).y;

            EditorHelpers.OverlayLabel(mainAnchorPosition + (Camera.current.transform.up * labelOffset),
                                       labelContent,
                                       EditorHelpers.FontWithBackgroundStyle);
        }
        else
        {
            if (!EditorHelpers.IsWarm(info.GetControlID("sliderAngle")) || DragAndDrop.objectReferences.Length != 0)
            {
                return(false);
            }
            if (SceneView.lastActiveSceneView)
            {
                SceneView.lastActiveSceneView.Repaint();
            }
        }

        return(false);
    }
    protected override bool SingleAnchorGUI(AnchoredJoint2D joint2D, AnchorInfo anchorInfo, JointHelpers.AnchorBias bias)
    {
        var wheelJoint2D = (WheelJoint2D)joint2D;

        var mainAnchorPosition      = JointHelpers.GetMainAnchorPosition(wheelJoint2D);
        var connectedAnchorPosition = JointHelpers.GetConnectedAnchorPosition(wheelJoint2D);

        var suspensionAngleControlID = anchorInfo.GetControlID("suspensionAngle");


        if (bias != JointHelpers.AnchorBias.Connected &&
            (GUIUtility.hotControl == suspensionAngleControlID || !Event.current.shift))
        {
            DrawAngleWidget(wheelJoint2D, suspensionAngleControlID);
        }

        var snapLineColor = GetAdjustedColor(new Color(1, 1, 1, .5f));

        //if the joint anchors are being moved, then show snap lines
        var sliderControlID = anchorInfo.GetControlID("slider");

        if (GUIUtility.hotControl == sliderControlID)
        {
            var snap = GetWantedAnchorPosition(wheelJoint2D, bias);
            using (new HandleColor(snapLineColor)) {
                Handles.DrawLine(connectedAnchorPosition, snap);
                Handles.DrawLine(mainAnchorPosition, snap);
            }
        }

        using (new HandleColor(snapLineColor))
        {
            Handles.DrawLine(mainAnchorPosition, connectedAnchorPosition);
            if (wheelJoint2D.connectedBody && GUIUtility.hotControl == suspensionAngleControlID)
            {
                Handles.DrawLine(mainAnchorPosition, GetTargetPosition(wheelJoint2D, JointHelpers.AnchorBias.Connected));
            }
        }
        return(false);
    }
Example #5
0
    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();
    }
Example #6
0
    private static bool HandleMainLimits(HingeJoint2D hingeJoint2D, AnchorInfo anchorInfo, Color limitAreaColor,
                                         float limitDifference, Vector2 anchorPosition, float distanceFromCenter,
                                         float maxMainAngle, HingeJoint2DSettings settings, Color limitColor,
                                         float minMainAngle, Color angleWidgetColor, Color activeAngleColor,
                                         Color hoverAngleColor, float angleHandleSize, JointAngleLimits2D limits,
                                         float liveMainAngle)
    {
        var changed = false;

        using (new HandleColor(limitAreaColor)) {
            if (limitDifference > 360)
            {
                Handles.DrawSolidDisc(anchorPosition, Vector3.forward, distanceFromCenter);
            }
            else
            {
                Handles.DrawSolidArc(anchorPosition, Vector3.forward,
                                     Helpers2D.GetDirection(maxMainAngle + settings.mainAngleOffset),
                                     limitDifference, distanceFromCenter);
            }
        }
        using (new HandleColor(limitColor)) {
            Vector3 minMainEnd = anchorPosition +
                                 Helpers2D.GetDirection(minMainAngle + settings.mainAngleOffset) *
                                 distanceFromCenter;
            Handles.DrawLine(anchorPosition, minMainEnd);

            Vector3 maxMainEnd = anchorPosition +
                                 Helpers2D.GetDirection(maxMainAngle + settings.mainAngleOffset) *
                                 distanceFromCenter;
            Handles.DrawLine(anchorPosition, maxMainEnd);

            if (limitDifference > 360)
            {
                Handles.DrawWireDisc(anchorPosition, Vector3.forward, distanceFromCenter);
            }
            else
            {
                Handles.DrawWireArc(anchorPosition, Vector3.forward,
                                    Helpers2D.GetDirection(maxMainAngle + settings.mainAngleOffset),
                                    limitDifference, distanceFromCenter);
            }


            EditorGUI.BeginChangeCheck();
            using (
                HandleDrawerBase drawer = new HandleCircleDrawer(angleWidgetColor, activeAngleColor,
                                                                 hoverAngleColor)) {
                minMainAngle = EditorHelpers.AngleSlider(anchorInfo.GetControlID("lowerMainAngle"), drawer,
                                                         anchorPosition,
                                                         minMainAngle + settings.mainAngleOffset,
                                                         distanceFromCenter, angleHandleSize * HandleUtility.GetHandleSize(minMainEnd) / 64) -
                               settings.mainAngleOffset;
            }

            if (EditorGUI.EndChangeCheck())
            {
                EditorHelpers.RecordUndo("Change Angle Limits", hingeJoint2D);
                limits.min          = Handles.SnapValue(liveMainAngle - minMainAngle, editorSettings.snapAngle);
                hingeJoint2D.limits = limits;
                changed             = true;
            }

            EditorGUI.BeginChangeCheck();
            using (
                HandleDrawerBase drawer = new HandleCircleDrawer(angleWidgetColor,
                                                                 activeAngleColor, hoverAngleColor)) {
                maxMainAngle = EditorHelpers.AngleSlider(anchorInfo.GetControlID("upperMainAngle"), drawer,
                                                         anchorPosition,
                                                         maxMainAngle + settings.mainAngleOffset,
                                                         distanceFromCenter, angleHandleSize * HandleUtility.GetHandleSize(maxMainEnd) / 64) -
                               settings.mainAngleOffset;
            }

            if (EditorGUI.EndChangeCheck())
            {
                EditorHelpers.RecordUndo("Change Angle Limits", hingeJoint2D);
                limits.max          = Handles.SnapValue(liveMainAngle - maxMainAngle, editorSettings.snapAngle);
                hingeJoint2D.limits = limits;
                changed             = true;
            }
        }
        return(changed);
    }
Example #7
0
    protected override bool PostAnchorGUI(AnchoredJoint2D joint2D, AnchorInfo info, List <Vector2> otherAnchors,
                                          JointHelpers.AnchorBias bias)
    {
        var hingeJoint2D = joint2D as HingeJoint2D;

        if (hingeJoint2D == null)
        {
            return(false);
        }

        if (!hingeJoint2D.useLimits)
        {
            return(false);
        }

        var   showAngle    = false;
        float angle        = 0;
        float displayAngle = 0;

        float jointAngle;

        if (EditorApplication.isPlayingOrWillChangePlaymode || Application.isPlaying)
        {
            jointAngle = hingeJoint2D.jointAngle;
        }
        else
        {
            jointAngle = 0;
        }

        var startPosition = JointHelpers.GetAnchorPosition(hingeJoint2D, bias);

        var mainBodyPosition = GetTargetPosition(hingeJoint2D, JointHelpers.AnchorBias.Main);

        var mainBodyAngle = JointHelpers.AngleFromAnchor(startPosition, mainBodyPosition,
                                                         JointHelpers.GetTargetRotation(hingeJoint2D, JointHelpers.AnchorBias.Main));

        var connectedBodyPosition = GetTargetPosition(hingeJoint2D, JointHelpers.AnchorBias.Connected);

        float connectedBodyAngle;

        if (hingeJoint2D.connectedBody)
        {
            connectedBodyAngle = JointHelpers.AngleFromAnchor(startPosition, connectedBodyPosition,
                                                              JointHelpers.GetTargetRotation(hingeJoint2D, JointHelpers.AnchorBias.Connected));
        }
        else
        {
            connectedBodyAngle = 0;
        }

        var angleDiff = jointAngle - (connectedBodyAngle - mainBodyAngle);

        var liveMainAngle = connectedBodyAngle + angleDiff;

        var minMainAngle = liveMainAngle - hingeJoint2D.limits.min;
        var maxMainAngle = liveMainAngle - hingeJoint2D.limits.max;

        var labelText = "";

        float angleOffset = 0;

        var settings = SettingsHelper.GetOrCreate <HingeJoint2DSettings>(hingeJoint2D);

        if (EditorHelpers.IsWarm(info.GetControlID("lowerMainAngle")))
        {
            showAngle    = true;
            angle        = minMainAngle;
            displayAngle = hingeJoint2D.limits.min;
            labelText    = "Lower: ";
            angleOffset  = settings.mainAngleOffset;
        }
        else if (EditorHelpers.IsWarm(info.GetControlID("upperMainAngle")))
        {
            showAngle    = true;
            angle        = maxMainAngle;
            displayAngle = hingeJoint2D.limits.max;
            labelText    = "Upper: ";
            angleOffset  = settings.mainAngleOffset;
        }
        else if (EditorHelpers.IsWarm(info.GetControlID("lowerConnectedAngle")))
        {
            showAngle     = true;
            angle         = hingeJoint2D.limits.min;
            displayAngle  = angle;
            labelText     = "Lower: ";
            startPosition = JointHelpers.GetConnectedAnchorPosition(hingeJoint2D);
            angleOffset   = settings.connectedAngleOffset;
        }
        else if (EditorHelpers.IsWarm(info.GetControlID("upperConnectedAngle")))
        {
            showAngle     = true;
            angle         = hingeJoint2D.limits.max;
            labelText     = "Upper: ";
            displayAngle  = angle;
            startPosition = JointHelpers.GetConnectedAnchorPosition(hingeJoint2D);
            angleOffset   = settings.connectedAngleOffset;
        }

        LimitContext(hingeJoint2D, info.GetControlID("lowerMainAngle"), Limit.Min);
        LimitContext(hingeJoint2D, info.GetControlID("upperMainAngle"), Limit.Max);
        LimitContext(hingeJoint2D, info.GetControlID("lowerConnectedAngle"), Limit.Min);
        LimitContext(hingeJoint2D, info.GetControlID("upperConnectedAngle"), Limit.Max);

        if (showAngle)
        {
            var distanceFromCenter = GetAngleSliderRadius(startPosition);


            var anglePosition = startPosition + Helpers2D.GetDirection(angle + angleOffset) * distanceFromCenter;

            var labelContent = new GUIContent(labelText + "\n" + String.Format("{0:0.00}", displayAngle));

            var fontSize = HandleUtility.GetHandleSize(anglePosition) * (1f / 64f);

            var labelOffset = fontSize * EditorHelpers.FontWithBackgroundStyle.CalcSize(labelContent).y;

            EditorHelpers.OverlayLabel((Vector3)anglePosition + (Camera.current.transform.up * labelOffset),
                                       labelContent,
                                       EditorHelpers.FontWithBackgroundStyle);
        }
        return(false);
    }
    protected void AnchorGUI(AnchoredJoint2D joint2D)
    {
        var jointSettings = SettingsHelper.GetOrCreate(joint2D);

        var anchorLock = WantsLocking() && jointSettings.lockAnchors;

        var playing = EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPaused;
        var worldAnchor = JointHelpers.GetMainAnchorPosition(joint2D);
        var worldConnectedAnchor = JointHelpers.GetConnectedAnchorPosition(joint2D);

        var overlapping = Vector2.Distance(worldConnectedAnchor, worldAnchor) <= AnchorEpsilon;

        var changed = false;

        AnchorInfo main = new AnchorInfo(controlNames),
                   connected = new AnchorInfo(controlNames),
                   locked = new AnchorInfo(controlNames);

        if (jointAnchorInfos.ContainsKey(joint2D)) {
            jointAnchorInfos[joint2D].Clear();
        } else {
            jointAnchorInfos[joint2D] = new List<AnchorInfo>();
        }

        jointAnchorInfos[joint2D].AddRange(new[] {
            main, connected, locked
        });

        var otherAnchors = GetAllAnchorsInSelection(joint2D);

        if (anchorLock && DragBothAnchorsWhenLocked()) {
            if (playing || overlapping) {
                if (AnchorDraggingWidgetGUI(joint2D, locked, otherAnchors, JointHelpers.AnchorBias.Either)) {
                    changed = true;
                }
            } else {
                //draw the locks instead, force them to show
                if (ToggleLockButton(main.GetControlID("lock"), joint2D, JointHelpers.AnchorBias.Main)) {
                    changed = true;
                }
                if (ToggleLockButton(connected.GetControlID("lock"), joint2D, JointHelpers.AnchorBias.Connected)) {
                    changed = true;
                }
            }

            if (!changed) {
                changed = PostAnchorGUI(joint2D, locked, otherAnchors, JointHelpers.AnchorBias.Either);
            }
        } else {
            if (AnchorDraggingWidgetGUI(joint2D, connected, otherAnchors, JointHelpers.AnchorBias.Connected)) {
                changed = true;
                if (anchorLock) {
                    ReAlignAnchors(joint2D, JointHelpers.AnchorBias.Connected);
                }
            }

            if (AnchorDraggingWidgetGUI(joint2D, main, otherAnchors, JointHelpers.AnchorBias.Main)) {
                changed = true;
                if (anchorLock) {
                    ReAlignAnchors(joint2D, JointHelpers.AnchorBias.Main);
                }
            }

            if (!changed) {
                changed = PostAnchorGUI(joint2D, main, otherAnchors, JointHelpers.AnchorBias.Main)
                          || PostAnchorGUI(joint2D, connected, otherAnchors, JointHelpers.AnchorBias.Connected);
            }
        }

        if (changed) {
            EditorUtility.SetDirty(joint2D);
        }
    }
    protected bool AnchorDraggingWidgetGUI(AnchoredJoint2D joint2D, AnchorInfo anchorInfo,
        IEnumerable<Vector2> otherAnchors, JointHelpers.AnchorBias bias)
    {
        var lockID = anchorInfo.GetControlID("lock");

        var changed = PreSliderGUI(joint2D, anchorInfo, bias);

        if (!changed && WantsLocking() && (Event.current.shift || GUIUtility.hotControl == lockID) &&
            (GUIUtility.hotControl == lockID || !anchorInfo.IsActive())) {
            var farAway =
                Vector2.Distance(
                    JointHelpers.GetMainAnchorPosition(joint2D),
                    GetWantedAnchorPosition(joint2D, JointHelpers.AnchorBias.Main)
                    ) > AnchorEpsilon
                || Vector2.Distance(
                    JointHelpers.GetConnectedAnchorPosition(joint2D),
                    GetWantedAnchorPosition(joint2D, JointHelpers.AnchorBias.Connected)
                    ) > AnchorEpsilon;

            if (SettingsHelper.GetOrCreate(joint2D)
                              .lockAnchors && (bias == JointHelpers.AnchorBias.Either || !farAway)) {
                //locked! show unlock
                if (ToggleUnlockButton(lockID, joint2D, bias)) {
                    changed = true;
                }
            } else {
                if (ToggleLockButton(lockID, joint2D, bias)) {
                    changed = true;
                }
            }
        } else if (SliderGUI(joint2D, anchorInfo, otherAnchors, bias)) {
            changed = true;
        }

        if (bias == JointHelpers.AnchorBias.Either) {
            DrawLineToBody(joint2D, JointHelpers.AnchorBias.Main);
            DrawLineToBody(joint2D, JointHelpers.AnchorBias.Connected);
        } else {
            DrawLineToBody(joint2D, bias);
        }

        changed = SingleAnchorGUI(joint2D, anchorInfo, bias) || changed;

        return changed;
    }
    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 static bool HandleMainLimits(HingeJoint2D hingeJoint2D, AnchorInfo anchorInfo, Color limitAreaColor,
        float limitDifference, Vector2 anchorPosition, float distanceFromCenter,
        float maxMainAngle, HingeJoint2DSettings settings, Color limitColor,
        float minMainAngle, Color angleWidgetColor, Color activeAngleColor,
        Color hoverAngleColor, float angleHandleSize, JointAngleLimits2D limits,
        float liveMainAngle)
    {
        var changed = false;
        using (new HandleColor(limitAreaColor)) {
            if (limitDifference > 360) {
                Handles.DrawSolidDisc(anchorPosition, Vector3.forward, distanceFromCenter);
            } else {
                Handles.DrawSolidArc(anchorPosition, Vector3.forward,
                    Helpers2D.GetDirection(maxMainAngle + settings.mainAngleOffset),
                    limitDifference, distanceFromCenter);
            }
        }
        using (new HandleColor(limitColor)) {
            Vector3 minMainEnd = anchorPosition +
                                 Helpers2D.GetDirection(minMainAngle + settings.mainAngleOffset) *
                                 distanceFromCenter;
            Handles.DrawLine(anchorPosition, minMainEnd);

            Vector3 maxMainEnd = anchorPosition +
                                 Helpers2D.GetDirection(maxMainAngle + settings.mainAngleOffset) *
                                 distanceFromCenter;
            Handles.DrawLine(anchorPosition, maxMainEnd);

            if (limitDifference > 360) {
                Handles.DrawWireDisc(anchorPosition, Vector3.forward, distanceFromCenter);
            } else {
                Handles.DrawWireArc(anchorPosition, Vector3.forward,
                    Helpers2D.GetDirection(maxMainAngle + settings.mainAngleOffset),
                    limitDifference, distanceFromCenter);
            }

            EditorGUI.BeginChangeCheck();
            using (
                HandleDrawerBase drawer = new HandleCircleDrawer(angleWidgetColor, activeAngleColor,
                    hoverAngleColor)) {
                minMainAngle = EditorHelpers.AngleSlider(anchorInfo.GetControlID("lowerMainAngle"), drawer,
                    anchorPosition,
                    minMainAngle + settings.mainAngleOffset,
                    distanceFromCenter, angleHandleSize * HandleUtility.GetHandleSize(minMainEnd) / 64) -
                               settings.mainAngleOffset;
            }

            if (EditorGUI.EndChangeCheck()) {
                EditorHelpers.RecordUndo("Change Angle Limits", hingeJoint2D);
                limits.min = Handles.SnapValue(liveMainAngle - minMainAngle, editorSettings.snapAngle);
                hingeJoint2D.limits = limits;
                changed = true;
            }

            EditorGUI.BeginChangeCheck();
            using (
                HandleDrawerBase drawer = new HandleCircleDrawer(angleWidgetColor,
                    activeAngleColor, hoverAngleColor)) {
                maxMainAngle = EditorHelpers.AngleSlider(anchorInfo.GetControlID("upperMainAngle"), drawer,
                    anchorPosition,
                    maxMainAngle + settings.mainAngleOffset,
                    distanceFromCenter, angleHandleSize * HandleUtility.GetHandleSize(maxMainEnd) / 64) -
                               settings.mainAngleOffset;
            }

            if (EditorGUI.EndChangeCheck()) {
                EditorHelpers.RecordUndo("Change Angle Limits", hingeJoint2D);
                limits.max = Handles.SnapValue(liveMainAngle - maxMainAngle, editorSettings.snapAngle);
                hingeJoint2D.limits = limits;
                changed = true;
            }
        }
        return changed;
    }
    protected override bool PostAnchorGUI(AnchoredJoint2D joint2D, AnchorInfo info, List<Vector2> otherAnchors,
        JointHelpers.AnchorBias bias)
    {
        var hingeJoint2D = joint2D as HingeJoint2D;
        if (hingeJoint2D == null) {
            return false;
        }

        if (!hingeJoint2D.useLimits) {
            return false;
        }

        var showAngle = false;
        float angle = 0;
        float displayAngle = 0;

        float jointAngle;
        if (EditorApplication.isPlayingOrWillChangePlaymode || Application.isPlaying) {
            jointAngle = hingeJoint2D.jointAngle;
        } else {
            jointAngle = 0;
        }

        var startPosition = JointHelpers.GetAnchorPosition(hingeJoint2D, bias);

        var mainBodyPosition = GetTargetPosition(hingeJoint2D, JointHelpers.AnchorBias.Main);

        var mainBodyAngle = JointHelpers.AngleFromAnchor(startPosition, mainBodyPosition,
            JointHelpers.GetTargetRotation(hingeJoint2D, JointHelpers.AnchorBias.Main));

        var connectedBodyPosition = GetTargetPosition(hingeJoint2D, JointHelpers.AnchorBias.Connected);

        float connectedBodyAngle;
        if (hingeJoint2D.connectedBody) {
            connectedBodyAngle = JointHelpers.AngleFromAnchor(startPosition, connectedBodyPosition,
                JointHelpers.GetTargetRotation(hingeJoint2D, JointHelpers.AnchorBias.Connected));
        } else {
            connectedBodyAngle = 0;
        }

        var angleDiff = jointAngle - (connectedBodyAngle - mainBodyAngle);

        var liveMainAngle = connectedBodyAngle + angleDiff;

        var minMainAngle = liveMainAngle - hingeJoint2D.limits.min;
        var maxMainAngle = liveMainAngle - hingeJoint2D.limits.max;

        var labelText = "";

        float angleOffset = 0;

        var settings = SettingsHelper.GetOrCreate<HingeJoint2DSettings>(hingeJoint2D);

        if (EditorHelpers.IsWarm(info.GetControlID("lowerMainAngle"))) {
            showAngle = true;
            angle = minMainAngle;
            displayAngle = hingeJoint2D.limits.min;
            labelText = "Lower: ";
            angleOffset = settings.mainAngleOffset;
        } else if (EditorHelpers.IsWarm(info.GetControlID("upperMainAngle"))) {
            showAngle = true;
            angle = maxMainAngle;
            displayAngle = hingeJoint2D.limits.max;
            labelText = "Upper: ";
            angleOffset = settings.mainAngleOffset;
        } else if (EditorHelpers.IsWarm(info.GetControlID("lowerConnectedAngle"))) {
            showAngle = true;
            angle = hingeJoint2D.limits.min;
            displayAngle = angle;
            labelText = "Lower: ";
            startPosition = JointHelpers.GetConnectedAnchorPosition(hingeJoint2D);
            angleOffset = settings.connectedAngleOffset;
        } else if (EditorHelpers.IsWarm(info.GetControlID("upperConnectedAngle"))) {
            showAngle = true;
            angle = hingeJoint2D.limits.max;
            labelText = "Upper: ";
            displayAngle = angle;
            startPosition = JointHelpers.GetConnectedAnchorPosition(hingeJoint2D);
            angleOffset = settings.connectedAngleOffset;
        }

        LimitContext(hingeJoint2D, info.GetControlID("lowerMainAngle"), Limit.Min);
        LimitContext(hingeJoint2D, info.GetControlID("upperMainAngle"), Limit.Max);
        LimitContext(hingeJoint2D, info.GetControlID("lowerConnectedAngle"), Limit.Min);
        LimitContext(hingeJoint2D, info.GetControlID("upperConnectedAngle"), Limit.Max);

        if (showAngle) {
            var distanceFromCenter = GetAngleSliderRadius(startPosition);

            var anglePosition = startPosition + Helpers2D.GetDirection(angle + angleOffset) * distanceFromCenter;

            var labelContent = new GUIContent(labelText + "\n" + String.Format("{0:0.00}", displayAngle));

            var fontSize = HandleUtility.GetHandleSize(anglePosition) * (1f / 64f);

            var labelOffset = fontSize * EditorHelpers.FontWithBackgroundStyle.CalcSize(labelContent).y;

            EditorHelpers.OverlayLabel((Vector3) anglePosition + (Camera.current.transform.up * labelOffset),
                labelContent,
                EditorHelpers.FontWithBackgroundStyle);
        }
        return false;
    }
    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);
        }
    }
Example #14
0
    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 bool SliderGUI(AnchoredJoint2D joint2D, AnchorInfo anchorInfo, IEnumerable<Vector2> otherAnchors,
        JointHelpers.AnchorBias bias)
    {
        var sliderID = anchorInfo.GetControlID("slider");
        List<Vector2> snapPositions = null;
        if (EditorGUI.actionKey) {
            snapPositions = new List<Vector2> {
                GetTargetPosition(joint2D, JointHelpers.AnchorBias.Main),
                JointHelpers.GetTargetTransform(joint2D, JointHelpers.AnchorBias.Main)
                            .position
            };

            if (joint2D.connectedBody) {
                snapPositions.Add(GetTargetPosition(joint2D, JointHelpers.AnchorBias.Connected));
                snapPositions.Add(JointHelpers.GetTargetTransform(joint2D, JointHelpers.AnchorBias.Connected)
                                              .position);
            }

            switch (bias) {
                case JointHelpers.AnchorBias.Main:
                    snapPositions.Add(JointHelpers.GetAnchorPosition(joint2D,
                        JointHelpers.AnchorBias.Connected));
                    break;
                case JointHelpers.AnchorBias.Connected:
                    snapPositions.Add(JointHelpers.GetAnchorPosition(joint2D, JointHelpers.AnchorBias.Main));
                    break;
            }

            snapPositions.AddRange(otherAnchors);
        }
        EditorGUI.BeginChangeCheck();
        var position = AnchorSlider(sliderID, editorSettings.anchorScale, snapPositions, bias, joint2D, anchorInfo);

        var changed = false;
        if (EditorGUI.EndChangeCheck()) {
            EditorHelpers.RecordUndo("Anchor Move", joint2D);
            changed = true;

            JointHelpers.SetWorldAnchorPosition(joint2D, position, bias);
        }
        return changed;
    }