Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Rigidbody getting stuck on tiled wall

Discussion in '2D' started by TaewYn, Jan 4, 2014.

  1. TaewYn

    TaewYn

    Joined:
    Jan 30, 2013
    Posts:
    19
    Hello, I'm currently having issues with this, not sure how to solve it:

    Setup:
    Top down, tiled
    Character with 2D box collider+ rigidbody, moved by changing velocity(works fine).
    Walls are made of tiles with 2D box colliders, everything has 1x1 unit size so there definitely is no gap between the wall tiles.

    The problem:
    Every now and then when moving the character along the wall he gets stuck on it.
    I can get him unstuck by turning the direction he is facing (scale*-1) without changing the movement direction.
    Anyone got any hints on what could be causing this ?
     
  2. dilmerval

    dilmerval

    Joined:
    Jun 15, 2013
    Posts:
    232
    hi yes the same thing happened to me.

    Just assign a Physics material to your wall and that should fix it.

    Dilmer
     
    wlwl2, jcameron47 and rsodre like this.
  3. TaewYn

    TaewYn

    Joined:
    Jan 30, 2013
    Posts:
    19
    Hm.. thanks for the tip. That doesn't seem to fix it for me though, also tried playing around with the Friction and Bounciness values but he always ends up getting stuck.

    If I change the collider to a circle collider the problem goes away, but then my character starts slowing down when running diagonally against the wall even though there is no friction. (probably the forces getting calculated differently)
    Also the circle collider isn't the ideal shape for what I'm doing.
    I might try combining circle and box colliders.

    If anyone has another way to solve this I'd appreciate it.
     
  4. dilmerval

    dilmerval

    Joined:
    Jun 15, 2013
    Posts:
    232
  5. Scorr

    Scorr

    Joined:
    Jul 2, 2013
    Posts:
    73
    I think it's a problem with the 2d box colliders. When using tiles as floor the character occasionally bumps up, even when the colliders are all evenly lined up without seams and even with a circle collider. This only seems to happen when you have many colliders placed next to eachother.

    As temporary fix I'm using a single box collider stretched out over all my tiles, but this wouldn't be a good idea if you have an in-game level creator.
     
  6. unitylover

    unitylover

    Joined:
    Jul 6, 2013
    Posts:
    346
    Its definitely an issue for people building tile based levels with box colliders. Im not Sure what happened between 4.3 and 4.3.1 but I swear dilmers suggestion worked on tiles at one point.
     
  7. TaewYn

    TaewYn

    Joined:
    Jan 30, 2013
    Posts:
    19
    Yeah I would have done that too but since I'm generating levels at run time it's sadly not an option I think .
     
    FireJojoBoy likes this.
  8. dasbin

    dasbin

    Joined:
    Jan 14, 2012
    Posts:
    261
    I actually have this problem even with a circle collider against a frictionless wall. The wall is not tiled, but it a Polygon Collider. The sticking points are the vertices between tris.

    The work-around for me was that I constantly animate the radius of the circle collider between 1 and 1.1 . This slow pulse/movement seems to prevent any sticking and is essentially unnoticeable. I suspect it's not great for performance though.
     
    Last edited: Jan 6, 2014
  9. huulong

    huulong

    Joined:
    Jul 1, 2013
    Posts:
    224
    Thanks, the Physics Material worked for me.

    I am working with Toolkit2D combined with Unity 2D Physics.
    Part of my walls are actually tiles generated with Toolkit2D TileMap. Others are Toolkit2D sprites with 2D box colliders (Tk2D lets you set appropriate colliders in the Sprite Collection Editor and automatically adds them the sprite objects).
    By using a custom Physics 2D Material with Friction = 0 and Bounciness = 0, the friction effect disappears. Using the default value of 0.4 for Friction gives the same result as using None Material (the default physics 2D material), i.e. a slowdown when moving diagonally (not when grazing the walls).

    To apply the change to the whole TileMap of Tk2D, you have to go the settings and change the physics material used for the layer you want, then commit. I guess there are similar global parameters for other TileMap systems.

    For those who still have issues with friction with the custom material, check your move algorithm. If you are normalizing speed for diagonal directions, moving diagonally against a wall makes your character move sqrt(2) slower in the projected cardinal direction. However, a friction of 0.4 makes it move considerably slower, so if your character is really slow it is not because of speed normalization (I though that at first, then disabled normalization and could still see the issue).

    If Unity 2D Physics tuning alone is not enough to solve the issue, you may need to refine your move controllers, which may be more or less complicated depending on your game. You could, for instance, make your character detect walls beforehand and only move in "free" directions.

    Hope that helps someone.
     
    DaStickman and Antonio_Ketch like this.
  10. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,539
    Just to save you guys some trouble, if you use Edge colliders instead, it gets rid of the issue. Just make 4 empty-game-objects a child of your tile, each with an EdgeCollider2D, and 2 of them rotated to form the walls. This way you'll also be able to tag the walls as walls, floors as floors and ceilings as ceilings... And you won't run into the ghost vertices problem that causes you to get stuck as well.

    Edge-Colliders also allow you to alter their shape and add more points, by holding down Shift and click+dragging anywhere along the edge.

    2022 Edit: Tilemap package exists now which is generally a better option. You can use a "Composite Collider 2D" which will merge all your tile box colliders into one continuous collider that doesn't have "ghost vertices", but also retaining the benefit of a box collider which will push objects out from inside of it, unlike an edge-collider which has no "volume".

    If your game can't really be tile-based, then the edge-collider is still the best option.
     
    Last edited: Mar 29, 2023
  11. Kytin

    Kytin

    Joined:
    Dec 4, 2013
    Posts:
    22
    Alternatively, you could use an edge collider for your character instead of the terrain tiles. That's what I did. I added some extra vertices and shaped into a box so that it would still give the all-around collision I wanted. (I also tried using a polygon collider, but for some reason it got stuck just as much as the box collider had)
     
    Dustrunner, sandygk and customphase like this.
  12. Deleted User

    Deleted User

    Guest

    Yeah, I was having this problem and putting the edge collider on the character worked like a charm.
     
  13. griden

    griden

    Joined:
    Apr 8, 2013
    Posts:
    33
    I'd try applying force to the rigidbody instead of directly changing the velocity. 2D physics engines tend to get "confused" if you do that. Also, make sure to not move bodies (by applying forces or modifying velocity) in the Update(). That should be done in FixedUpdate() if you need to use continuous force.

    If the rigidbody is moving very fast, you may need to use Continuous Collision Detection, but that's for extreme cases.
     
  14. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,539
    Nah, it's an issue with Box2D and some other engines. Edge colliders are the solution.
    http://www.iforce2d.net/b2dtut/ghost-vertices
     
    ow3n, reinfeldx and sandygk like this.
  15. Eklavyaa

    Eklavyaa

    Joined:
    May 4, 2014
    Posts:
    20
    Ran into same issue, where two box colliders with rigidbody were getting stuck into each other ! on one rigidbody I just surrounded it by edge collider instead of Box Collider ! Voila !! Problem solved :)
     
    abogilovic likes this.
  16. DarkNeo

    DarkNeo

    Joined:
    Apr 27, 2014
    Posts:
    53
    Physics Material Worked perfect for me! Thank you :)
     
  17. ajdrew81

    ajdrew81

    Joined:
    Mar 9, 2015
    Posts:
    11
    Thanks! This worked great.
     
  18. reinfeldx

    reinfeldx

    Joined:
    Nov 23, 2013
    Posts:
    164
    The edge collider fix here is working well for me so far!
     
  19. enhawk

    enhawk

    Joined:
    Aug 22, 2013
    Posts:
    833
    The problem with Edge Colliders is that physics overlap can't see them. If you are using Physics Overlap for grounded calculations your player wiil never be grounded.

    Running a box collider over other box colliders stacked together seems to make the box get stuck. (this is particularly annoying with tile based 2D games)

    The technique for using a circle collider for feet and a box collider for head works until you want 1-way platforms or ladders. Then one of the colliders will get stuck.

    In any case, if you want boxes / crates etc, giving them circle colliders makes them slide about with bad friction (even with friction ramped up to the max).

    Not sure of a work around, Unity would have to change the way Box2D works. But if we are to make 2D platformers in Unity, there should be some fix in the works as they will come accross the same issues too.

    A 2D character controller by @MelvMay is in the works but no date on it's arrival. It's a lozenge shaped collider like the 3D character controller. This seems to fix the issue for players or enemies but as highlighted above, the box collider on moving crates would still get stuck in tiles, also it's not part of Unity just yet.
     
    Last edited: Jan 15, 2016
  20. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    The CapsuleCollider2D isn't a character controller and it won't solve the issue of catching corners on discontinuous collider surfaces, it's prone to catching corners just like any other collider.

    I am however working on a solution that allows you to group and therefore merge colliders together but this is a WIP.

    I created IsTouching and IsTouchingLayers to detect if you are currently touching other colliders and in a lot of cases this can be used for an 'Is grounded' check. It's also super fast as it only checks existing contacts and doesn't perform any intersection tests. It also isn't just an approximation of whether you're touching something, it's actually accurate and real contacts and not some offset overlap.
     
  21. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,732
    I like the sound of this!
     
  22. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    You can find the API references here.
     
  23. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,732
    Thanks @MelvMay, I didn't realise they were available.
     
  24. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    No problem. The only downside to using these is that you can't check for contacts 'underneath' a character so if side-walls are counted as 'ground' and the collider is touching them then you can't distinguish unless you do further calculations.

    On the upside, there's a new 'GetContacts' API that'll eventually land that will allow you to retrieve all current contacts for a Collider2D or Rigidbody2D which should help. Unfortunately that has been delayed pending some other core framework changes.
     
  25. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,732
    I hadn't even considered that a problem actually. I have just been playing around with it and to differentiate between wall collisions and ground collisions I was just using different layers and it was working how I wanted, although I can see how a GetContacts function would be useful.
     
  26. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    To distinguish you could always have a wall layer and a ground layer, assuming the wall can never be ground.
     
  27. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,732
    Yep, that's exactly what I did, worked a treat :)
     
    MelvMay likes this.
  28. ClearRoseOfWar

    ClearRoseOfWar

    Joined:
    Sep 6, 2015
    Posts:
    89
    Physics Material worked perfect, thank you :)
     
  29. enhawk

    enhawk

    Joined:
    Aug 22, 2013
    Posts:
    833
    I ran in to the this problem again, adding an edge collider to the very base of of objects, while keeping the box collider and editing it's size just a fraction so it is raised from the base, seems to work very well for non kinematic moving rigidbodies moving by force over tiled surfaces.
     
    Snory likes this.
  30. reinfeldx

    reinfeldx

    Joined:
    Nov 23, 2013
    Posts:
    164
    Just wanted to chime in here and say I'm still having problems with box colliders getting stuck while sliding around on tiled environments. All the colliders have friction set to zero—I see that this has worked for some people, but in my case I've got the gravity turned up on my game and this fix doesn't help (-50 gravity).

    I just thought of the same solution that @hawken mentioned; about to try that.
     
    enhawk likes this.
  31. tarabout

    tarabout

    Joined:
    Jan 23, 2016
    Posts:
    11
    That sounds awesome, any possible ETA or other infos about this feature?
     
  32. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    The feature is being worked on now but I can't give you an ETA. It'll most likely be seen in a preview release.
     
  33. tidyui

    tidyui

    Joined:
    Mar 13, 2016
    Posts:
    8
    Just out of curiosity @MelvMay, when you say merging colliders are we talking about constructing a new collider at runtime (or editor) from several existing colliders. I'm currently working on a tiled based game and is looking to optimize colliders before adding a path finder, but if this kind of feature is coming out of the box I might just wait instead of writing a lot of custom code for it :)
     
  34. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    It is merging colliders but not into a new collider though. It's definitely suited to tile-based scenarios. Because of its WIP status, I certainly don't think you should wait.
     
    tidyui likes this.
  35. Simeon

    Simeon

    Joined:
    Sep 26, 2012
    Posts:
    50
    I've had the same Issues and I tried adding the force needed to push the colliding objects apart. This can be done just by adding the Impulse force in Collision.impulse in the OnCollisionStay method. Like so:

    Code (CSharp):
    1. void OnCollisionStay(Collision collision)
    2.     {
    3.         bool isGround = false;
    4.         foreach (ContactPoint contactPoint in collision.contacts)
    5.         {
    6.             if (Vector3.Angle(Vector3.up, contactPoint.normal) < maxSlopeAngle)
    7.             {
    8.                 isGround = true;
    9.                 grounded = true;
    10.                 maxVelocityChangeSmooth = maxVelocityChange;
    11.             }
    12.         }
    13.  
    14.         if (!isGround)
    15.         {
    16.             Debug.Log(collision.impulse);
    17.             rigidBody.AddForce(collision.impulse, ForceMode.Impulse);
    18.         }
    19.     }
     
    Ado4007 likes this.
  36. josephquested

    josephquested

    Joined:
    Oct 21, 2015
    Posts:
    5
    The best solution I've found is a variant on the advice in this article. http://www.iforce2d.net/b2dtut/ghost-vertices
    The trick seems to be colliders with rounded edges, so a circle or capsule. But, if you have a cube character like I do, just using a CapsuleCollider isn't going to be enough. So, my character has a BoxCollider "skin", which ends slightly above the base of the transform. Then, a CapsuleCollider centre, which is the collider that actually touches the ground.

    Screen Shot 2016-04-25 at 8.13.18 AM.png
     
  37. alpbyte

    alpbyte

    Joined:
    Jun 15, 2016
    Posts:
    2
    Has anybody any news regarding the feature for merging colliders?
    I am not sure if i should wait or just try to implement a workaround.
     
  38. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    There's no news on the CompositeCollider2D but it'll certainly be in the next experimental preview for 2D as it'll be used by the TileMapCollider2D. No dates to give. Obviously this only applies to 2D physics, not 3D physics.
     
  39. alpbyte

    alpbyte

    Joined:
    Jun 15, 2016
    Posts:
    2
    Ok thank you, looking forward to it ;)
     
  40. Vinvirinvi

    Vinvirinvi

    Joined:
    May 11, 2017
    Posts:
    1
    I ran into this problem - character with a box collider getting stuck in wall tiles (with Tilemap Collider 2D). The solution I found is to set up edge radius of the box collider on character, just 0.001 worked fine - I got rid of getting stuck issue and the gap between colliding objects remained invisible.
     
    Last edited: Nov 29, 2017
  41. albertvasconcellos

    albertvasconcellos

    Joined:
    Feb 18, 2016
    Posts:
    5
    This worked perfectly for me, all I had to do was go to the settings of my Box Collider2D and change the edge radius to 0.001 and my character didn't get stuck anymore. Thanks!
     
  42. Verdusk

    Verdusk

    Joined:
    Apr 13, 2017
    Posts:
    1
    I've tried the edge radius solution, which appears to mostly solve the problem - however sometimes the character would "bump" in between the tiles, for example when you're falling you can bump to the wall and sort of slow down the fall speed instead of sliding down smoothly. It's a good fix for something so easily done, but doesn't perfectly solve the problem.

    I've managed to revise a solution of that is the opposite: complex, something of a chore to implement, but works perfectly. Basically a workaround that combines the hitboxes of adjacent tiles, I loop through all the tiles in the Tilemap (that would only include wall/obstacle tiles), and create [prefab objects that contain] edge colliders on the outline of adjacent tile chunks, so that there's no in between hitboxes.

    upload_2019-3-28_17-50-4.png
    (For each wall tile, check adjacent tiles for blank/no wall tiles, where you would have to draw lines)

    The result is very clean and smooth in performance. You'll have to iterate through each tile, but unless there are something like a hundred million of them, it probably won't even cause significant delay during this collider-building.
     
  43. ilyasofficial1617

    ilyasofficial1617

    Joined:
    Oct 24, 2018
    Posts:
    1
    I have a fix for this problem, by combining TilemapCollider2D + CompositeCollider2D

    1. add TilemapCollider2D to the tile layer's component
    2. check "used by composite" field in TilemapCollider2D
    3. set Rigidbody2D to static

    Capture.PNG

    this will combine adjacent collider to be one huge collider
     
    Last edited: Aug 22, 2019
  44. unity_b1W6Nl1D_xYz8A

    unity_b1W6Nl1D_xYz8A

    Joined:
    Aug 5, 2019
    Posts:
    11
    I tried all suggested fixes posted here, but unfortunately none completely removed the bug for us.
    We have a 2D runner game where the tiles (structures) get generated.
    Even though @ilyasofficial1617 fix created one collider without seam for us, the player still got stuck on some structures, essentially walking continuously against the wall without falling down.

    While our fix might only work for some of your games it definitely helped us.

    Code (CSharp):
    1.     public class PlatformCollisionPatch : MonoBehaviour
    2.     {
    3.         public bool patchIsActive = true;
    4.  
    5.         private Rigidbody2D body;
    6.         private CharacterController2D character;
    7.  
    8.  
    9.         void Start()
    10.         {
    11.             body = GetComponent<Rigidbody2D>();
    12.             character = GetComponent<CharacterController2D>();
    13.         }
    14.  
    15.         void LateUpdate()
    16.         {
    17.             if (patchIsActive)
    18.             {
    19.                 if (transform.hasChanged)
    20.                 {
    21.                     transform.hasChanged = false;
    22.                 }
    23.                 else if (body.velocity.magnitude == 0 && !character.GetGroundedStatus())
    24.                 {
    25.                     body.AddForce(Vector2.down);
    26.                 }
    27.             }
    28.         }
    29.     }
    We just simply apply a downward force, if the player is in the air (not grounded) and the position has not changed since the last frame.

    Hope this helps somebody.
     
  45. Brandaboss

    Brandaboss

    Joined:
    Jul 9, 2018
    Posts:
    1
    I have tried every single solution suggested here, but not a single one worked. After trying this I didn't think it worked either. However, when I changed the geometry type in the composite collider to polygons, it worked perfectly. I also had a friction-less material on the tiles so I don't know if that played a role, but this solution worked great.
     
    Andrew-Park likes this.
  46. ka20nave1234

    ka20nave1234

    Joined:
    May 31, 2020
    Posts:
    1
    I set the bounciness of the material of my player to something really small like 0.01 and the friction to 0. It's a really subtle effect so its pretty much unnoticeable and it is really smooth.
     
  47. christianlong99

    christianlong99

    Joined:
    Aug 20, 2018
    Posts:
    3
    This is what I did, but it didn't work until I set the "edge radius" to a value greater than zero. That gave it boxes with circles between, instead of just being 2D lines.
     
  48. unity_gd3I5NJvhKz8CA

    unity_gd3I5NJvhKz8CA

    Joined:
    May 21, 2019
    Posts:
    1
    Holy!!! thanks man!
    I was looking for some solution and started to experiment with edge, but then I just left it.
    I guess you just saved me a lot of troubles and time
     
  49. HuldaGnodima

    HuldaGnodima

    Joined:
    Oct 10, 2016
    Posts:
    110
    Thank you for this. I had used capsule collider 2D and it didn't make my character "stuck" on the tiles, rather it randomly caused it to do very small y-directional bounces.
    Changed the capsule collider 2D to an edge collider 2D and no more bounces! What a nice and simple fix :) thanks

    Edit: If you're using a "single line" edge-collider 2d I recommend making it perfectly straight (you can edit edge-collider points by pressing "Points" and set the Y-coords to be the exact same)! I got strange bugs when it was just a tiny bit crooked.
     
    Last edited: Mar 28, 2021