Search Unity

Replacing BoxCollider2D with four EdgeCollider2Ds

Discussion in '2D' started by MoonJellyGames, Oct 31, 2014.

  1. MoonJellyGames

    MoonJellyGames

    Joined:
    Oct 2, 2014
    Posts:
    331
    Anyone who has tried making a tile-based game in Unity has probably encountered this issue, and I've seen many posts with people puzzling over why their player's box collider is getting snagged on the environment.

    The answer to this problem is nicely explained here: http://www.iforce2d.net/b2dtut/ghost-vertices

    I don't know how to implement the solution they offer in the above tutorial, as they are using the Box2D physics engine, so I came up with my own solution. It's clumsy and tedious, and there's probably more reasons why it's just plain bad, but on a basic level, it works:

    I use a script that I found online to make objects snap to a grid which I apply to my individual tiles. Once my tiles are in place, I create an empty game object and put all of the tiles into it, just to keep each wall/floor/ceiling segment together. Then, I create another game object with a box collider that is big enough to cover all of the tiles in the segment. I apply the SnapToGrid script to the box collider, move it in place (over the tiles), and then put the collider into the WallSegment/FloorSegment/CeilingSegment game object-- again, to keep the related level pieces together. The SnapToGrid script causes crazy collision problems with my player, so I remove it from all of my tiles and colliders.

    Pretty ridiculous, right? I know that you can purchase tools to make tilemaps in Unity, but I still feel like I'm at a skill level where I'd rather focus on doing what I can with the tools included in the free version of Unity. So, I'm willing to deal with the tedium as long as it works.

    Here's where it falls apart though: My player characters, which are almost square, need to be able to walk over each other smoothly. Here's a screen-cap to explain what I mean:



    The red player is currently controllable (selected = true) while the blue and yellow players are not. As you can see, the box colliders on my !selected players are a little too big-- the sprites just need to be adjusted so that the graphic doesn't get smaller when they change form. Anyways, the problem is when the red player walks from the top of yellow to blue or vice-versa. Occasionally, it will become snagged on the lower player's collision box.

    A reoccurring solution that I've found online is to add four game objects with edge colliders to either each level tile or the player (I'd opt for the latter). I feel like this would solve the problem described above, as well as remove the need for my tedious level building process. I've read that edge colliders are a good way to go to stop this snagging problem, but nobody has described how they actually do it. When I add an edge collider to an object, I get a horizontal line. Nothing in the inspector seems to allow me to adjust the length of this line. I can manually change the size by holding Shift and click/dragging the end points, but this often leads to me accidentally changing the y-position of a point, and that leads to other problems. The other thing is I don't know how I'm supposed to position these edge colliders in relation to my player. I could try to manually position my colliders exactly where each side of the box collider is, and then remove the box collider-- but again, that's imprecise. It seems like the side edge colliders should be a little bit shorter, too. That way, when the bottom collider dips into another collider (like, one on the level, for example), the side edge collider stays above that point. Mmm... I'm having a hard time explaining this. If that doesn't make any sense, I'll make a diagram or something.

    So what is the best way to go about replacing my players' box colliders with four walls made of edge colliders? Any help is always appreciated.
     
  2. Pyrian

    Pyrian

    Joined:
    Mar 27, 2014
    Posts:
    301
    So basically the editor doesn't allow you to be precise enough? Have you tried turning on vertex snapping? Alternatively, you could set the values programmatically through EdgeCollider2D.points (just an array of Vector2D's).
     
  3. MoonJellyGames

    MoonJellyGames

    Joined:
    Oct 2, 2014
    Posts:
    331
    I actually got the edges on my tiles just how I want them. I found that adding an empty game object to a tile and then adding the EdgeCollider2D component to that game object would make the EdgeCollider2D exactly the width of my tile. I could then adjust the transform in the inspector setting the x and y positions to half of the +/- object's width/height and rotatating 90-degrees for the side edges.

    This seems to make my tiles work as far as getting a player to walk along them without getting snagged. Because my characters also need to function as platforms, however, had to do something similar for them. I found that the player characters don't actually need four EdgeCollider2D sides though. I can keep the BoxCollider2D, making it a little bit shorter and moving the center up a little bit, and then adding a single EdgeCollider2D to the bottom.

    For the sake of future uses of EdgeCollider2Ds, would you (or somebody) explain how vertex snapping works?

    EDIT: I made a mistake. The EdgeCollider2D actually only becomes the desired width when it is added as a component of the same game object I want it attached to-- not when its a separate child object.
     
    Last edited: Nov 1, 2014
  4. GarBenjamin

    GarBenjamin

    Joined:
    Dec 26, 2013
    Posts:
    7,441
    You could also just not use the Unity colliders at all. One of advantages of using tile maps is you can simply check the points yourself to find out what tiles are there. In my tile map platform game I do that. When moving left 3 points on the left side are checked. Jumping 2 points at top are checked, etc. Just look at the map for those points and find out what tile is there. Then react accordingly. Simple, fast and proven method.
     
  5. MoonJellyGames

    MoonJellyGames

    Joined:
    Oct 2, 2014
    Posts:
    331
    Could you please clarify what you mean by using a tilemap instead of Unity colliders?

    The first time I tried making this game, it was with a platformer library for Flash called Flixel. It used tilemaps, and simple bounding boxes for collision, but both were very limited. My game's "stacking" mechanic (see diagram) seemed to require the use of a proper physics engine. That's the recommendation that came from the Flixel forum after my many failed attempts.



    I've made some changes and come to what appears to be a solution. It's a messy one though, and it could be expensive in terms of processing. Honestly, I'm not sure. Here's what it looks like:



    The players have a gameobject attached with an edge collider. I manually adjusted the length so that it's as close to the width of the player's collision box as I could make it. The edge is positioned at just the right height so that if the player is in a 1-block-deep pit, the edge is flush with the top of the adjacent floor tiles. This is so that other players can smoothly walk over them without getting snagged. It's important that this works consistently as I have designed a puzzle around it and the idea is reusable. The floating block has four edge colliders and a box collider. Why would I use five colliders on a single tile? Well, if I just go with a single box collider, the player's top edge collider hits it and is unable to pass underneath. If I just use four edge colliders, the raycasts that come from the bottom of the player do not reliably hit the tile's edge collider, so you can't jump when you should be able to. That's why the box collider is the full width of the tile, but not the full height.

    It seems to work well enough, but as I said, I don't know how expensive of a solution it is. :/

    EDIT: Nope. I was testing with three players. If I add a fourth one, the collision between players gets completely screwed up. Still searching for a solution... :/
     
    Last edited: Nov 3, 2014