// Update is called once per frame
 void FixedUpdate()
 {
     if (RailSys == null || !Active || GlobalVar.PAUSED)
     {
     }
     else if (CurrentNode == null)
     {
         CurrentNode = RailSys.GetClosestNode(transform);
     }
     else
     {
         if (CurrentNode.Lerping)
         {
             //Debug.Log("Moving Towards: Node" + CurrentNode + " | " + TargetMoveTowards);
             transform.position = Vector2.Lerp(transform.position, CurrentNode.transform.position, CurrentNode.Speed * Time.deltaTime);
         }
         else
         {
             transform.position = Vector2.MoveTowards(transform.position, CurrentNode.transform.position, CurrentNode.Speed * Time.deltaTime);
         }
         if (Vector2.Distance(transform.position, CurrentNode.transform.position) < 0.1f)
         {
             CurrentNode = RailSys.GetNode(ref CurrentNode, ref ReachedEnd);
             //Debug.Log("Get New Node: " + CurrentNode + " | " + TargetMoveTowards) ;
         }
     }
 }
 // Start is called before the first frame update
 void Awake()
 {
     //So when the railRider is created
     if (RailSys != null)
     {
         CurrentNode = RailSys.GetClosestNode(transform);
         //transform.position = RailSys.GetNode(CurrentNode, ref ReachedEnd);
         CurrentNode = RailSys.GetNode(ref CurrentNode, ref ReachedEnd);
     }
 }
    public RailAnchor GetNode(ref RailAnchor CurrentAnchor, ref bool ReachedEnd)
    {
        if (AnchorList.Count <RailAnchor>() == 1)
        {
            return(AnchorList.ElementAt <RailAnchor>(0));
        }
        if (CurrentAnchor == null)
        {
            Debug.Log("Our anchors are null...?");
            return(CurrentAnchor);
        }
        switch (Rail)
        {
        case RailType.OneWay:
            if (ReachedEnd)
            {
                ReachedEnd = true;
                return(CurrentAnchor);
            }
            if (!AnchorList.Contains(CurrentAnchor.Next))
            {
                ReachedEnd = true;
            }
            return(CurrentAnchor.Next);

        case RailType.Rubberband:
            if (ReachedEnd == true)
            {
                if (CurrentAnchor.Previous == null)
                {
                    ReachedEnd = false;
                    return(CurrentAnchor);
                }
                return(CurrentAnchor.Previous);
            }
            else
            {
                if (CurrentAnchor.Next == null)
                {
                    ReachedEnd = true;
                    return(CurrentAnchor);
                }
                return(CurrentAnchor.Next);
            }

        case RailType.Loop:
            return(CurrentAnchor.Next);

        case RailType.UnitActivated:
        default:
            return(null);
        }
    }
    public RailAnchor GetClosestNode(Transform Other)
    {
        RailAnchor retVal = null;

        if (AnchorList.Count <RailAnchor>() == 0)
        {
            return(retVal);
        }

        retVal = AnchorList.ElementAt <RailAnchor>(0);

        foreach (RailAnchor Anchor in AnchorList)
        {
            if (Other == null)
            {
                retVal = Anchor;
            }
            else if (Vector3.Distance(Other.position, Anchor.transform.position) < Vector3.Distance(Other.position, retVal.transform.position))
            {
                retVal = Anchor;
            }
        }
        return(retVal);
    }
    // These should be placed at the 0 position for best results
    // Start is called before the first frame update

    void Awake()
    {
        //Debug.Log(AnchorParent.GetComponentsInChildren<RailAnchor>());
        foreach (RailAnchor Anchor in AnchorParent.GetComponentsInChildren <RailAnchor>())
        {
            //Debug.Log(Anchor.name);
            //So if the anchor isn't already in the list ADD IT
            if (!AnchorList.Contains(Anchor))
            {
                AnchorList.AddRange(GetComponentsInChildren <RailAnchor>());
            }
            //if(Anchor.transform == this.transform) AnchorLocations.Remove(this.transform);
        }

        //Setup for stuff linking Anchors Together
        bool       first          = true;
        RailAnchor PreviousAnchor = null;
        RailAnchor CurrentAnchor  = null;

        foreach (RailAnchor Anchor in AnchorList)
        {
            //If we're at index 0 we set the current location to index 0
            if (first)
            {
                Anchor.Previous = null;
                CurrentAnchor   = Anchor;
                first           = !first;
            }
            else
            {
                //So we update the positions
                PreviousAnchor = CurrentAnchor;
                CurrentAnchor  = Anchor;

                PreviousAnchor.Next    = CurrentAnchor;
                CurrentAnchor.Previous = PreviousAnchor;

                Vector3 Pos1 = PreviousAnchor.transform.position;
                Vector3 Pos2 = CurrentAnchor.transform.position;

                TotalDistance += Vector2.Distance(Pos1, Pos2);
                GenerateRail(Pos1, Pos2);
            }
            //Debug.Log(TotalDistance);
        }


        //So if it's a loop type we have to take the 0 and
        if (Rail == RailType.Loop)
        {
            PreviousAnchor = CurrentAnchor;
            CurrentAnchor  = AnchorList.ElementAt <RailAnchor>(0);

            PreviousAnchor.Next    = CurrentAnchor;
            CurrentAnchor.Previous = PreviousAnchor;

            GenerateRail(PreviousAnchor.transform.position, CurrentAnchor.transform.position);
        }


        //This is not exactly going to be used often.....
        if (CreateRiders)
        {
        }
        else
        {
            foreach (RailRider Rider in RiderParent.GetComponentsInChildren <RailRider>())
            {
                Rider.RailSys = this;
                RiderList.Add(Rider);
            }
        }

        //StartCoroutine(AngleCheck());
    }
    public RailAnchor getAnchor(float targetGlobalOffset, ref RailAnchor anchor, float precision = 10.0f)
    {
        float step = 1.0f/Mathf.Max(1.0f, precision);

        // special case for end
        if (targetGlobalOffset >= 1.0f - step)
        {
            anchor.section = TrackManager.instance.lastSection;
            anchor.globalOffset = anchor.sectionOffset = 1.0f;
            anchor.xOffset = anchor.yOffset = anchor.distance = 0.0f;
            anchor.position = anchor.section.end.position;
            return anchor;
        }

        // approximate anchor based on the offset
        float globalStep = step / numberOfSections;
        float globalOffset = 0.0f;
        foreach(var section in iterateForwards())
        {
            for(float sectionOffset = 0.0f; sectionOffset < 1.0f;
                sectionOffset += step, globalOffset += globalStep)
            {
                if(globalOffset >= targetGlobalOffset)
                {
                    Vector3 anchorPosition = section.getCurvePosition(sectionOffset);

                    anchor.section = section;
                    anchor.sectionOffset = sectionOffset;
                    anchor.globalOffset = globalOffset;
                    anchor.position = anchorPosition;
                    anchor.distance = anchor.xOffset = anchor.yOffset = 0.0f;

                    return anchor;
                }
            }
        }

        // failure :'(
        Debug.LogError("'TrackManager::getAnchor' Could not find an anchor for targetGlobalOffset = "
            + targetGlobalOffset + " best was " + globalOffset);
        return anchor;
    }
 public RailAnchor getAnchor(float targetTotalOffset, float precision = 10.0f)
 {
     RailAnchor anchor = new RailAnchor();
     return getAnchor(targetTotalOffset, ref anchor, precision);
 }
    public RailAnchor getAnchor(Vector3 position, ref RailAnchor anchor, float precision = 10.0f)
    {
        float step = 1.0f/Mathf.Max(1.0f, precision);

        float bestAnchorDistance = Mathf.Infinity;

        float globalOffset = 0.0f;

        foreach(var section in iterateForwards())
        {
            for(float sectionOffset = 0.0f; sectionOffset < 1.0f;
                sectionOffset += step, globalOffset += step)
            {
                Vector3 anchorPosition = section.getCurvePosition(sectionOffset);
                float anchorWidth = section.getCurveWidth(sectionOffset);
                float anchorDistance = Vector3.Distance(position, anchorPosition)
                    / (anchorWidth*anchorWidth);

                // we will always enter here at least once
                // assuming there is at least one RailSection
                if(anchorDistance < bestAnchorDistance)
                {
                    bestAnchorDistance = anchor.distance = anchorDistance;

                    anchor.section = section;
                    anchor.sectionOffset = sectionOffset;
                    anchor.globalOffset = globalOffset / numberOfSections;
                    anchor.position = anchorPosition;
                }
            }
        }

        // calculate offsets
        Vector3 offset = (position - anchor.position);
        // calculate horizontal offset
        Vector3 left = -anchor.right;
        anchor.xOffset = Vector3.Dot(offset, left)/anchor.width;
        // calculate vertical offset
        Vector3 down = -anchor.up;
        anchor.yOffset = Vector3.Dot(offset, down)/anchor.depth;

        // return the anchor
        return anchor;
    }
 public RailAnchor getAnchor(Vector3 position, float precision = 10.0f)
 {
     RailAnchor anchor = new RailAnchor();
     return getAnchor(position, ref anchor, precision);
 }