How to move 2D Object with WASD in Unity

41,642

Solution 1

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.

Solution 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;

    }
}
Share:
41,642

Related videos on Youtube

5120bee
Author by

5120bee

Why StackOverflow SUCKS StackOverflow is a monster Q&A machine. If you have a programming question, StackOverflow is probably the best place to ask – you have a better chance to get an answer on SO than anywhere else. The paradox is that SO is not interested in users getting answers to their questions. Usually Q&A sites want their questioners to be happy, but not SO. SO wants great questions and great answers. Hence the reputation system and an army of Nazi retards moderating everything they can see. If a question is considered poor by the user with moderating privileges, it will be downvoted, closed and finally deleted. But that is not all – SO has an automatic ban system. Users providing questions & answers that received low marks can be banned by robots. One of the first questions I answered on SO more that 2 years ago was: Here is a task: “3 brothers have to transfer 9 boxes from one place to another. These boxes weigh 1, 2, 4, 5, 6, 8, 9, 11, 14 kilos. Every brother takes 3 boxes. So, how to make a program that would count the most optimal way to take boxes? The difference between one brother’s carrying boxes weight and other’s has to be as small as it can be.” Can you just give me an idea or write a code with any programming language you want ( php or pascal if possible? ). Thanks. I thought the question was interesting and after spending some time found a solution based on checking all permutations of 9 weight numbers, it appeared to be blazingly fast. I posted an answer, and my answer was accepted by the questioner. Sure that was not a great question. Also the question was not properly tagged – with ‘php’ and ‘pascal’. I guess ‘php’ tag was a mistake; the questioner got a whole army of moderating idiots attacking his question. The question received 17 downvotes. The question got the comment Smells like homework to me and the comment got 14 upvotes; the presumption of innocence does not work on SO, and a guy with the editing privileges tagged the question as ‘homework’. Later on it was closed by the moderator called Bill the Lizard with the following resolution: It’s difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. Strange resolution, isn’t it? The question was answered… The strange guy Bill the Lizard did not stop after closing the question. More than 1.5 year (!) after the question was answered he returned to it and deleted both the question and my answer (my answer probably because it contradicted his resolution). If you think your post was not well accepted on SO, just think of the whole picture. ~ Serg

Updated on January 13, 2022

Comments

  • 5120bee
    5120bee almost 2 years

    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.

    • Programmer
      Programmer about 6 years
      Can you describe your control? What's WASD used for?
    • 5120bee
      5120bee about 6 years
      Just a general move up, down, left, right in a 2d game screen (sprites)
    • Programmer
      Programmer about 6 years
      Does the object have rigidbody2d?
    • 5120bee
      5120bee about 6 years
      I'm going to be adding it later on when I add enemies
    • Programmer
      Programmer about 6 years
      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.
  • 5120bee
    5120bee about 6 years
    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?
  • Programmer
    Programmer about 6 years
    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.
  • Geordi Rugenbrink
    Geordi Rugenbrink over 4 years
    Shouldn't you handle physics calculations in the FixedUpdate instead of the Update function?
  • Grace Thompson
    Grace Thompson about 2 years
    Worked for me as of Oct '21