0
\$\begingroup\$

I tried this : And the pingPong is working but after some times changing the pingpong flag true false many times i'm getting index out of bound exception :

The pingpong line that give the exception :

transform.position = Vector3.Lerp(pos[index + 30], pos[index], Mathf.PingPong(Time.time, 1));

And how i tried to use the pingPong :

void Move()
    {
        if (pingPong)
        {
            transform.position = Vector3.Lerp(pos[index + 30], pos[index], Mathf.PingPong(Time.time, 1));
        }
        else
        {
            Vector3 newPos = transform.position;
            float distanceToTravel = speed * Time.deltaTime;

            bool stillTraveling = true;
            while (stillTraveling)
            {
                if (changeDir && goForward)
                {
                    goForward = false;
                }
                if (changeDir == false && goForward == false)
                {
                    goForward = true;
                }

                Vector3 oldPos = newPos;

                newPos = Vector3.MoveTowards(oldPos, pos[index], distanceToTravel);

                distanceToTravel -= Vector3.Distance(newPos, oldPos);
                if (newPos == pos[index]) // Vector3 comparison is approximate so this is ok
                {
                    // when you hit a waypoint:
                    if (goForward)
                    {
                        atLastOne = index >= pos.Length - 1;
                        if (!atLastOne)
                        {
                            index++;
                            counter++;
                            if (counter == numofposbetweenpoints)
                            {
                                c++;

                                counter = 0;
                            }
                            if (c == curvedLinePoints.Count - 1)
                            {
                                c = 0;
                            }
                        }
                        else
                        {
                            if (stop && index == pos.Length - 1)
                            {
                                break;
                            }
                            else
                            {
                                if (loop)
                                {
                                    index = 0;
                                }
                                else
                                {
                                    index--;
                                    goForward = false;
                                }
                            }
                        }
                    }
                    else
                    { // going backwards:
                        bool atFirstOne = index <= 0;
                        if (!atFirstOne)
                        {
                            index--;

                            counter++;
                            if (counter == numofposbetweenpoints)
                            {
                                c++;

                                counter = 0;
                            }
                            if (c == curvedLinePoints.Count - 1)
                            {
                                c = 0;
                            }
                        }
                        else
                        {
                            if (stop && index == 0)
                            {
                                break;
                            }
                            else
                            {
                                if (loop)
                                {
                                    index = pos.Length - 1;
                                }
                                else
                                {
                                    index++;
                                    goForward = true;
                                }
                            }
                        }
                    }
                }
                else
                {
                    stillTraveling = false;
                }
            }

            transform.position = newPos;
        }
    }

The full script :

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class MoveOnCurvedLines : MonoBehaviour
{ 
    public LineRenderer lineRenderer;
    public float speed;
    public bool go = false;
    public bool moveToFirstPositionOnStart = false;
    public float rotSpeed;
    public bool loop = false;
    public bool changeDir = false;
    public bool pingPong = false;
    public bool stop = false;
    public bool random = false;
    public int currentCurvedLinePointIndex;
    public TextMeshProUGUI lastWaypointText;
    public TextMeshProUGUI countWaypointText;

    private Vector3[] positions;
    private Vector3[] pos;
    private int index = 0;
    private bool goForward = true;
    private List<GameObject> curvedLinePoints = new List<GameObject>();
    private int numofposbetweenpoints;
    private bool getPositions = false;
    int randomIndex;
    int curvedPointsIndex;
    private bool atLastOne = false;

    // Start is called before the first frame update
    void Start()
    {
        curvedLinePoints = GameObject.FindGameObjectsWithTag("Curved Line Point").ToList();

        if (curvedLinePoints != null && curvedLinePoints.Count > 0)
        {
            transform.rotation = curvedLinePoints[1].transform.rotation;
        }

        if (random)
            GetNewRandomIndex();

        if (lastWaypointText != null)
        {
            lastWaypointText.text = "Last Waypoint : " + (curvedPointsIndex + 1).ToString();
        }

        if (countWaypointText != null)
        {
            countWaypointText.text = "Waypoints Count : " + curvedLinePoints.Count.ToString();
        }
    }

    Vector3[] GetLinePointsInWorldSpace()
    {
        if (lineRenderer != null)
        {
            positions = new Vector3[lineRenderer.positionCount];
            //Get the positions which are shown in the inspector
            lineRenderer.GetPositions(positions);

        }

        //the points returned are in world space
        return positions;
    }

    // Update is called once per frame
    void Update()
    {
        if (lineRenderer != null)
        {
            if (curvedLinePoints.Count > 0)
            {
                for (int i = 0; i < curvedLinePoints.Count; i++)
                {
                    if (curvedLinePoints[i].transform.hasChanged)
                    {
                        getPositions = false;
                    }
                }
            }

            if (lineRenderer.positionCount > 0 && getPositions == false)
            {
                pos = GetLinePointsInWorldSpace();

                numofposbetweenpoints = pos.Length / curvedLinePoints.Count;

                if (moveToFirstPositionOnStart == true)
                {
                    transform.position = pos[index];
                }

                getPositions = true;
            }

            if (go == true && lineRenderer.positionCount > 0)
            {
                Move();

                Vector3 targetDirection = (curvedLinePoints[c].transform.position - transform.position).normalized;
                curvedLinePoints[c].transform.localRotation = Quaternion.LookRotation(targetDirection);
                transform.localRotation = Quaternion.RotateTowards(transform.localRotation, curvedLinePoints[c].transform.localRotation, Time.deltaTime * rotSpeed);
            }

            if (curvedLinePoints.Count > 1)
            {
                var dist = Vector3.Distance(transform.position, curvedLinePoints[curvedPointsIndex].transform.position);
                if (dist < 0.1f)
                {
                    if (curvedPointsIndex < curvedLinePoints.Count - 1)
                    {
                        curvedPointsIndex++;

                        if (lastWaypointText != null)
                        {
                            lastWaypointText.text = "Last Waypoint : " + curvedPointsIndex.ToString();
                        }
                    }
                    else
                    {
                        if (lastWaypointText != null)
                        {
                            lastWaypointText.text = "Last Waypoint : " + (curvedPointsIndex + 1).ToString();
                        }

                        curvedPointsIndex = 0;
                    }

                    currentCurvedLinePointIndex = curvedPointsIndex;
                }
            }
        }
    }

    int counter = 0;
    int c = 1;
    void Move()
    {
        Vector3 newPos = transform.position;
        float distanceToTravel = speed * Time.deltaTime;

        bool stillTraveling = true;
        while (stillTraveling)
        {
            if(changeDir && goForward)
            {
                goForward = false;
            }
            if(changeDir == false && goForward == false)
            {
                goForward = true;
            }

            if(pingPong)
            {
                if(goForward)
                {
                    transform.position = Vector3.Lerp(pos[index + 1], pos[index], Mathf.PingPong(Time.time, 1));
                }
            }

            Vector3 oldPos = newPos;

            newPos = Vector3.MoveTowards(oldPos, pos[index], distanceToTravel);

            distanceToTravel -= Vector3.Distance(newPos, oldPos);
            if (newPos == pos[index]) // Vector3 comparison is approximate so this is ok
            {
                // when you hit a waypoint:
                if (goForward)
                {
                    atLastOne = index >= pos.Length - 1;
                    if (!atLastOne)
                    {
                        index++;
                        counter++;
                        if (counter == numofposbetweenpoints)
                        {
                            c++;

                            counter = 0;
                        }
                        if (c == curvedLinePoints.Count - 1)
                        {
                            c = 0;
                        }
                    }
                    else
                    {
                        if (stop && index == pos.Length - 1)
                        {
                            break;
                        }
                        else
                        {
                            if (loop)
                            {
                                index = 0;
                            }
                            else
                            {
                                index--;
                                goForward = false;
                            }
                        }
                    }
                }
                else
                { // going backwards:
                    bool atFirstOne = index <= 0;
                    if (!atFirstOne)
                    {
                        index--;

                        counter++;
                        if (counter == numofposbetweenpoints)
                        {
                            c++;

                            counter = 0;
                        }
                        if (c == curvedLinePoints.Count - 1)
                        {
                            c = 0;
                        }
                    }
                    else 
                    {
                        if (stop && index == 0)
                        {
                            break;
                        }
                        else
                        {
                            if (loop)
                            {
                                index = pos.Length - 1;
                            }
                            else
                            {
                                index++;
                                goForward = true;
                            }
                        }
                    }
                }
            }
            else
            {
                stillTraveling = false;
            }
        }

        transform.position = newPos;
    }

    void GetNewRandomIndex()
    {
        randomIndex = UnityEngine.Random.Range(0, curvedLinePoints.Count);
    }
}
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

Here's a debug suggestion:

Given that there are so many places to set the value of index,You can do an interception like:

Replce: private int index = 0; with:

private int _index = 0;
private int index
{
    get
    {
        return _index;
    }
    set
    {
        if (value < 0 || value > pos.Length - 1 || value + 30 < 0 || value + 30 > pos.Length - 1)
        {
            Debug.Log($"{value},{pos.Length}");
            Debug.Log(System.Environment.StackTrace);
        }
        _index = value;
    }
}

Or if the debugger is working, simply set a conditional breakpoint here.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .