Search Unity

2D Movement

Discussion in '2D' started by Silasi, Sep 8, 2019.

  1. Silasi

    Silasi

    Joined:
    Jul 25, 2016
    Posts:
    48
    Hey guys,

    I really struggle with implementing a good, working movement system. Every tutorial out there is based on joysticks and GetAxis but I want to work only with touch input.

    This is what I made, moving the player to the left when the left side of the screen is touched:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class InputScript : MonoBehaviour
    6. {
    7.     public int speed;
    8.     private int touchWidth;
    9.     private Rigidbody2D playerRB;
    10.  
    11.     void Start()
    12.     {
    13.         touchWidth = Screen.width / 2;
    14.     }
    15.  
    16.     void Update()
    17.     {
    18.         InputCheck();
    19.     }
    20.  
    21.     private void InputCheck()
    22.     {
    23.         if(Input.touchCount > 0)
    24.         {
    25.             Touch touch = Input.GetTouch(0);
    26.  
    27.             //Move Left
    28.             if (touch.position.x <= touchWidth)
    29.             {
    30.                 playerRB.velocity = new Vector2(-5, 0) * Time.deltaTime * speed;
    31.                 if (touch.phase == TouchPhase.Ended)
    32.                 {
    33.                     playerRB.velocity = new Vector2(0, 0);
    34.                 }
    35.             }
    36.         }
    37.     }
    38. }

    It works as I want. It is snappy, it feels right. What doesn't work is when I let go of the touch. It's not always registering. 2 out of 10 cases when I stop touching the screen, the player continues to move left.

    I tried to move "if (touch.phase == TouchPhase.Ended)" elsewhere but then the jump won't work because for the jump, I want just to tap on the top sides of the screen. By just tapping, it registeres the jump, it jumps, and then immediately it stops because it registeres an ended touch and it sets the velocity to 0.

    Kinda new to programming and I need some help finding a way around this...
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    This line is very odd. You're setting a velocity using a mixed bag of a constant velocity (-5,0) multiplied by a "speed" (integer but should really be a float) but then multiplied by the amount of time the last frame took. The last (time) part doesn't make sense and would only make sense if you were making changes (acceleration or deceleration).

    If you want to set a specific velocity when you're touching and want to move left then I'd just use:
    Code (CSharp):
    1. playerRB.velocity = Vector2(-speed, 0);
    There are other ways to tidy the code up, specially if you also want movement right but for now, the time part is certainly not correct.
     
  3. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    I'm kind of guessing at what you want but changing it all might look like:
    Code (CSharp):
    1. using UnityEngine;
    2.    
    3. public class InputScript : MonoBehaviour
    4. {
    5.     public float speed;
    6.     private float touchWidth;
    7.     private Rigidbody2D playerRB;
    8.    
    9.     void Start()
    10.     {
    11.         touchWidth = Screen.width / 2;
    12.     }
    13.    
    14.     void Update()
    15.     {
    16.         InputCheck();
    17.     }
    18.    
    19.     private void InputCheck()
    20.     {
    21.         if (Input.touchCount > 0)
    22.         {
    23.             Touch touch = Input.GetTouch(0);
    24.  
    25.             if (touch.phase == TouchPhase.Ended)
    26.             {
    27.                 playerRB.velocity = Vector2.zero;
    28.                 return;
    29.             }
    30.    
    31.             // Move Left
    32.             if (touch.position.x <= touchWidth)
    33.             {
    34.                 playerRB.velocity = new Vector2(-speed, 0);
    35.             }
    36.         }
    37.     }
    38. }
    39.  
    Note I changed the speed/touchWidth to be floats. The speed will need to be changed to be x5 what you original set.
     
    Silasi likes this.
  4. Silasi

    Silasi

    Joined:
    Jul 25, 2016
    Posts:
    48
    Thank you! Yeah... the Time.deltaTime was there because I thought that maybe velocity is related to physics and so it needs to be multiplied by deltaTime
     
  5. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    It is related to physics (the body velocity) but it's you're not changing it over time, just setting it to a constant value therefore doesn't need scaling against time.
     
    Silasi likes this.
  6. Silasi

    Silasi

    Joined:
    Jul 25, 2016
    Posts:
    48
    Understood. Thank you for helping!
     
    MelvMay likes this.