Optimising a level of colliders

Now that The Wisp is over with, I’d like to talk about on of the problems I faced in development, the problem of using too many colliders.

The game uses a 2D lighting system bought off the asset store which draws a mesh that represents a light shining amongst geometry. The system used Physics2D.Raycast a lot which checks against all colliders in the scene to find which ones it hit.

all-colliders
All colliders in the scene
zoomed-in-on-colliders
Displaying that the colliders are indeed individual

This performance bug was not an easily fixable problem, it wasn’t my code, so I needed to optimise the other end of this problem, the number of colliders checked against. After some thought, I came to the conclusion that I would need to convert all existing colliders into a single large collider that the physics engine would check against once per raycast call.

I realised that the colliders of the scene are axis-aligned, which means I could paint the current colliders to a grid and make a single collider out of that.

I made a 2 dimensional grid of booleans where true meant a collider was overlapping this grid point. This was easy, just painting the colliders to the grid, by finding the grid location of the bottom left of the collider and how large it is horizontally and vertically, I was able to iterate through that, turning all that I go over to true. If I draw cubes using the Gizmos class in Unity I get:

boolean world grid.png
Colliders painted to grid, true is red, false is nothing

With this I could now figure out the collider. The way I did this was I drew a line around the true values in the grid of booleans.

To achieve this, I made another 2D array, but with an additional column and row. The idea behind this array is to find the direction a point needs to be going clockwise around the trues in the grid. At each point in the new array, I would check all directions starting with right and going clockwise. The way I would check if it is that direction would be to check if the grid point forward and to the right relative to the current direction was true and if the grid point forward and to the left relative to the current direction was false. If both were true, then that means the current direction is the direction I’m up to. If no direction is found, I would just but a null value, in this case since I’m using an int to represent the direction (0 = right, 1 = down, 2 = left, 3 = up) I would have it as -1.

The result looks like this:

collider outline.PNG
Outline of grid

The next thing I did was iterate through all of the new array to find the first direction, when found I would start a method that would get that loop.

The loop was just a while loop that would repeat if the current position in the grid was not the same as the original position in the grid. When I had a grid point, I would get the direction, add the current position to an array of grid points if the new direction is not the same as the current direction, move the current position to the grid point I was just at plus the direction it had, then set the old grid’s value to -1. I would do this until I found a -1 which means I would finish the loop, store it, and erase it at the same time. I would then continue to iterate through the world until either I found another direction and do what I just said, again, or reach the final position of the grid which would kick me out anyway.

Once I had all my points, I would throw it at the Polygon Collider which would easily build the collider for me:

polygon collider.PNG
Polgon Collider after its creation
zoomed in polygon collider.PNG
Close up of the polygon collider

And there we have it, my collider with essentially a step by step guide, though with none of the maths which is vital in doing this.

Problems:

  • The lighting system we were using, I found out didn’t support Polygon Colliders
    • The new lighting system I am currently using has this support, but doesn’t have some features.
  • I had a loop counter in a method which I hoped would stop infinite while loops., but instead broke the system.
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s