I don't understand this coroutine
So basically I'm trying to understand why my coroutine keeps getting called by the update method each frame. I find this weird because I'm turning one of the conditions for Update off when starting the coroutine. If anyone could provide some insight it would be greatly appreciated!
enum Direction
{
North,
East,
South,
West
}
void Update()
{
if (!isMoving && isAllowedToMove)
{
input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
if (Mathf.Abs(input.x) > Mathf.Abs(input.y))
input.y = 0;
else
input.x = 0;
if (input != Vector2.zero)
{
if (input.x < 0)
{
currentDir = Direction.West;
}
if (input.x > 0)
{
currentDir = Direction.East;
}
if (input.y < 0)
{
currentDir = Direction.South;
}
if (input.y > 0)
{
currentDir = Direction.North;
}
StartCoroutine(ChgDir());
}
}
}
public IEnumerator ChgDir()
{
isMoving = true;
switch (currentDir)
{
case Direction.North:
gameObject.GetComponent<SpriteRenderer>().sprite = walk_up_left;
yield return new WaitForSeconds(0.1f);
gameObject.GetComponent<SpriteRenderer>().sprite = northSprite;
break;
case Direction.East:
gameObject.GetComponent<SpriteRenderer>().sprite = walk_right_left;
yield return new WaitForSeconds(0.1f);
gameObject.GetComponent<SpriteRenderer>().sprite = eastSprite;
break;
case Direction.South:
gameObject.GetComponent<SpriteRenderer>().sprite = walk_down_left;
yield return new WaitForSeconds(0.1f);
gameObject.GetComponent<SpriteRenderer>().sprite = southSprite;
break;
case Direction.West:
gameObject.GetComponent<SpriteRenderer>().sprite = walk_left_left;
yield return new WaitForSeconds(0.1f);
gameObject.GetComponent<SpriteRenderer>().sprite = westSprite;
break;
}
isMoving = false;
yield return 0;
}
Hello.
You do this at the end of the corutine
is$$anonymous$$oving = false;
So it can be executed again, no? and only waits for 0.1 seocnds, so it is executed 10 times a seconds
To follow up on what TA wrote, try increasing the delay. Replace all of those 0.1's with a variable "moveWaitSeconds" or something. Set it to 2.0 (something so huge you can't miss it). Then make sure is$$anonymous$$oving is public in the Inspector -- you should see it uncheck for 2 seconds, then go back on.
Answer by anilhdas · Oct 29, 2019 at 06:11 AM
TLDR: isAllowedToMove
is not seemingly reset!
The boolean isMoving
is reset to false at the end of each Coroutine call, which makes the 1st condition in update to be true.
And assuming initial value isAllowedToMove
to be true (If not the coroutine wouldn't be called at all), I don't see it being reset to false.
Answer by davve146 · Oct 29, 2019 at 09:52 PM
Thanks for the reply @anilhdas .
The thing is that isAllowedToMove
is always true unless another method or script changes its value. In other words I always want the update method to be called unless some in-game event changes it or the character is moving ( isMoving = false
). The problem here is that update is called again before the character has stopped moving, resulting in the coroutine running several times instead of once. If I insert a Debug.Log()
statement it prints several times over the course of the character moving once.
I’m assuming that the coroutine doesn’t wait long enough for the action to complete but I could be totally wrong about that. Thanks again for the reply
Your answer
![](https://koobas.hobune.stream/wayback/20220612213640im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Why isn't my coroutine working when I call it from another script. 0 Answers
Coroutine Not working properly. 1 Answer
Coroutines and loading screens 1 Answer
Using Grid-like singletons but have an issue with Coroutines. 2 Answers
"Can't add script behaviour AICharacterControl. The script needs to derive from MonoBehaviour!" ? 0 Answers