Search Unity

Dynamically creating EdgeCollider2D to form solid shapes

Discussion in '2D' started by direcalmly, Aug 31, 2014.

  1. direcalmly

    direcalmly

    Joined:
    Sep 5, 2013
    Posts:
    3
    I hope this doesn't come off as a "build my game for me" post, but I've been thinking about how I might do this for a while. There are alternatives to doing this, but it would be a rock-solid way to work with Unity's 2d built-in physics system.

    I'm creating a 2D platformer where the levels (the solid parts anyway) are built out of blocks of equal size. My first go-around I put box colliders on them and called it good. What I noticed was that my player, that had a polygon collider attached to a rigidbody, would periodically "bump" over what I'm guessing is the corners of each block as they sat next to each other. I tried a few work-arounds like making the player's collider a circle but that changed the gameplay physics too much to be viable. I noticed that this bumping problem was eliminated if the surfaces my character moved on were single colliders (like an edge collider or a single box collider). However, this was a pain to do manually and I'd rather just be able to build the level with boxes.

    Here's my little graphic explaining what I want to do:

    map-explanation.png

    So what I want to do is have a script that automatically detects the shapes created by these groups of blocks and builds an edge collider (or maybe a polygon collider) to surround them. This would eliminate any of the bumping over the tiles because the edges would be continuous. The script, as I've been thinking about it, would go something like this:

    1. Get all blocks tagged 'ground-tile' and put them in a list.
    2. Find all blocks that are touching each other and sort those into lists, one for each shape created.
    3. In those lists of shapes, find the points that define each shape.
    4. Create edge colliders connecting the points.

    I'm good with C# and Unity, but this is some higher-level design that I haven't approached before. What would be a good way start writing something like this?

    Just for fun here's a video showing the gameplay:

     
    Last edited: Aug 31, 2014
  2. SpacemanBoots

    SpacemanBoots

    Joined:
    Nov 27, 2012
    Posts:
    32
    Are you sure you want to do this? What you are suggestion can have quite some complexity. And I would reckon that shaping a PolygonCollider2D would take probably only 3 minutes for the level you displayed in the video.
     
  3. direcalmly

    direcalmly

    Joined:
    Sep 5, 2013
    Posts:
    3
    After working on some pseudocode for this I can say--yes it is quite complex. I was hoping that this was at least an uncommon way to construct levels and someone had some suggestions on where to start, maybe an example or two.
     
  4. Vitor_r

    Vitor_r

    Joined:
    May 23, 2013
    Posts:
    93
    Can you show us your pseudocode so i can see the direction you're going.

    Anyway, i would try to make some GameObjects and put them where the red dots are positioned.
    Change their names to numbers, so i can check by code that the number 1 connect to number 2 and so on.
    Parent them all to another GameObject. This parent gameobject will be a whole plataform. So you will have to do this for each plataform.
    Then a script in this parent game object that will add edge colliders connecting his children positions.

    Btw, it will add some extra time to your level design.

    Example:

    - Parent
    -- 1
    -- 2
    -- 3
    -- 4

    The script will create one EdgeCollider and using points connect the '1' GO position to the '2' GO position, then connect to the '3' GO position, then connect to the '4' GO position and finally when there are no more childrens connect to the first one again.

    Hope this could be useful :)
     
  5. SpacemanBoots

    SpacemanBoots

    Joined:
    Nov 27, 2012
    Posts:
    32
    Well if you still want to pull through with it, I thought of something that might work.

    This is presuming that all blocks fall on a perfect grid, there are no holes in the structure and that you already have the blocks separated into groups of blocks that are connected.

    If you take one group of blocks and generate all the points for that group(i.e. 4 points per block). Generating those points you can put them in a dictionary, with the key being your point and the value being the number of times that you generated the same point.

    Now you can filter through the list, removing all the points that have an even count. Which should leave you with all the outlining points. These are still unordered though.

    To order the points you can walk through the points starting at an arbitrary point.
    The rules are:
    • Never walk backwards
    • The next point must align to the current point on either the x or y axis.
    This will still mean you will get multiple options of what the next point might be sometimes. In those cases you will have to split the object that walks the points, so you'll have multiple object walking over your points.

    To eliminate the objects that walk the wrong path, you can simply remove the ones that have finished the path while there is still an other object busy walking. The correct path will always be the longest.

    I think that should work.


    @Vitor_r What's the difference between modeling a PolygonCollider2D and what you are suggesting?
     
  6. Vitor_r

    Vitor_r

    Joined:
    May 23, 2013
    Posts:
    93
    Well, you can make a new EdgeCollider Component for each face of the plataform if you want.
    I think that a EdgeCollider is just a PolygonCollider with 2 points.

    Btw, your suggestion is a lot script oriented, might work better for direcalmly