0

I want to put a delay on the characters movement every time an arrow button is pressed so the player can't just spam move, but for some reason my IEnumerator function doesn't work and it doesn't wait. I'm not sure if I'm using it wrong since I'm getting back into unity. I'm using version 2019.3.14f1 if that helps.

using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Security.Cryptography;
using System.Threading;
using UnityEngine;

public class Movement : MonoBehaviour
{
    void Start()
    {
        transform.position = new Vector3(0, 0, 0);
    }

    void Update()
    {
        CalculateMovement();
    }

    private IEnumerator delay()
    {
        yield return new WaitForSeconds(1);
    }

    void CalculateMovement() 
    {
        if (Input.GetKey(KeyCode.UpArrow))
        {
            if (transform.position.y != 4)
            {
                StartCoroutine(delay());
                transform.position += new Vector3(0, 1, 0);
            }
        }
        else if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            if (transform.position.y != -4)
            {
                StartCoroutine(delay());
                transform.position += new Vector3(0, -1, 0);
            }
        }
        else if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            if (transform.position.x != 4)
            {
                StartCoroutine(delay());
                transform.position += new Vector3(1, 0, 0);
            }
        }
        else if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            if (transform.position.x != -4)
            {
                StartCoroutine(delay());
                transform.position += new Vector3(-1, 0, 0);
            }
        }
    }
}
  • From [the documentation](https://docs.unity3d.com/ScriptReference/WaitForSeconds.html) it looks like you're doing the right thing. Are you sure your `if` statements are correct? Looks a bit iffy that you're calling `GetKey` in the first one and `GetKeyDown` in the rest. – Wai Ha Lee Aug 31 '22 at 15:33
  • 2
    No he's not, what are you talking about? – Blindy Aug 31 '22 at 15:34

2 Answers2

1

The coroutine part is just this:

private IEnumerator delay()
{
    yield return new WaitForSeconds(1);
}

You can't call StartCoroutine() on it and then do your work expecting it to be delayed, the delayed part has to be part of your coroutine, like this:

private IEnumerator BetterNamePlease()
{
    yield return new WaitForSeconds(1);
    transform.position += new Vector3(0, 1, 0); // use parameters here
}
Blindy
  • 65,249
  • 10
  • 91
  • 131
  • Just adding to this: Also don't expect `transform.position.x != -4` to behave correctly. See [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) => `if(!Mathf.Approximately(transform.position.x, 4))` ... and also `if (Input.GetKey(KeyCode.UpArrow))` should probably rather be `if (Input.GetKeyDown(KeyCode.UpArrow))` – derHugo Aug 31 '22 at 15:43
  • Finally (opinion based) - UX wise it is pretty uncanny to wait a second to see your input handled ;) – derHugo Aug 31 '22 at 15:44
0

The StartCoroutine does not block code execution, it kind of just allows logic to continue while executing other logic. If you're trying to prevent the user from moving at all you can use something like this:

public class Movement : MonoBehaviour
{
    private bool CanMove = true;

    void Start()
    {
        transform.position = new Vector3(0, 0, 0);
    }

    void Update()
    {
        CalculateMovement();
    }

    private IEnumerator DelayMovement()
    {
        CanMove = false;

        yield return new WaitForSeconds(1);
        
        CanMove = true;
    }

    void CalculateMovement() 
    {
        if (!CanMove)
        {
            return;
        }

        if (Input.GetKey(KeyCode.UpArrow))
        {
            if (transform.position.y != 4)
            {
                StartCoroutine(DelayMovement());
                transform.position += new Vector3(0, 1, 0);
            }
        }
        // etc
    }
}
Daevin
  • 778
  • 3
  • 14
  • 31