1
\$\begingroup\$

This is my code so far:

public class PlayerMovement : MonoBehaviour
{
    public float moveSpeed;

    public Rigidbody2D rb;
    public Animator animator;

    Vector2 movement;

    void Update()
    {
        movement.x = Input.GetAxisRaw("Horizontal");
        movement.y = Input.GetAxisRaw("Vertical");
        movement = movement.normalized;

        if (movement.x != 0)
        {
            movement.y = 0;
        }

        else if (movement.y != 0)
        {
            movement.x = 0;
        }

        animator.SetFloat("Horizontal", movement.x);
        animator.SetFloat("Vertical", movement.y);
        animator.SetFloat("Speed", movement.sqrMagnitude);
    }

    void FixedUpdate()
    {
        rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
    }
}

I'm trying to restrict diagonal movement. The issue is that whenever up/down is being pressed, you can press left/right at the same time, and the object will then move left/right. When moving left/right, however, pressing up/down at the same time still has you continue left/right. Switching the position of the if/else if statements causes the same issue with converse directions. I'd prefer to have the player go in whatever the latest key press was for either direction!

I've tried making both statements if statements, as well as separating +/- values for both axes, but nothing changed! Any help is appreciated.

\$\endgroup\$
  • \$\begingroup\$ When the player moves up and releases up when holding down, left or right, what to do? \$\endgroup\$ – trollingchar Sep 23 '19 at 6:54
0
\$\begingroup\$

This code will store the last pressed direction key. When it's released, the key resets to None.

You'll need a field to store it, initialized with None:

KeyCode key = KeyCode.None;

Put this in Update:

if      (Input.GetKeyDown (KeyCode.W))  key = KeyCode.W;
else if (Input.GetKeyDown (KeyCode.A))  key = KeyCode.A;
else if (Input.GetKeyDown (KeyCode.S))  key = KeyCode.S;
else if (Input.GetKeyDown (KeyCode.D))  key = KeyCode.D;

if (Input.GetKeyUp (key))  key = KeyCode.None;

After this code you can set animator variables or move your character. The key variable will store the last pressed direction key or None. Handling may be done like this:

Vector2 direction; // (0, 0) by default
switch (key) {
    case KeyCode.W:  direction.y =  1;  break;
    case KeyCode.A:  direction.x = -1;  break;
    case KeyCode.S:  direction.y = -1;  break;
    case KeyCode.D:  direction.x =  1;  break;
}
// here you use direction variable to set animator params etc.
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you for the response! I put your code at the beginning of Update - should I go about having the player move in a different way than what I had previously? movement.x = Input.GetAxisRaw("Horizontal"); movement.y = Input.GetAxisRaw("Vertical"); allows the player to move diagonally. Apologies! Totally new to this. \$\endgroup\$ – David K. Sep 23 '19 at 15:45
  • \$\begingroup\$ @DavidK. you should handle movement depending on key in this case. The simplest way is to use switch block to set x and y. You'll not need GetAxisRaw. \$\endgroup\$ – trollingchar Sep 23 '19 at 19:19
  • \$\begingroup\$ @DavidK. answer edited \$\endgroup\$ – trollingchar Sep 24 '19 at 6:44
0
\$\begingroup\$

Assuming you want you character to move exclusively in the first direction it was told to go in:

You can store the movement state of the player across each tick of the game loop.

//Player variables stored somewhere
bool forwardHeld;
bool backwardHeld;
bool leftHeld;
bool rightHeld;

For your code itself, you will need to check what state it was in before and act based on that. For example:

//Was forward being held down last frame?
if(forwardHeld == true)
{
    //Yes, check if it is still being held down
    if(yourKeyboardVariableName.forwardKeyPressed == true)
    {
        //forward is still pressed, ignore further inputs.
    }
    else
    {
        //Forward is no longer pressed, reset its variable
        forwardHeld = false;

        //Is backward being pressed?
        if(yourKeyboardVariableName.backwardKeyPressed == true)
        {
            //Yes, set backward to true
            backwardHeld = true;
        }
        else
        {
            //No, are left or right (exclusive) being pressed?
               yourKeyboardVariableName.LeftKeyPressed !=
               yourKeyboardVariableName.RightKeyPressed)
            {
                if(yourKeyboardvariableName.LeftKeyPressed == true)
                {
                    leftHeld = true;
                }
                else
                {
                    rightHeld = true;
                }
            }//left/right?
        }//backward?
    }//forward still held
}//forward held
else if (backwardHeld)
{
    //Repeat for backward, etc.
}
...

After one of the four branches have executed, only one of the variables for forward/backward/left/right will be true and you can act on it as normal.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ He wants to move the character based on the last key, not the first. Also your code is too complicated, why not to use a single number/enum variable instead of all these flags? All == true can be omitted. If you know that a != b then you also know that if they are boolean then at least one of them is true, so your a || b is redundant. \$\endgroup\$ – trollingchar Sep 23 '19 at 7:11
  • \$\begingroup\$ I always write the == true because it is easier for people to understand than the implicit true. My background is in industrial automation so I try to keep things readable by the poor mechanic on night shift who has hardly touched a Fanuc robot. I wasn't sure from reading the question about first or last, so I offered the answer for anyone who might want it. You could use an int or enum and I do in my own code. I used flags for readability so it was clear what was doing what. The a!=b one is correct. Good point and I will update my post. \$\endgroup\$ – GaleRazorwind Sep 23 '19 at 16:16
  • \$\begingroup\$ Understandable. I guess our code styles and approaches for readability are too different. \$\endgroup\$ – trollingchar Sep 23 '19 at 19:29
  • \$\begingroup\$ No worries. There is more than one way to write code. Some people like very condensed, concise code and some people prefer more verbose code. As long as it functions as intended and at a fast enough speed for the application, then it is all good. Thanks for removing the down vote. \$\endgroup\$ – GaleRazorwind Sep 24 '19 at 2:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.