Hello guys,
I have this really annoying issue that I just can’t understand. To begin with here is the code :
public void OnExecuteClick()
{
is_moving = true;
print(is_moving + "1");
if (move_dir == "up")
{
Vector2 up_dir = new Vector2(XCORD, YCORD);
move_player_cr = StartCoroutine(MovePlayer(up_dir));
}
if (move_dir == "down")
{
Vector2 down_dir = new Vector2(-XCORD, -YCORD);
move_player_cr = StartCoroutine(MovePlayer(down_dir));
}
if (move_dir == "left")
{
Vector2 left_dir = new Vector2(-XCORD, YCORD);
move_player_cr = StartCoroutine(MovePlayer(left_dir));
}
if (move_dir == "right")
{
Vector2 right_dir = new Vector2(XCORD, -YCORD);
move_player_cr = StartCoroutine(MovePlayer(right_dir));
}
}
private IEnumerator MovePlayer(Vector2 direction)
{
print(is_moving + "2");
is_moving = true;
float elapsed_time = 0;
orig_pos = transform.position;
target_pos = orig_pos + direction;
while(elapsed_time < move_time)
{
transform.position = Vector2.Lerp(orig_pos, target_pos, (elapsed_time / move_time));
elapsed_time += Time.deltaTime;
print("step" + i);
yield return null;
}
yield return new WaitForSeconds(0.2f);
transform.position = target_pos;
if (i > 1)
{
i--;
print(i);
OnExecuteClick();
}
if(i == 1)
{
is_moving = false;
}
print(is_moving + "4");
}
A slight explenation:
- This code handles movement on an isometric grid.
- while loop is for “animating\smoothing” player’s movement.
- The coroutine is handling movement of 1 tile exactly , the movement is determined by a dice so the coroutine happens as many time as the rolled number(rolled number = i).
- The code flow is this, you first roll a dice to determine how many tiles to move, you pick a direction and then you click on the “execute” button and you move said times on the said direction.
I have 2 problems so far:
A) is_moving is supposed to turn false at the end of the coroutine after the while loop has ended but it does not. is_moving becomes false before the movement stops. The movement is still visually happening meaning the code is still inside the while loop and yet is_moving somehow becomes false before the while loop stops
B)As you can see i have many prints trying to determine what’s wrong. The weird thing is that when i = 1 (on the last step) the console outputs (i have the code inside the parentheses for ease):
-
1 (print(i);)(after while loop)
-
True1 (print(is_moving + “1”);)(inside OnExecuteClick)
-
True2 (print(is_moving + “2”);)(before while loop)
-
step1 (print(“step” + i);)(inside while loop)
All good so far
-
False4 (print(is_moving + “4”);)(coroutine end ? while loop run only once ?)
-
step1 (print(“step” + i);)(and we are somehow again inside while loop)
-
step1 (after that, it runs as it should, print step1 a lot of times as it i moving)
-
… -||- …
-
False4 (and we end here when the code actually exits the coroutine)
As you can see, somehow the code exits the loop after running only once, reaches the end of the coroutine and then returns inside the while loop. This creates a problem in the grid since the player ends up in a position not alligned to the grid and I think is the cause of problem A.
To get into a bit more detail, Inside my scene i have 2 dice each with an execute button. I use is_moving to determine whether the next execute button can be pressed(meaning when you press the execute button of the first dice, is_moving = true, so now you have to wait for the moves to happen, is_moving is reset to false, before pressing the second execute to perform the next moves and so on). Now, if after you roll both dice pres the execute button of the first dice and then spam the execute button of the second the movement gets messed up. Some times it skips some moves, some times the player is not alligned with the grid(for example the player stops in-between two tiles). Since is_moving is supposed to reset AFTER ALL movement has stopped spamming the execute buttons should not be a problem. But apparently it is…
I have no idea why this is happening, I’ve found less than nothing online and I am desperate… This is happening on a game I am making for a game jam and it set me back a lot of hours sadly…
Before I end this wall of text I would like to know one more thing, when you call a function inside a coroutine (like I am doing) does the coroutine stop ? does the coroutine run in parallel with the called function ? or does the coroutine run till it’s exit and then calls the function ? I am guessing it’s the first one but I wasn’t able to confirm that so…
Thank you so much for your help and for going through this!