Search Unity

2D Movement Issue

Discussion in 'Getting Started' started by cchin25, Jan 12, 2020.

  1. cchin25

    cchin25

    Joined:
    Jan 22, 2019
    Posts:
    3
    Hello,

    I'm playing with top-down 2D movement fundamentals and running into either

    #1. Movement is smooth, but player collider bounces off 2D Tilemap Colliders (walls)
    ex: (while holding left arrow key down) https://imgur.com/a/fJLlMow

    #2. Character doesn't bounce off walls, but as the sprite moves across screen its jittery.

    I understand that the issue with 1 seems to be that the tilemap colliders still behave with physics, so when my character collider hits them, it goes through a bit, and the wall pushes it back out. As I understand it #2 is due to frames being out of sync (update vs fixedupate)

    I can see it happening in simple video tutorials as well, but the people never mention it and all my googling puts me in the same spot where one gets fixed, but the other occurs.

    This is the script that has the smooth movement but gets pushed by the walls:

    Code (CSharp):
    1. public class PlayerMovementAlt : MonoBehaviour
    2. {
    3.     private float speed = 5.0f;
    4.  
    5.     private Rigidbody2D thisRigidBody = null;
    6.     private Vector3 movement = new Vector3();
    7.     void Start()
    8.     {
    9.         thisRigidBody = GetComponent<Rigidbody2D>();
    10.     }
    11.  
    12.     void Update()
    13.     {
    14.      
    15.         ProcessInputs();
    16.         Move();
    17.     }
    18.  
    19.     private void ProcessInputs()
    20.     {
    21.         movement = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
    22.         movement.Normalize();
    23.     }
    24.     private void Move()
    25.     {
    26.         transform.position = transform.position + (movement * speed * Time.deltaTime);
    27.     }
    28. }
    Being a beginner, is the problem that I shouldn't be using the 2D tilemap collider for walls at all? Or is there a fix for the script? Thanks for any thoughts.
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Yes, that's the problem. You almost certainly shouldn't be using physics at all in a game like this. Move your objects around by simply assigning a new transform.position on each frame. If you have a tile map for your environment, check the tile map yourself to decide when it's OK to move, and if not, what to do about it.

    The physics engine is like the dark side of the Force: it may seem easier, quicker to join you in a fight, but once you start down that dark path, forever will it consume your destiny.
     
    cchin25 likes this.
  3. cchin25

    cchin25

    Joined:
    Jan 22, 2019
    Posts:
    3
    I thought that might be the case lol. Thank you for the feedback, I'll go back to the drawing board.
     
  4. cchin25

    cchin25

    Joined:
    Jan 22, 2019
    Posts:
    3
    Just an fyi, I ended up finding the exact issue described within the Ruby 2D tutorial on page 9.

    To fix Ruby’s jittering, you need to move the Rigidbody itself and not the GameObject Transform, and let the Physics System synchronize the GameObject position to the Rigidbody position. That way, the physics system can stop the movement before it gets inside the box, rather than having to move Ruby after she is already in the box.

    Code (CSharp):
    1. public class RubyController : MonoBehaviour
    2. {
    3.    Rigidbody2D rigidbody2d;
    4.    
    5.     // Start is called before the first frame update
    6.     void Start()
    7.     {
    8.         rigidbody2d = GetComponent<Rigidbody2D>();
    9.     }
    10.  
    11.     // Update is called once per frame
    12.     void Update()
    13.     {
    14.         float horizontal = Input.GetAxis("Horizontal");
    15.         float vertical = Input.GetAxis("Vertical");
    16.        
    17.         Vector2 position = rigidbody2d.position;
    18.         position.x = position.x + 3.0f* horizontal * Time.deltaTime;
    19.         position.y = position.y + 3.0f * vertical * Time.deltaTime;
    20.  
    21.         rigidbody2d.MovePosition(position);
    22.     }
    23. }
     
  5. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Well, yes, if you want to use the physics system, that's how you use it. But I still claim (from long experience) that you'll be better off without it, unless you're making an Angry Birds clone or something that really requires physics.
     
    BrandyStarbrite likes this.