private bool ShouldFlipEdgeOffset(GrindSpline spline, Collider[] test_cols)
    {
        if (IsEdge)
        {
            if (AutoDetectEdgeAlignment)
            {
                var left = false;

                var a = spline.transform.GetChild(0).position;
                var b = spline.transform.GetChild(1).position;

                var dir      = a - b;
                var right    = Vector3.Cross(dir.normalized, Vector3.up);
                var test_pos = a + (right * GeneratedColliderWidth);

                foreach (var t in test_cols)
                {
                    // if this ray doesnt hit anything then the ledge is to our left

                    if (t.Raycast(new Ray(test_pos + Vector3.up, Vector3.down), out var hit, 1f) == false)
                    {
                        left = true;
                    }
                }

                return(left);
            }

            return(FlipEdge);
        }

        return(false);
    }
    private Collider CreateColliderBetweenPoints(GrindSpline spline, Vector3 pointA, Vector3 pointB)
    {
        var go = new GameObject("Grind Cols")
        {
            layer = LayerMask.NameToLayer(spline.IsCoping ? "Coping" : "Grindable")
        };

        go.transform.position = pointA;
        go.transform.LookAt(pointB);
        go.transform.SetParent(ColliderContainer != null ? ColliderContainer : transform);
        go.tag = $"Grind_{spline.SurfaceType}";

        var length = Vector3.Distance(pointA, pointB);

        if (spline.IsRound)
        {
            var cap = go.AddComponent <CapsuleCollider>();

            cap.direction = 2;
            cap.radius    = GeneratedColliderRadius;
            cap.height    = length + 2f * GeneratedColliderRadius;
            cap.center    = Vector3.forward * length / 2f + Vector3.down * GeneratedColliderRadius;
        }
        else
        {
            var box = go.AddComponent <BoxCollider>();

            box.size = new Vector3(GeneratedColliderWidth, GeneratedColliderDepth, length);
            var offset = IsEdge ? new Vector3(flipEdgeOffset ? (GeneratedColliderWidth / 2f) * -1 : GeneratedColliderWidth / 2f, 0, 0) : Vector3.zero;
            box.center = offset + Vector3.forward * length / 2f + Vector3.down * GeneratedColliderDepth / 2f;
        }

        return(go.GetComponent <Collider>());
    }
Exemple #3
0
    public static void OnSceneGUI_SplineDrawingCommon(Editor editor, GrindSpline grindSpline, string lmbLabel, ref bool vertexSnap, ref Vector3 pointPosition)
    {
        HandleUtility.AddDefaultControl(editor.GetHashCode());

        Handles.BeginGUI();
        {
            var r = new Rect(10, SceneView.currentDrawingSceneView.camera.pixelHeight - 30 * 3 + 10, 400, 30 * 4);

            GUILayout.BeginArea(r);
            GUILayout.BeginVertical(new GUIStyle("box"));

            var label = $"{lmbLabel}\n" +
                        $"V : Toggle Vertex Snap\n" +
                        $"Space : Confirm\n" +
                        $"Escape : Cancel";

            GUILayout.Label($"<color=white>{label}</color>", new GUIStyle("label")
            {
                richText = true, fontSize = 14, fontStyle = FontStyle.Bold
            });
            GUILayout.EndVertical();
            GUILayout.EndArea();
        }
        Handles.EndGUI();

        if (Event.current.type == EventType.KeyUp && Event.current.keyCode == KeyCode.V)
        {
            vertexSnap = !vertexSnap;
        }

        if (vertexSnap)
        {
            if (GrindSplineUtils.SnapToVertexAtCursor(out var pos))
            {
                pointPosition = pos;
            }
        }
        else
        {
            if (GrindSplineUtils.SnapToSurfaceAtCursor(out var pos))
            {
                pointPosition = pos;
            }
        }

        HandleUtility.Repaint();

        Handles.color = Color.cyan;

        if (grindSpline != null && grindSpline.PointsContainer.childCount > 0)
        {
            Handles.DrawAAPolyLine(3f, grindSpline.PointsContainer.GetChild(grindSpline.PointsContainer.childCount - 1).position, pointPosition);
        }

        Handles.CircleHandleCap(0, pointPosition, Quaternion.LookRotation(SceneView.currentDrawingSceneView.camera.transform.forward), 0.02f, EventType.Repaint);
    }
    public static GameObject AddPoint(GrindSpline spline, Vector3 position)
    {
        var p  = spline.transform;
        var n  = p.childCount;
        var go = new GameObject($"Point ({n + 1})");

        go.transform.position = position;
        go.transform.SetParent(p);

        Undo.RegisterCreatedObjectUndo(go, "GrindSpline.AddPoint");

        return(go);
    }
    public static void AddPoint(GrindSpline spline)
    {
        var p  = spline.transform;
        var n  = p.childCount;
        var go = new GameObject($"Point ({n + 1})");

        var pos = n > 0 ? p.GetChild(p.childCount - 1).localPosition : Vector3.zero;

        go.transform.SetParent(p);
        go.transform.localPosition = pos + (p.childCount > 1 ? p.InverseTransformVector(Vector3.forward) : Vector3.zero);

        Undo.RegisterCreatedObjectUndo(go, "GrindSpline.AddPoint");
    }
Exemple #6
0
    private void OnSceneGUI()
    {
        if (drawSplines)
        {
            HandleUtility.AddDefaultControl(GetHashCode());

            var pick_new_vert = GrindSplineUtils.PickNearestVertexToCursor(out var pos, 0, grindSurface.transform);

            if (pick_new_vert)
            {
                nearestVert = pos;
            }

            HandleUtility.Repaint();

            Handles.color = Color.green;

            if (activeSpline != null && activeSpline.transform.childCount > 0)
            {
                Handles.DrawAAPolyLine(3f, activeSpline.transform.GetChild(activeSpline.transform.childCount - 1).position, nearestVert);
            }

            var label = (activeSpline != null ? "Shift Click : Add Point\n" : "Shift + LMB : Create Grind\n") +
                        $"Space : Confirm\n" +
                        $"Escape : {(activeSpline == null ? "Exit Drawing Mode" : "Cancel")}";

            var offset = Vector3.up * Mathf.Lerp(0.1f, 1f, Mathf.Clamp01(SceneView.currentDrawingSceneView.cameraDistance / 4));

            Handles.Label(nearestVert + offset, label, new GUIStyle("whiteLabel")
            {
                richText = true, fontSize = 14, fontStyle = FontStyle.Bold
            });
            Handles.CircleHandleCap(0, nearestVert, Quaternion.LookRotation(SceneView.currentDrawingSceneView.camera.transform.forward), 0.02f, EventType.Repaint);

            if (Event.current == null)
            {
                return;
            }

            if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && Event.current.modifiers.HasFlag(EventModifiers.Shift))
            {
                if (activeSpline == null)
                {
                    activeSpline = CreateSpline();
                    activeSpline.transform.position = nearestVert;

                    Undo.RegisterCreatedObjectUndo(activeSpline.gameObject, "Create GrindSpline");

                    GrindSplineUtils.AddPoint(activeSpline);
                }
                else
                {
                    GrindSplineUtils.AddPoint(activeSpline, nearestVert);
                }
            }

            if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Space)
            {
                if (activeSpline != null && activeSpline.transform.childCount < 2)
                {
                    DestroyImmediate(activeSpline.gameObject);
                    grindSurface.Splines.Remove(activeSpline);
                }

                activeSpline = null;

                grindSurface.GenerateColliders();

                Repaint();
            }

            if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Escape)
            {
                drawSplines = false;

                if (activeSpline != null)
                {
                    DestroyImmediate(activeSpline.gameObject);
                    grindSurface.Splines.Remove(activeSpline);
                    activeSpline = null;
                }

                grindSurface.GenerateColliders();

                Repaint();
            }
        }
    }
Exemple #7
0
    private void OnSceneGUI()
    {
        if (drawSplines)
        {
            Tools.current = Tool.None;

            SplineDrawingShared.OnSceneGUI_SplineDrawingCommon(
                editor: this,
                grindSpline: activeSpline,
                lmbLabel: (activeSpline != null ? "Shift Click : Add Point" : "Shift + LMB : Create Grind"),
                vertexSnap: ref vertexSnap,
                pointPosition: ref pointPosition);

            if (Event.current == null)
            {
                return;
            }

            if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && Event.current.modifiers.HasFlag(EventModifiers.Shift))
            {
                if (activeSpline == null)
                {
                    activeSpline = CreateSpline();
                    activeSpline.DrawingActive      = true;
                    activeSpline.transform.position = pointPosition;

                    Undo.RegisterCreatedObjectUndo(activeSpline.gameObject, "Create GrindSpline");

                    GrindSplineUtils.AddPoint(activeSpline);
                }
                else
                {
                    GrindSplineUtils.AddPoint(activeSpline, pointPosition);
                }
            }

            if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Space)
            {
                // destroy if invalid

                if (activeSpline != null && activeSpline.PointsContainer.childCount < 2)
                {
                    foreach (var c in activeSpline.GeneratedColliders)
                    {
                        DestroyImmediate(c.gameObject);
                    }

                    DestroyImmediate(activeSpline.gameObject);

                    grindSurface.Splines.Remove(activeSpline);
                }

                activeSpline = null;

                Repaint();
            }

            if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Escape)
            {
                drawSplines = false;

                if (activeSpline != null)
                {
                    foreach (var c in activeSpline.GeneratedColliders)
                    {
                        DestroyImmediate(c.gameObject);
                    }

                    DestroyImmediate(activeSpline.gameObject);
                    grindSurface.Splines.Remove(activeSpline);
                    activeSpline.DrawingActive = false;
                    activeSpline = null;
                }

                Repaint();
            }
        }
    }