key press one a time....

Hi all, this is my 1st answer, and yes I’m new in unity, I’m still make a game where the player move just in X and Z direction, with arrow keys, my problem is:
When I press up/down arrow and at same time I press left/right, nothing append, that’s ok I want it move up/down, but when I press left/right and I press up/down it change, why?
This is the code I put on fixedUpdate.
I try also to invert the code, put left/right up on the code and unity invert the situation, but the problem is not solve.

    //Movement
if (Input.GetKey(KeyCode.UpArrow))
{
	rigidbody.MovePosition(rigidbody.position + speedH * Time.deltaTime);
}

else if (Input.GetKey(KeyCode.DownArrow))
{
	rigidbody.MovePosition(rigidbody.position + -speedH * Time.deltaTime);
}

else if (Input.GetKey(KeyCode.LeftArrow))
{
	rigidbody.MovePosition(rigidbody.position + -speedV * Time.deltaTime);
}

else if (Input.GetKey(KeyCode.RightArrow))
{
	rigidbody.MovePosition(rigidbody.position + speedV * Time.deltaTime);
}

I want who play need to release the key to start to move in a different direction, it’s a puzzle game :smiley:

I make an online version, this is just the prototype, use arrow and try :smiley:
http://www.williamjcrow.altervista.org/file/prova.html

Thanks in advanced

P.S. Sorry for my english, I’m not native :wink:

Basically what happens is the fact that every update it checks if you press one of those buttons, because of the order and the else it will stop after the first if that returns true. up will go before down, before left, before right.

to solve this add

private KeyCode keyPressed;

Update()
{
if (Input.GetKey(KeyCode.UpArrow) && keyPressed == KeyCode.None || keyPressed == KeyCode.UpArrow && Input.GetKey(keyPressed))
{
rigidbody.MovePosition(rigidbody.position + speedH * Time.deltaTime);
keyPressed = KeyCode.UpArrow;
}

// and add those for the other arrowkeys as well

// then add

if(Input.GetKeyUp(keyPressed))
{
keyPressed = KeyCode.None;
}
}

First wrong decision, the Input in the Update.

Input shoudl be in Update to be checked every frame.
Long story short, FU happens at fixed rate, Update happens every frame and your input is generating by OS every frame. If your Update runs 100fps and your FU runs 60fps you have 405 chance your input may be missed.

Now to fix all that.

enum Previous{Vert, Hor, None}
Previous state;
Vector3 velocity;

void Update()
{
    float hor = Input.GetAxis("Horizontal");
    float ver = Input.GetAxis("Vertical");
    if(hor != 0 && (state == Previous.None || state == Previous.Hor))
    {
         velocity = rigidbody.position + speedH * hor;
         state = Previous.Hor;
    }
    if(ver != 0 && (state == Previous.None || state == Previous.Vert))
    {
         velocity = rigidbody.position + speedV *ver;
         state = Previous.Vert;
    }
    if(hor == 0 && ver == 0)state = Previous.None;
}

In this case you have to have a moment where all buttons are up. Is it what you are after?

Quite an old question, but I was attempting the same thing and came across a much more streamlined method.

	public float moveSpeed = 10.0f;
	public Vector3 moveVector;

    void Update()
    {
        GetInput(Input.GetAxis ("Vertical"), Input.GetAxis("Horizontal"));
    }
    
    void GetInput(float vert, float horiz)
    {
//apply directional vectors
    		moveVector = (transform.forward * vert + transform.right * horiz) * moveSpeed;

//cap speed
    		moveVector = Vector3.ClampMagnitude(moveVector, moveSpeed);
//apply to velocity
    		rigidbody.velocity = moveVector;
    }

It eliminates all the if checks. That’s a good place to start. I ended up putting acceleration into it so the changing of directions isn’t so instant but this method works just fine. You don’t have to pass in the Inputs as parameters, that’s just what I did. Hope it helps someone.