- Home /
How do you suspend key presses if a bool value is true?
I am trying to make some grid based movement where the character moves one tile for every key press with this code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private Vector3 targetPos;
private float tileLength = 1.1f;
private float speed = 5f;
private bool isMoving;
Rigidbody2D rb;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
if (!isMoving)
{
isMoving = true;
if (Input.GetKeyDown(KeyCode.UpArrow))
{
targetPos = new Vector3(transform.position.x, transform.position.y + tileLength, 0);
StartCoroutine(MovePlayer(targetPos, "up"));
} else if (Input.GetKeyDown(KeyCode.DownArrow))
{
targetPos = new Vector3(transform.position.x, transform.position.y - tileLength, 0);
StartCoroutine(MovePlayer(targetPos, "down"));
} else if (Input.GetKeyDown(KeyCode.LeftArrow))
{
targetPos = new Vector3(transform.position.x - tileLength, transform.position.y, 0);
StartCoroutine(MovePlayer(targetPos, "left"));
} else if (Input.GetKeyDown(KeyCode.RightArrow))
{
targetPos = new Vector3(transform.position.x + tileLength, transform.position.y, 0);
Debug.Log(isMoving);
StartCoroutine(MovePlayer(targetPos, "right"));
}
isMoving = false;
}
}
private IEnumerator MovePlayer(Vector3 tPos, string direc)
{
switch (direc)
{
case "up":
while (transform.position.y < tPos.y)
{
rb.velocity = new Vector3(0, speed, 0);
yield return null;
}
break;
case "down":
while (transform.position.y > tPos.y)
{
rb.velocity = new Vector3(0, -speed, 0);
yield return null;
}
break;
case "left":
while (transform.position.x > tPos.x)
{
rb.velocity = new Vector3(-speed, 0, 0);
yield return null;
}
break;
case "right":
while (transform.position.x < tPos.x)
{
rb.velocity = new Vector3(speed, 0, 0);
yield return null;
}
break;
}
rb.velocity = new Vector3(0, 0, 0);
transform.position = tPos;
}
}
After a bit of testing I think what's happening is that the isMoving bool isn't getting set to true at the beginning of the loop if it was previously set to false. So basically it's just constantly set to false when I don't think it should be. It feels like there's some super simple solution to this problem that I just don't know, but I don't know where to look XD.
Any and all help is appreciated!!!
GetKeyDown only triggers once per keypress anyway, so wouldn't it already have the behavior you want? What does your code do if you don't include the is$$anonymous$$oving logic?
Answer by xxmariofer · Dec 21, 2020 at 11:56 AM
ismoving is getting set to true but you are setting it back to false before finishing the update for some reason, which makes no sense, you need to move the
isMoving = false;
inside the coroutine and remove from the update
private IEnumerator MovePlayer(Vector3 tPos, string direc)
{
switch (direc)
{
case "up":
while (transform.position.y < tPos.y)
{
rb.velocity = new Vector3(0, speed, 0);
yield return null;
}
break;
case "down":
while (transform.position.y > tPos.y)
{
rb.velocity = new Vector3(0, -speed, 0);
yield return null;
}
break;
case "left":
while (transform.position.x > tPos.x)
{
rb.velocity = new Vector3(-speed, 0, 0);
yield return null;
}
break;
case "right":
while (transform.position.x < tPos.x)
{
rb.velocity = new Vector3(speed, 0, 0);
yield return null;
}
break;
}
rb.velocity = new Vector3(0, 0, 0);
transform.position = tPos;
isMoving = false;
}
Your answer

Follow this Question
Related Questions
how to move my camera... 2 Answers
player Movement using acceleration 2 Answers
How to get keyboard/controller state? 1 Answer
Can Unity3D recognise Keyboard events, when the window is not active? 0 Answers
Sprinting camera shake 1 Answer