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

BoxCollider2D colliding with EdgeCollider2D

Discussion in '2D' started by hektac, Jan 17, 2014.

  1. hektac

    hektac

    Joined:
    Nov 9, 2012
    Posts:
    28
    Has anyone else run into the situation where the BoxCollider2D will get stuck when colliding with EdgeCollider2D?

    Example:

    I have a BoxCollider2D and Rigidbody2D on my player, my world is built out of tiled sprites with EdgeCollider2D's attached. When I jump against a wall, the player will get stuck until I release the keys, same if I try to jump up a tiled staircase.

    This is really irritating. I have tried using a CircleCollider2D, Polygon2D, and the double collider method from the tutorial. I have also tried adding frictionless materials to both the player and the tiles but no success. If this isn't what I should be using for a platformer, can someone point me in the right direction?
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,333
    If I understand you correctly then colliders will collide with the "ends" of the edge collider. You need to use a single edge collider to produce the surfaces of your platforms even though they are made up of tiles. Don't just use single edge colliders to produce a single edge on each tile.

    iforce2d explains "Ghost vertices" very well.

    Hope that helps.
     
    luiggialarcon14 likes this.
  3. Dosetsu

    Dosetsu

    Joined:
    Dec 22, 2011
    Posts:
    39
    This doesn't really help if you have a procedural level generation at runtime. If you need to be able to create you level out of tiles or pieces you'll run up against this problem. You can't always just replace everything with a giant collider.
     
  4. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,539
    It does. Make your tile prefabs out of a few EdgeCollider2D instead of BoxCollider2D.
    Also make sure it's not an issue of your Raycast's thinking you're grounded due to not using Layermasks.

    The issue of getting stuck on walls was happening to me when I used BoxCollider2D on the ground/wall tiles and Player, but after changing my tiles to multiple edge colliders, everything works perfect.
     
  5. Dosetsu

    Dosetsu

    Joined:
    Dec 22, 2011
    Posts:
    39
    Got it working with the edge collider!

    They key for me was giving it a frictionless material. Now it runs nice and smoothly with no unexpected bounces. Now I can tile my prefabs as needed. Thanks!
     
  6. GeekyTime

    GeekyTime

    Joined:
    Aug 29, 2014
    Posts:
    2
    I'm having the same issue that Dosetsu had, where I am trying to dynamically chunk together levels from prefabs.

    I've tried using several combinations of edge and circle colliders for my player and my tiles, but my player is still bouncing like crazy no matter what kind of colliders I use. (I've tried circle/box, circle/edge, and edge/edge.)

    I have also tried using a frictionless material, and adjusting the physics settings for min penetration, etc. Still bouncing away.

    Is anyone else experiencing this with the latest version of Unity? Perhaps there were changes to the 2D physics engine?
     
  7. kamalkumar murari

    kamalkumar murari

    Joined:
    Jun 23, 2015
    Posts:
    1
    am using edge collider 2d when the balls are falling it will be struck on the edges ..can any one help me...
     

    Attached Files:

  8. Industrion

    Industrion

    Joined:
    Nov 21, 2013
    Posts:
    41
    I'm having this similar problem. Does anyone know if the correct/only real solution to this is to treat the adjacent blue and green Edge colliders as a single PolygonCollider?

    Thanks
     

    Attached Files:

  9. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,333
    You should use a single EdgeCollider2D as that provides a continuous surface. Simply placing separate colliders together won't work. Even a PolygonCollider2D won't produce a single continuous surface because it isn't a primitive collider, it's just an outline that has been decomposed into multiple convex colliders.
     
  10. Industrion

    Industrion

    Joined:
    Nov 21, 2013
    Posts:
    41
    Thanks! I forgot that I'd initially decided I didn't want to use the multiple edges of each edge collider as I'm using resizable rectangles to create collidable areas (in a runtime editor), and I opted for check boxes for which sides of the rectangle are used (so I can create a long pipe piece with just top and bottom edges active), but I can understand how this works, and I'll try to adjust what I've got.
     
  11. Industrion

    Industrion

    Joined:
    Nov 21, 2013
    Posts:
    41
    I'm still getting collision with the edges of a 3-sided edge shape (kinda C-shaped, made out of 4 points), when I fall down past it I can actually land on the bottom even though I'm falling along the side (not the side with the opening). D'you know if the order of the vertices is strict, having to be clockwise or counter clockwise?
     
  12. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,333
    If it's a single EdgeCollider2D then you should not catch vertices (apart from the ends). Can you zip-up a super simple repro project and post it here? If so, I can take a quick look at it for you.
     
  13. Industrion

    Industrion

    Joined:
    Nov 21, 2013
    Posts:
    41
    Thanks - it might not be easy to do that because I have a runtime level editor which complicates a lot for sending a simple project over without all my source code. But the scene in action is very simple, which is why this is quite baffling. It's 3 or 4 edge colliders and a box collider with a rigidbody. I've taken another screenshot (not a diagram drawn in Flash this time!) and a screenshot of the inspector window for an edge collider that's behaving this way, so you can see the values. Hopefully that'll help a bit.

    There's code for applying these edge collider points, but it's wired into a couple of ease-of-use things that attempt to automatically decide what the edge collider's points should be: I'm allowing the resizing of rotatable rectangles in my editor, and toggling the use of edge colliders on each side of the rectangle. I'm careful, though, about how edge colliders are then made up on such a rectangle. For example, if left-bottom-right is enabled on the rectangle, then it's one edge collider that wraps round three sides, but if it's a top-and-bottom rectangle being placed, it's two separate edge colliders. Ignore that for now, though - like I said, the bug is taking place with one single rectangle-forming edge collider, the player starts on top of it and attempts to jump down one side of it and gets stuck on the floor even though the player should be outside its 'box' entirely.

    So for a rectangle that needs all 4 sides as an edge collider, this happens:

    edgeCollider1.points = new Vector2[] { bottomLeft, bottomRight, topRight, topLeft, bottomLeft };
    edgeCollider2.enabled = false;

    EXAMPLE:
    Vector2 topLeft { get { return new Vector2(visualBounds.x, visualBounds.y + visualBounds.height); } }

    The second edge collider used for top-and-bottom-only and left-and-right-only rectangles is turned off, and shortcut accessors for the corner points of the visual rectangle are used to create the list of points.

    I imagine all of this shouldn't matter too much though (it probably sounds all too complex at the moment for what you're seeing on screen). I imagine it's what the inspector shows that's what matters, and that the green gizmo showing the rectangle as I know it should be. Here are some screenshots:
    screenshot.PNG Screenshot2.PNG

    Edit: Note that the inspector being shown is for the edge collider the player's colliding with in the other screenshot. Also, it has scale values set - not sure if that can affect the collision. Also, the player is using Continuous collision detection, and I'll attach my Physics2D settings:

    screenshot3.PNG

    Thanks again.
     
    Last edited: Dec 14, 2015
  14. Industrion

    Industrion

    Joined:
    Nov 21, 2013
    Posts:
    41
    Any ideas?
     
  15. Industrion

    Industrion

    Joined:
    Nov 21, 2013
    Posts:
    41
    I found that increasing the Min Penetration For Penalty seems to prevent this glitch. I did want to reduce the value to allow my rigidbodies to line up more flush with surfaces, but since I can imagine that's directly related to the error, I'll just find a happy medium by tweaking the value. If anybody knows whether this sounds like the expected effect of a reduced Min Penetration value, please say!
     
  16. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,333
    The min-penetration value is there as a buffer for polygon collision. Reducing it means that there is less room and can cause problems (as the doco states).

    The gap produced by this is extremely small (5mm), The idea is that your game should be scaled so that 5mm is visually insignificant. As an alternative, ensure that the collider is slightly smaller than the visuals.
     
  17. Industrion

    Industrion

    Joined:
    Nov 21, 2013
    Posts:
    41
    Thanks, I forgot that I hadn't adjusted the scale yet - it almost certainly should be larger.
     
  18. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,333
    No problem at all.
     
  19. Industrion

    Industrion

    Joined:
    Nov 21, 2013
    Posts:
    41
    I'm still suffering with this issue - the problem I have is that, while I'm happy to algorithmically calculate the entire inner edge of all accessible game area, this solution fails when I have moving platforms or platforms that turn on and off (and I want to support both). If I'm correct, to solve this I'd need to repeatedly check for where edges come into contact and break contact with others, and split the geometry at those points to open and close this entire inner polygon.

    example.jpg

    If the blue line is the usual whole-map inner polygon (usually a fine solution to the problem), the trouble I'm having is what happens to the area I've marked with the red line. Obviously the purple line - a collider individual to the moving platform - has to exist, and the portion it's bumping into has to exist, but if they don't form one continuous line while they're at rest at one side of the drop, the issue presents itself again - when walking onto the platform, you can bump up slightly if you're using the circular-player-feet workaround, or you'll get stuck fast if you're completely rectangular.

    I used to use a workaround for this in Box2d, in its PreSolve callback. I'd check whether the edge being hit by the player (or any other active character for that matter) is surrounded by other geometry, and then make a call on whether to do contact.SetEnabled(false), to scrap the collision entirely. This worked (although it presented a restriction for me on other types of environment surface that I was willing to give up on because solving this was more important). However, Unity doesn't allow this PreSolve step - see here:

    https://feedback.unity3d.com/suggestions/add-presolve-slash-postsolve-for-physics2d-of-unity-4-dot-3

    I looked at the effectors as a way of solving this problem but while they're pretty useful, none of them seem to do the trick. I hope I'm wrong though!
     
  20. Industrion

    Industrion

    Joined:
    Nov 21, 2013
    Posts:
    41
    I thought I had a solution by manually applying gravity, and only applying it when - even at an AABB-based pixel level - I know the player shape's underside is in contact with what I consider to be a floor object.

    This approach is already very sound for me in determining whether the player can jump (I prefer it to looking for the presence of bodies in a contact list).

    I reworked this 'is-surfaced' check to take place for all 4 sides of the player, and use the direction velocity vector of the player to know exactly when the player is moving into an object, either via gravity or even via some game hazard or plaything, for example a wind machine that pushes the player continually downward onto ground, or forces the player against the wall at speed as the player attempts to jump straight up.

    By the looks of my logging of player velocity, this makes it look as though the player should never be pushed into the ground at points where box-shaped separate colliders meet.

    This appeared to work for long enough (a couple of minutes spent jumping and moving around, with restarts), and I thought it had worked, but it now appears to be manifesting the old ghost collisions again.

    This makes me think that the issue isn't really to do with being forced beyond the very edges of these inner edges of side-by-side box colliders, and that it will happen even without the Y-axis (if gravity and the concept of ground level is downward) playing a part. In other words, I could create a game in which the player starts above, but flush with, a set of ground shapes side-by-side, and never move the Y-velocity away from 0, and there'd still be these collisions.
     
  21. awesomedata

    awesomedata

    Joined:
    Oct 8, 2014
    Posts:
    1,419
    I agree. I am having a very similar problem with a slope edge collider against a box-collider. It's off by about .02 units on a flat surface. I'm using a box collider player and a single edge collider 2d platform. Nothing more fancy than that. The box is simply not appearing flush on the platform, no matter the scale.
     
  22. Industrion

    Industrion

    Joined:
    Nov 21, 2013
    Posts:
    41
    I'm still no further forward with this. Is there any way to implement PreSolve and PostSolve (like Box2D's contact listener) with Unity's 2d physics?
     
  23. Industrion

    Industrion

    Joined:
    Nov 21, 2013
    Posts:
    41
    I've been experimenting with a port of Box2D to see whether I can find a reasonable workaround for this, using its PreSolve step.

    I was able to use the contact points given in the collision manifold to decide whether the contact could be ignored. This seemed to work, but it would kick in only after an initial single PreSolve step, where this information wasn't yet available. I think this will be the simplified initial AABB collision check, which I think is still going on to act on the behaviour of the dynamic body (the player), and I can't use its information nearly as effectively, so I've ended up with what looks like a solution good enough for me, but I can't get round this initial frame.

    I still can't understand how using a circular or semi-rounded polygonal player body is sufficient with any sort of high-speed movement. Quite regularly, I see the body be chipped upwards because, while it's prevented an absolute stop-in-place, a collision has still taken place. I'm talking about game speed similar to Super Meat Boy - fairly fast movement, fairly low gravity, but nothing that is physics-defying.

    Imagine a tile-based environment where the player (a circle) is travelling along a tunnel that is essentially one tile high (the player isn't quite as large as a whole environment tile), and there are spikes above the player preventing it from jumping. If the circle stutters on one of these floor tile boundaries and gets launched up, the player is dead.

    I even considered trying suspension on the player - a ball floor body that can dampen these jumps. But I don't trust that it's going to completely remove the issue, and I want to be able to switch gravity, so even if I'm doing this only in the Y axis, I need this suspension mechanism on top and bottom, and obviously on left and right if I'm switching gravity to be horizontal too.

    Please let me know your thoughts.