Beispiel #1
0
        /// <summary>
        /// Returns a position on the spline at the given percentage.
        /// </summary>
        public Vector3 GetPosition(float percentage, bool evenDistribution = true, int distributionSteps = 100)
        {
            //evaluate curve:
            CurveDetail curveDetail = GetCurve(percentage);

            //avoid an error in editor usage where this index can be -1:
            if (curveDetail.currentCurve < 0)
            {
                return(Vector3.zero);
            }

            SplineAnchor startAnchor = Anchors[curveDetail.currentCurve];
            SplineAnchor endAnchor   = Anchors[curveDetail.currentCurve + 1];

            return(BezierCurves.GetPoint(startAnchor.Anchor.position, endAnchor.Anchor.position, startAnchor.OutTangent.position, endAnchor.InTangent.position, curveDetail.currentCurvePercentage, evenDistribution, distributionSteps));
        }
Beispiel #2
0
        /// <summary>
        /// Returns a facing vector at the given percentage along the spline to allow content to properly orient along the spline.
        /// </summary>
        public Vector3 GetDirection(float percentage)
        {
            //get direction:
            CurveDetail curveDetail = GetCurve(percentage);

            //avoid an error in editor usage where this index can be -1:
            if (curveDetail.currentCurve < 0)
            {
                return(Vector3.zero);
            }

            SplineAnchor startAnchor = Anchors[curveDetail.currentCurve];
            SplineAnchor endAnchor   = Anchors[curveDetail.currentCurve + 1];

            return(BezierCurves.GetFirstDerivative(startAnchor.Anchor.position, endAnchor.Anchor.position, startAnchor.OutTangent.position, endAnchor.InTangent.position, curveDetail.currentCurvePercentage).normalized);
        }
Beispiel #3
0
        static void DrawTools(Transform target)
        {
            Spline spline = target.GetComponent <Spline> ();

            if (spline == null)
            {
                return;
            }
            if (target.transform.childCount == 0)
            {
                return;
            }

            //set primary draw color:
            Handles.color = spline.SecondaryColor;

            for (int i = 0; i < spline.Anchors.Length; i++)
            {
                //refs:
                Quaternion   lookRotation  = Quaternion.identity;
                SplineAnchor currentAnchor = spline.Anchors[i];

                //scale geometry:
                currentAnchor.InTangent.localScale  = Vector3.one * (spline.toolScale * 1.3f);
                currentAnchor.OutTangent.localScale = Vector3.one * (spline.toolScale * 1.3f);
                currentAnchor.Anchor.localScale     = Vector3.one * (spline.toolScale * 2.1f);

                if (spline.toolScale > 0)
                {
                    //draw persistent identifiers that face the scene view camera and only draw if the corrosponding tangent is active:
                    if (currentAnchor.OutTangent.gameObject.activeSelf)
                    {
                        //connection:
                        Handles.DrawDottedLine(currentAnchor.Anchor.position, currentAnchor.OutTangent.position, 3);

                        //indicators:
                        if (SceneView.currentDrawingSceneView != null)
                        {
                            lookRotation = Quaternion.LookRotation((SceneView.currentDrawingSceneView.camera.transform.position - currentAnchor.OutTangent.position).normalized);
                            Handles.CircleHandleCap(0, currentAnchor.OutTangent.position, lookRotation, spline.toolScale * .65f, EventType.Repaint);
                            Handles.CircleHandleCap(0, currentAnchor.OutTangent.position, lookRotation, spline.toolScale * .25f, EventType.Repaint);
                        }
                    }

                    if (currentAnchor.InTangent.gameObject.activeSelf)
                    {
                        //connection:
                        Handles.DrawDottedLine(currentAnchor.Anchor.position, currentAnchor.InTangent.position, 3);

                        //indicators:
                        if (SceneView.currentDrawingSceneView != null)
                        {
                            lookRotation = Quaternion.LookRotation((SceneView.currentDrawingSceneView.camera.transform.position - currentAnchor.InTangent.position).normalized);
                            Handles.CircleHandleCap(0, currentAnchor.InTangent.position, lookRotation, spline.toolScale * .65f, EventType.Repaint);
                            Handles.CircleHandleCap(0, currentAnchor.InTangent.position, lookRotation, spline.toolScale * .25f, EventType.Repaint);
                        }
                    }

                    //anchor tools:
                    if (SceneView.currentDrawingSceneView != null)
                    {
                        lookRotation = Quaternion.LookRotation((SceneView.currentDrawingSceneView.camera.transform.position - currentAnchor.Anchor.position).normalized);
                        Handles.CircleHandleCap(0, currentAnchor.Anchor.position, lookRotation, spline.toolScale, EventType.Repaint);
                    }

                    //identify path origin:
                    if (spline.direction == SplineDirection.Forward && i == 0 || spline.direction == SplineDirection.Backwards && i == spline.Anchors.Length - 1)
                    {
                        Handles.CircleHandleCap(0, currentAnchor.Anchor.position, lookRotation, spline.toolScale * .8f, EventType.Repaint);
                        Handles.CircleHandleCap(0, currentAnchor.Anchor.position, lookRotation, spline.toolScale * .75f, EventType.Repaint);
                        Handles.CircleHandleCap(0, currentAnchor.Anchor.position, lookRotation, spline.toolScale * .5f, EventType.Repaint);
                        Handles.CircleHandleCap(0, currentAnchor.Anchor.position, lookRotation, spline.toolScale * .45f, EventType.Repaint);
                        Handles.CircleHandleCap(0, currentAnchor.Anchor.position, lookRotation, spline.toolScale * .25f, EventType.Repaint);
                    }
                }
            }

            //draw spline:
            for (int i = 0; i < spline.Anchors.Length - 1; i++)
            {
                SplineAnchor startAnchor = spline.Anchors[i];
                SplineAnchor endAnchor   = spline.Anchors[i + 1];
                Handles.DrawBezier(startAnchor.Anchor.position, endAnchor.Anchor.position, startAnchor.OutTangent.position, endAnchor.InTangent.position, spline.color, null, 2);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Makes a spline longer.
        /// </summary>
        public GameObject[] AddAnchors(int count)
        {
            //refs:
            GameObject anchorTemplate = Resources.Load("Anchor") as GameObject;

            //if we have no anchors let's make sure we create a spline segment and not just a single anchor:
            if (Anchors.Length == 0)
            {
                count = 2;
            }

            //create return array:
            GameObject[] returnObjects = new GameObject[count];

            for (int i = 0; i < count; i++)
            {
                //previous anchor refs:
                Transform previousPreviousAnchor = null;
                Transform previousAnchor         = null;
                if (Anchors.Length == 1)
                {
                    previousPreviousAnchor = transform;
                    previousAnchor         = Anchors[0].transform;
                }
                else if (Anchors.Length > 1)
                {
                    previousPreviousAnchor = Anchors[Anchors.Length - 2].transform;
                    previousAnchor         = Anchors[Anchors.Length - 1].transform;
                }

                //create a new anchor:
                GameObject newAnchor = Instantiate <GameObject>(anchorTemplate);
                newAnchor.name = newAnchor.name.Replace("(Clone)", "");
                SplineAnchor anchor = newAnchor.GetComponent <SplineAnchor>();
                anchor.tangentMode           = defaultTangentMode;
                newAnchor.transform.parent   = transform;
                newAnchor.transform.rotation = Quaternion.LookRotation(transform.forward);

                //tilt tangents for variety as we add new anchors:
                //anchor.Tilt (new Vector3 (0, 0, 0));
                anchor.InTangent.Translate(Vector3.up * .5f);
                anchor.OutTangent.Translate(Vector3.up * -.5f);

                //position new anchor:
                if (previousPreviousAnchor != null && previousAnchor != null)
                {
                    //determine direction for next placement:
                    Vector3 direction = (previousAnchor.position - previousPreviousAnchor.position).normalized;
                    if (direction == Vector3.zero)
                    {
                        direction = transform.forward;
                    }

                    //place from the previous anchor in the correct direction:
                    newAnchor.transform.position = previousAnchor.transform.position + (direction * 1.5f);
                }
                else
                {
                    newAnchor.transform.localPosition = Vector3.zero;
                }

                //catalog this new anchor for return:
                returnObjects[i] = newAnchor;
            }

            return(returnObjects);
        }