# bools and if-statement logic

Hi Guys, I was making a top down movement system. problem is that when I hold ‘A’ key to move left simultaneously press ‘D’ key the player change its direction and start moving in right and same happens with W and S keys. I cannot use simple if statements to change direction(using if statements instead of else-if makes the player go diagonal).I think what i need is when one if-statement is running then other should stop working. I tried to use bools to manage the if statements but it didn’t work. Here is the code:

``````void Move()
{
float movX = 0;
float movY = 0;

if (Input.GetKey(KeyCode.D) )
{
movX = 1f;
}
else if (Input.GetKey(KeyCode.A))
{
movX = -1f;
}

else if (Input.GetKey(KeyCode.W))
{
movY = 1f;
}
else if (Input.GetKey(KeyCode.S))
{
movY = -1f;
}

Vector2 movDir = new Vector2(movX, movY);

idle = movX == 0 && movY == 0;
if (idle)
{
rigidbody2d.velocity = Vector2.zero;
}
else
{
rigidbody2d.velocity = movDir * speed;
}
}
``````

I have been staring at this code for long enough. Can anyone give me some guidance.

You do not want the `else` statement on line 16.

1 Like

Thanks Kurt for replying, I don’t want diagonal movement in the game so making it `if` will do the opposite. Problem is with ‘A’ and ‘D’ . If I press ‘D’ key while holding ‘A’ it changes direction to right. Is there any way to make first `if` statement(Line 7) stop when second `else` statement (Line 11) is running? I mean I know we can use `Bool` to tackle this problem but the logic is not clicking in my mind.

Do you mean that want only one axis of motion to be possible at once? eg only left, right, up or down (or sit still)?

It seems to me your original code would do that. If it does not, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

• is this code even running? which parts are running? how often does it run?
• what are the values of the variables involved? Are they initialized?

1 Like

Oh Yes code is working fine (kind of) and yes I want motion in one axis at a time I don’t want any diagonal movements . Problem is when I am holding ‘A’ key it moves the player left but simultaneously if I hold ‘D’ key it moves the player in right direction(and I am still holding the ‘A’ key). I think what I am looking for is when one if statement is running others should stop working. (I did use Debug.Log statements to track the movDir Vector and it was working fine. Problem is with the if statements.)

That is a little bit trickier and requires maintaining from frame to frame which key was down.

What you would need to do is track which key was active last frame, check if it is still active this frame, and if so, disregard ALL other keys. Only when the key from the previous frame is not down would you consider checking the other keys.

1 Like

Why using GetKey instead of GetButton? Using GetButton / GetAxis allow the player to map the key as he likes.
In addition, it is not recommended editing the velocity directly.
One last thing that I cannot see here but you could have implemented it somewhere else, always multiply your desired move speed by Time.deltaTime - If you will not, to player movement speed will be inconsistent during gameplay and across different platforms.

Now basically the problem is that you have 4 different if statements that the code checks 1 by 1.
That means that if you hold the D key, and after a while you hold the A key as well, the player will continue to go right since the if statement of D key is first.
The same goes if you hold A and then you hold W well. But if you will then hold D as well, the player will go right.

Just a note, I barely know any games that don’t allow interruption and forcing you to move by one direction if you hit a key no matter what key your press later on.
But the piece of code below is a solution for your problem I came up real quick. I can’t tell you if it’s the most efficient way, it probably isn’t, but it should give you a clue.
It feels clunky in my opinion though.

``````public class YourClass : MonoBehaviour
{

bool isDPressed = false;
bool isAPressed = false;
bool isWPressed = false;
bool isSPressed = false;
bool isAnyKeyPressed = false;
void Update()
{
GetPlayerMovement();
}

private void GetPlayerMovement()
{
float movX = 0;
float movY = 0;

if (Input.GetKey(KeyCode.D) && !isAnyKeyPressed || Input.GetKey(KeyCode.D) && isAnyKeyPressed && isDPressed)
{
movX = 1f;
isAnyKeyPressed = true;
isDPressed = true;
}
else if (Input.GetKey(KeyCode.A) && !isAnyKeyPressed || Input.GetKey(KeyCode.A) && isAnyKeyPressed && isAPressed)
{
movX = -1f;
isAnyKeyPressed = true;
isAPressed = true;
}

else if (Input.GetKey(KeyCode.W) && !isAnyKeyPressed || Input.GetKey(KeyCode.W) && isAnyKeyPressed && isWPressed)
{
movY = 1f;
isAnyKeyPressed = true;
isWPressed = true;
}
else if (Input.GetKey(KeyCode.S) && !isAnyKeyPressed || Input.GetKey(KeyCode.S) && isAnyKeyPressed && isSPressed)
{
movY = -1f;
isAnyKeyPressed = true;
isSPressed = true;
}
else
{
isDPressed = false;
isAPressed = false;
isWPressed = false;
isSPressed = false;
isAnyKeyPressed = false;
}

Vector2 movDir = new Vector2(movX, movY);
transform.Translate(movDir * speed * Time.deltaTime);
}
}
``````
1 Like

Sorry for late reply. This worked like charm. I knew we can manage this with booleans but logic was not clicking in my head. I’ll keep those tips in mind. Thanks