Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

2D rigidbody bounces over tiled colliders

Discussion in 'Scripting' started by Hero101, Jun 28, 2016.

  1. Hero101

    Hero101

    Joined:
    Jul 14, 2015
    Posts:
    158
    *If this question would be better in another forum please let me know and I will move it*

    Making a 2D platformer with tiled sprites. The player has a circle collider and the tiles (ground) has box colliders. Was having issues with the player being all jittery but realized that only happened in the editor and not the build. But there is still one more problem: when the player moves along the ground he bounces ever so slightly.

    The tiles/colliders match up perfectly. I tried other suggestions I found such as adding a physics material to the ground tiles and/or adjusting the Min Penetration for Penalty in the Physics2D settings but it didn't help at all. Making the rigidbody kinematic eliminates the bounce but I don't want to do that as this is my first time controlling a character with its rigidbody and I want to learn how.

    I'm not using the 2d Character Controller the Unity gives you. Added my own rigidbody, collider, and a very basic script to the player sprite:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayerController : MonoBehaviour {
    5.  
    6.     public float speed;
    7.  
    8.     private Rigidbody2D rb;
    9.  
    10.     void Awake ()
    11.     {
    12.         transform.localScale = new Vector3(-0.4f, 0.4f, 0.4f);
    13.     }
    14.  
    15.     void Start ()
    16.     {
    17.         rb = GetComponent<Rigidbody2D>();
    18.     }
    19.  
    20.     void FixedUpdate ()
    21.     {
    22.         float horizontalMovement = Input.GetAxis ("Horizontal");
    23.         rb.velocity = new Vector2 (horizontalMovement * speed, rb.velocity.y);
    24.     }
    25. }
    26.  
    I assume it's something funky with the character going over tiled sprites that each have a box collider because if I move him on top on a single, long box collider he doesn't bounce.

    Any idea how I can prevent this?
     
  2. Hero101

    Hero101

    Joined:
    Jul 14, 2015
    Posts:
    158
  3. Hero101

    Hero101

    Joined:
    Jul 14, 2015
    Posts:
    158
    It is worth mentioning that sometimes when I jump it launches me way high up. I'm guessing it is jumping during one of these "bumps"

    *Edit* I actually have no idea why my character launches so high... I can be in an area without where the character is only touching one tile collider beneath him and it jump over and over (after touching the ground each time) and sometimes it jumps as it should and other times it launches me...

    Here is the updated script:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayerController : MonoBehaviour {
    5.  
    6.     public float speed;
    7.     public float jumpHeight;
    8.  
    9.     private Rigidbody2D rb;
    10.  
    11.     public Transform groundPoint;
    12.     public float radius;
    13.     public LayerMask groundMask;
    14.  
    15.     bool isGrounded;
    16.  
    17.     void Start ()
    18.     {
    19.         rb = GetComponent<Rigidbody2D>();
    20.     }
    21.        
    22.     void Update ()
    23.     {
    24.         isGrounded = Physics2D.OverlapCircle(groundPoint.position, radius, groundMask);
    25.  
    26.         if(Input.GetAxis("Jump") > 0 && isGrounded)
    27.         {
    28.                 rb.AddForce(new Vector2(0, jumpHeight));
    29.         }
    30.     }
    31.  
    32.     void FixedUpdate ()
    33.     {
    34.         float horizontalMovement = Input.GetAxis ("Horizontal");
    35.         rb.velocity = new Vector2 (horizontalMovement * speed, rb.velocity.y);
    36.     }
    37. }
    38.  
     
    Last edited: Jun 28, 2016
  4. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    179
    I have same issue with 3D box colliders and I haven't found solution to it apart from making one huge collider (like they are suggesting for 2D edge) or placing them smart so they are actually splitting where they need to be on different levels.
     
    Hero101 likes this.
  5. Hero101

    Hero101

    Joined:
    Jul 14, 2015
    Posts:
    158
    Thanks for the reply. That's a bummer. My game is really simple and the levels are really small so it would be simple enough to use large colliders where needed....I just wanted to learn "best practices" as I make this game. Alas, from all of my google searches over the last several hours it seems like a ton of people have had this issue. The threads I found were at least 1-3 years old so I just wanted to double check if a new solution/fix was implemented in Unity.

    Thanks again for the reply.
     
  6. listener

    listener

    Joined:
    Apr 2, 2012
    Posts:
    179
    No problem,

    I posted question under Physics question on this forum but no reply whatsoever. It looks like when moving rigid body comes to contact with seem between two colliders it reacts to it no matter if they are perfectly aligned. This can create problem if you have huge map with different features on it.

    Because my game is 3D it really hinders modular way of assembling map as it will with 2D for sure since you can't just have one collider per element and then assemble maps. I'm still hoping there is some elegant solution for this but so far nothing I have read gives me confidence.
     
    Hero101 likes this.
  7. Hero101

    Hero101

    Joined:
    Jul 14, 2015
    Posts:
    158
    Sad panda. Using edge colliders doesn't work either. Player still bumps at intersection of edge colliders. Looks like I really am going to have to go in and manually shape large box colliders to fit the terrain in my 2d platformer game. Hopefully a fix for this is going to happen one day...

    I checked out your website and you are light years ahead of me in programming skills haha So I wanted to ask you something: What about the possibility of using Raycasting to handle collision between the ground and the player? In theory couldn't you shorten the bottom of the rigidbody so it isn't touching the ground and then use a raycast to hold the player up so you can coast over the collider intersections?
     
  8. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    The 2D collision detection in Unity should be resolved in threes to prevent this, but it's not. What type of collider are you using on your player? I think you'll have to use a circle collider(or CapsuleCollider2D when Unity finally adds it..) on your objects bottom half or implement your own collision detection. *Note* You might have to lock the Z rotation so your character doesn't fall over.

    Alternatively use a single edge collider that wraps around your ground. You could generate it easily if you're storing your tiles in a grid or tree structure.

    @listener, I believe the related 3D issue can be fixed by lowering Physics.defaultContactOffset or directly in Edit > Project Settings > Physics.

    As for the jumping, you probably want to specify ForceMode2D.Impulse. The default is ForceMode2D.Force which is for applying force across multiple frames.
     
    Last edited: Jul 2, 2016
    Hero101 likes this.
  9. Hero101

    Hero101

    Joined:
    Jul 14, 2015
    Posts:
    158
    Thank you for the thorough response. I am actually using a circle collider. My character is rather round so he fits perfectly in one.

    I don't know how to use a single edge collider to wrap around my ground. When I add an edge collider it positions it at the center of my ground tile and I have to move it up to the top. I will have to do some research on how to do this and also look into storing my tiles in "a grid or tree structure." Thanks!

    Thanks for also addressing my jump problem! Was about to start a new thread to ask about it. I originally thought it was launching because of the intersections of the ground colliders but when I tested it on a single box collider it was still happening. Never knew about ForceMode2D.Impulse. I will give it a shot!

    Thanks again!
     
  10. GibTreaty

    GibTreaty

    Joined:
    Aug 25, 2010
    Posts:
    792
    Normally when I make my player controllers that use a rigidbody I use a raycast to check for the ground and position the player just above the ground. When the player is touching the ground, I also disable gravity for that rigidbody. That'll get rid of your current issue.

    Here's a player script I made http://pastebin.com/LxnRQJqa

    The important bit is right here
    Code (CSharp):
    1. void DetectGround() {
    2.                 RaycastHit2D hit = Physics2D.Raycast(groundRaycaster.position, -Vector2.up, raycastDistance);
    3.                 if(hit.collider) {
    4.                         if(Rigidbody2DComponent.velocity.y <= 0) {
    5.                                 Rigidbody2DComponent.gravityScale = 0;
    6.                                 Vector3 position = transform.position;
    7.                                 position.y = position.y - (feetLocationTransform.position.y - hit.point.y);
    8.                                 transform.position = position;
    9.                         }
    10.                         IsGrounded = true;
    11.                 }
    12.                 else {
    13.                         Rigidbody2DComponent.gravityScale = 1;
    14.                         IsGrounded = false;
    15.                 }
    16.         }
     
    Hero101 likes this.
  11. Hero101

    Hero101

    Joined:
    Jul 14, 2015
    Posts:
    158
    Duuuuude. You are awesome for showing code! I never considered disabling the gravity. I'm definitely going to give this a shot. Really don't want to have fiddle with shaping large colliders to avoid the whole player 'bump' issue if I can avoid it.
     
    GibTreaty likes this.
  12. Hero101

    Hero101

    Joined:
    Jul 14, 2015
    Posts:
    158
    Just looked at your script... I dream of the day I have as much skill in programming as you haha I still have so much to learn but I will get there eventually if I keep working at every day :)
     
  13. GibTreaty

    GibTreaty

    Joined:
    Aug 25, 2010
    Posts:
    792
    My advice is just to try new things, even if those things don't apply to your project(s). I've been learning new stuff all the time since I started coding in BlitzBasic in 2003ish (then C# in 2009). Looking at other peoples' code and looking up some more advanced techniques helps.
     
    Hero101 likes this.
  14. Hero101

    Hero101

    Joined:
    Jul 14, 2015
    Posts:
    158
    Thanks for the advice. I did ActionScript3 for 1-2 years trying to make games with Flash. Made the switch to Unity/C# a couple months ago. Luckily my knowledge in AS3 made the transition to C# not terribly difficult, but still have so much to learn. Will definitely be pushing my limits and trying to learn new things.

    Thanks again for all of your help I greatly appreciate it :)
     
    GibTreaty likes this.
  15. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    That is extremely strange... A circular collider shouldn't be having these issues.

    I personally use 3D colliders and rigidbodies in 2D games because there are fewer problems. Then again, I loathe 2d collision implementations that have no settings for the number of colliders that are resolved at once. Another option would be to implement your own 2D collision detection.

    I assume from this that you are manually placing each tiled sprite in your scene? You should instead create a "tile map editor" that will let you place tiles into a fixed grid. With the grid, you can iterate over filled tiles and create your edge colliders on the outside edges where there are no neighboring filled tiles (similar to voxel mesh generation).

    This will most likely only fix the problem on horizontal ground. If you were to jump up while holding forward into a tiled wall, it will cause the same issue.
     
    Hero101 likes this.
  16. Hero101

    Hero101

    Joined:
    Jul 14, 2015
    Posts:
    158
    Thanks for the link to the tile mapper. I was looking at similar products in the Asset Store but the one you linked is free so I have to check it out :)
     
  17. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    They are very easy to code and there is probably a couple billion tutorials on how to do it on google.
     
  18. nicolas_mg

    nicolas_mg

    Joined:
    Nov 17, 2019
    Posts:
    1
    Now I know this thread is old, but just in case someone is having the same problem nowadays.

    For the bouncing when the character moves along the ground there is this fix, that maybe wasn't implemented in Unity at that time, but here it is:

    After adding to your tiles the Tilemap Collider 2D, you should check the "Used by Composite" box. Then you add a new collider called Composite Collider 2D. This will automatically create a Rigidbody 2D needed to use the Composite Collider. To avoid unnecessary work for Unity just change the RB body type from Dynamic to Static, since the ground won't be moving anyway.

    This will make a single, and more efficient collider that covers your whole tileset and adapts automatically to any changes you make to it.
     
  19. Hero101

    Hero101

    Joined:
    Jul 14, 2015
    Posts:
    158
    That definitely did exist back then haha But I do appreciate the response. I haven't worked with tiles since this game, but figured I would make another game with them eventually. Your response will come in handy then :)
     
  20. Kuutioo

    Kuutioo

    Joined:
    Aug 3, 2020
    Posts:
    1
    This solved the problem for me, but after I did this my player characters' movement became a bit "jittery", so I added a physics material to my players Rigidbody2D component that has 0 Friction and 0 Bounciness
     
  21. Nackley

    Nackley

    Joined:
    Aug 14, 2022
    Posts:
    5

    I love you........ thank you for this.
     
  22. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,365
    Good to be appreciative but I would ask that you please consider using the "Like" button instead of necroing posts.

    Thanks.