I am simulating cars driving through a road network given four columns of data time
, id
, x
and z
where a car with id id
is located at x,0,z
at time t
Here is a sample:
t id x z
957,1,-1.50,250.07
958,1,-1.50,232.39
959,1,-4.50,209.72
960,1,-4.50,193.05
961,1,-4.50,176.39
962,1,-4.50,159.72
963,1,-4.50,143.05
...
At the moment, I'm able to spawn cars and update their positions as time elapses and according to the data. I'm stuck on how to more realistically simulate car movement, instead of the car simply popping from point to point.
I am using Vector.Lerp
but it jump without consistent, smooth movement:
car.transform.position =
Vector3.Lerp(car.transform.position, nextPosition, Time.deltaTime);
At each second, I check the data above to find the coordinates of the car at the current second. Those coordinates are passed as nextPosition
into the above Lerp
function. This means that the car is 'Lerping' from point to point, every second.
How can I make the movement smoother? The position updates are every second and therefore the car needs to reach the next position in 1 second.
You need to use the moveToX
function which moves object to a position within x seconds. It simplifies this whole stuff. All you have to do now is loop over each position in the list, and the moveToX
function and provide the time (1 sec) the object must be there.
This moveToX
function works by using Time.deltaTime
to increment a counter variable until it reaches the target time specified. The t
is calculated by dividing that counter with the target time resulting to 0
and 1
values since that's what t
in Vector3.Lerp
expects. All these must be done in a coroutine function because coroutine simplifies waiting in a function.
public GameObject car;
public List<Vector3> pos;
bool isMoving = false;
IEnumerator MoveCar()
{
//Loop over each postion
for (int i = 0; i < pos.Count; i++)
{
//Get next position
Vector3 nextPosition = pos[i];
//Move to new position within 1 second
yield return StartCoroutine(moveToX(car.transform, nextPosition, 1.0f));
}
}
then you can start the movement by calling the coroutine function:
void Start()
{
StartCoroutine(MoveCar());
}