Im working in Unity3d (this is more a C# question, so I doubt that is an issue). Im working on a movement system like you would find in Civilization. I have a loop setup so that you can move 2 squares per turn. This works fine. I click on a square 10 blocks away and it takes 5 turns to get there. Now im trying to make the pawn lerp between blocks. I have got lerp to work, problem is, it jumps from the current tile to the 1st tile, then transitions to the 2nd tile where its supposed to be. I used a coroutine to make this work instead of the update function (as the update would cause it to just lerp to the final destination instead of from current, to first, to second). So what im running into is the loop that goes through each move the pawn has, isnt waiting for the coroutine to complete before continuing its own loop. Here is the code
public void MoveNextTile()
{
float remainingMoves = moveSpeed;
while (remainingMoves > 0)
{
if (currentPath == null)
return;
//Get the cost from current tile to next tile
remainingMoves -= map.CostToEnterTile(currentPath[0].x, currentPath[0].y, currentPath[1].x, currentPath[1].y);
//Move us to the next tile in the sequence
toVector = map.TileCoordToWorldCoord(currentPath[1].x, currentPath[1].y);
Vector3 fromVec = transform.position;
StartCoroutine(MoveObject(fromVec, toVector, 1.0f));
//transform.position = map.TileCoordToWorldCoord(currentPath[1].x, currentPath[1].y);
//Remove the old current tile
this.tileX = currentPath[0].x;
this.tileY = currentPath[0].y;
currentPath.RemoveAt(0);
if (currentPath.Count == 1)
{
this.tileX = currentPath[0].x;
this.tileY = currentPath[0].y;
currentPath = null;
}
}
}
IEnumerator MoveObject(Vector3 source, Vector3 target, float overTime)
{
float startTime = Time.time;
while (Time.time < startTime + overTime)
{
transform.position = Vector3.Lerp(source, target, (Time.time - startTime) / overTime);
yield return null;
}
transform.position = target;
}
I know this is a noob question. I just never have needed to do this in C# before. Thank in advance for all the help
I suggest you research into how coroutines work.
Your coroutine doesn't execute fully and then return to complete the rest of your MoveNextTile function. It actually executes up until the first yield statement and then continues execution of MoveNextTile. Each subsequent frame will continue to run one 'step' of the coroutine until the next yield statement in an attempt to replicate asynchronous methods.
What you want to do is tell your program to explicitly wait for your coroutine to finish. To do so;
yield return StartCoroutine(MoveObject(fromVec, toVector, 1.0f));
Of course, you can only use this statement inside of an IEnumerator. So you would have to change your void MoveNextTile function to IEnumerator MoveNextTile. You end up with something as follows;
public IEnumerator MoveNextTile() {
// Ommited
while (remainingMoves > 0) {
//Ommited
yield return StartCoroutine(MoveObject(fromVec, toVector, 1.0f));
// Now MoveNextTile will continue after your MoveObject coroutine finishes.
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With