How to move 2D Object with WASD in Unity

5120bee picture 5120bee · Oct 16, 2017 · Viewed 30.5k times · Source

My code below only works for horizontal movement. Shouldn't the vertical movement be working too? I'm just starting out with basic 2D Unity programming:

public class Player : MonoBehaviour {

    //These fields will be exposed to Unity so the dev can set the parameters there
    [SerializeField] private float speed = 1f;
    [SerializeField] private float upY;
    [SerializeField] private float downY;
    [SerializeField] private float leftX;
    [SerializeField] private float rightX;

    private Transform _transformY;
    private Transform _transformX;
    private Vector2 _currentPosY;
    private Vector2 _currentPosX;

    // Use this for initialization
    void Start () {
        _transformY = gameObject.GetComponent<Transform> ();
        _currentPosY = _transformY.position;        

        _transformX = gameObject.GetComponent<Transform> ();
        _currentPosX = _transformX.position;
    }

    // Update is called once per frame
    void Update () {
        _currentPosY = _transformY.position;
        _currentPosX = _transformX.position;

        float userInputV = Input.GetAxis ("Vertical");
        float userInputH = Input.GetAxis ("Horizontal");

        if (userInputV < 0) 
            _currentPosY -= new Vector2 (0, speed);     

        if (userInputV > 0)
            _currentPosY += new Vector2 (0, speed);

        if (userInputH < 0)
            _currentPosX -= new Vector2 (speed, 0);

        if (userInputH > 0)
            _currentPosX += new Vector2 (speed, 0);

        CheckBoundary ();

        _transformY.position = _currentPosY;
        _transformX.position = _currentPosX;
    }

    private void CheckBoundary(){
        if (_currentPosY.y < upY)
            _currentPosY.y = upY;

        if (_currentPosY.y > downY)
            _currentPosY.y = downY;

        if (_currentPosX.x < leftX)
            _currentPosX.x = leftX;

        if (_currentPosX.x > rightX)
            _currentPosX.x = rightX;
    }
}

If I remove/comment out the _currentPosX and it's related codes then my Vertical movement works. But if I remove/comment out the _currentPosY and it's related codes then my Horizontal movement works.

But how come I'm having trouble getting them to work at the same time? I think I'm just missing something but I can't figure it out since I'm just a beginner at this.

Thanks to whoever can give advise.

EDIT: for further clarification...

I'm coding a simple 2d game that will have the player move in 4-directions using the WASD keys.

W = move up
A = move left
S = move down
D = move right

My main problem is that I can get two of the keys working only in one axis: either A and D is working for Horizontal while W and S are not working at all for Vertical movement or vice-versa.

Answer

Programmer picture Programmer · Oct 16, 2017

You don't need those if statements. Just use += to append the input to the current transform position.

Move without Rigidbody:

public float speed = 100;
public Transform obj;

public void Update()
{
    float h = Input.GetAxis("Horizontal");
    float v = Input.GetAxis("Vertical");

    Vector3 tempVect = new Vector3(h, v, 0);
    tempVect = tempVect.normalized * speed * Time.deltaTime;

    obj.transform.position += tempVect;
}

Move Object with Rigidbody2D:

public float speed = 100;
public Rigidbody2D rb;

public void Update()
{
    float h = Input.GetAxis("Horizontal");
    float v = Input.GetAxis("Vertical");

    Vector3 tempVect = new Vector3(h, v, 0);
    tempVect = tempVect.normalized * speed * Time.deltaTime;
    rb.MovePosition(rb.transform.position + tempVect);
}

I suggest using the second code and moving the Rigidbody if you want to be able to detect collison later on.

Note:

You must assign the object to move to the obj slot in the Editor. If using the second code, assign the object with the Rigidbody2D to the rb slot in the Editor.