How to move 2D Object with WASD in Unity
Asked Answered
G

3

2

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.

Genius answered 15/10, 2017 at 22:59 Comment(5)
Can you describe your control? What's WASD used for?Weller
Just a general move up, down, left, right in a 2d game screen (sprites)Genius
Does the object have rigidbody2d?Weller
I'm going to be adding it later on when I add enemiesGenius
If you you are still struggling to apply boundary on the movement then look at this question another user asked. I left answer on how to do that there.Weller
W
12

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.

Weller answered 15/10, 2017 at 23:24 Comment(3)
what does Time.deltaTime do and can I still use my CheckBoundary(); function to prevent the player from going off the camera screen view boundaries?Genius
It makes sure that the move speed is the-same on every device/computer. Some devices are faster than others. Without that, it would be unfair for players to play against those with fast computers as their character would move faster. As for your second question, yes. If you can't do that then create a new question about restricting player movement to some boundaries.Weller
Shouldn't you handle physics calculations in the FixedUpdate instead of the Update function?Medievalism
B
2

THIS CODE WORK 100% (you must try it.)

public float moveSpeed = 5;


void Start()
{
   
}


 void Update()
{

    if (Input.GetKey(KeyCode.D))
    {
        transform.position += Vector3.right * moveSpeed * Time.deltaTime;
        
    }
    else if (Input.GetKey(KeyCode.A))
    {
        transform.position += Vector3.right * -moveSpeed * Time.deltaTime;
        
    }

    else if (Input.GetKey(KeyCode.W))
    {
        transform.position += Vector3.up * moveSpeed * Time.deltaTime;

    }
    else if (Input.GetKey(KeyCode.S))
    {
        transform.position += Vector3.up * -moveSpeed * Time.deltaTime;

    }
}
Brogan answered 25/8, 2021 at 15:43 Comment(1)
Worked for me as of Oct '21Intonate
B
0

Try changing the value 0 in the Vector2 functions to current x/ y position...I ran into a similar problem with my project

if (userInputV < 0) 
        _currentPosY -= new Vector2 (/*current position*/, speed); 
Bleacher answered 13/9, 2020 at 12:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.