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 ?
hi yes the same thing happened to me. Just assign a Physics material to your wall and that should fix it. Dilmer
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.
I setup my character just like is shown in this video: http://unity3d.com/learn/tutorials/modules/beginner/2d/2d-controllers The speaker does use two colliders for the character and that's what I did with my character. Good luck Dilmer
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.
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.
Yeah I would have done that too but since I'm generating levels at run time it's sadly not an option I think .
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.
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.
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.
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)
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.
Nah, it's an issue with Box2D and some other engines. Edge colliders are the solution. http://www.iforce2d.net/b2dtut/ghost-vertices
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
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.
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.
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.
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.
To distinguish you could always have a wall layer and a ground layer, assuming the wall can never be ground.
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.
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.
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.
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
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.
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): void OnCollisionStay(Collision collision) { bool isGround = false; foreach (ContactPoint contactPoint in collision.contacts) { if (Vector3.Angle(Vector3.up, contactPoint.normal) < maxSlopeAngle) { isGround = true; grounded = true; maxVelocityChangeSmooth = maxVelocityChange; } } if (!isGround) { Debug.Log(collision.impulse); rigidBody.AddForce(collision.impulse, ForceMode.Impulse); } }
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.
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.
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.
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.
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!
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. (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.
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 this will combine adjacent collider to be one huge collider
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): public class PlatformCollisionPatch : MonoBehaviour { public bool patchIsActive = true; private Rigidbody2D body; private CharacterController2D character; void Start() { body = GetComponent<Rigidbody2D>(); character = GetComponent<CharacterController2D>(); } void LateUpdate() { if (patchIsActive) { if (transform.hasChanged) { transform.hasChanged = false; } else if (body.velocity.magnitude == 0 && !character.GetGroundedStatus()) { body.AddForce(Vector2.down); } } } } 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.
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.
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.
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.
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
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.