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);
}
}