Search Unity

Moving at a constant speed in 2D

Discussion in 'Physics' started by 15north97, May 5, 2020.

  1. 15north97

    15north97

    Joined:
    May 3, 2020
    Posts:
    5
    Hello,

    I am working on getting my 2D sprite to move in a certain way, but I can't seem to make it work.
    I want the sprite to move at a constant speed and be able to move in 6 directions. Right now the sprite has a bit of a lag between the button press and the movement. Also, the movement is not smooth when changing directions.

    Code (CSharp):
    1. void Update()
    2.     {
    3.         //Store the current horizontal input in the float moveHorizontal.
    4.         int moveHorizontal = (int)Input.GetAxis ("Horizontal");
    5.  
    6.         //Store the current vertical input in the float moveVertical.
    7.         int moveVertical = (int)Input.GetAxis ("Vertical");
    8.  
    9.         //Use the two store floats to create a new Vector2 variable movement.
    10.         Vector2 movement = new Vector2 (moveHorizontal, moveVertical);
    11.  
    12.         //Call the AddForce function of our Rigidbody2D rb2d supplying movement multiplied by speed to move our player.
    13.         rb2d.velocity = movement.normalized * speed;
    14.     }
    Anything would help!
    Thanks,
    Jacob
     
  2. norilalatoli

    norilalatoli

    Joined:
    Aug 9, 2018
    Posts:
    12
    Hello Jacob,

    The lag is because of the way you get your movement from your input.

    Code (CSharp):
    1. (int)Input.GetAxis("Horizontal")
    Input.GetAxis returns a float in the range of 0,1 depending on how long you are holding the button.
    When you cast a float as an int, you always round down to the nearest integer.
    As a result, (int)Input.GetAxis will return 0 until it Input.GetAxis reaches 1. This is the source of your delay.

    To fix this, simply use Input.GetAxisRaw()

    Code (CSharp):
    1. (int)Input.GetAxisRaw("Horizontal")
    This function returns either 0 or 1 depending on if you are pressing the button. That will give you immediate movement.

    Furthermore, you do not need to cast to integers at all. Vectors love floats as much as integers.
    Also, Input.GetAxis and Input.GetAxisRaw return only 0 to 1. You do not have to and infact should not normalize the vector you get by combing the x and y components.
    Normalizing the vector sets the magnitude of the vector of 1, so if you have

    movement.x = 1 and
    movement.y = 1

    movement.normalized will give you components
    movement.x = 0.707 (sqrt(1))
    movement.y = 0.707 (sqrt(1))

    Just get rid of the .normalized part and you are good.

    Your final code should like:

    Code (CSharp):
    1. void Update()
    2.     {
    3.         //Store the current horizontal input in the float moveHorizontal.
    4.         float moveHorizontal = Input.GetAxisRaw ("Horizontal");
    5.         //Store the current vertical input in the float moveVertical.
    6.         float moveVertical = Input.GetAxisRaw ("Vertical");
    7.         //Use the two store floats to create a new Vector2 variable movement.
    8.         Vector2 movement = new Vector2 (moveHorizontal, moveVertical);
    9.         //Call the AddForce function of our Rigidbody2D rb2d supplying movement multiplied by speed to move our player.
    10.         rb2d.velocity = movement * speed;
    11.     }