Runtime Collider Generation
The 2D ColliderGen package comes with an experimental RuntimeAlphaMeshCollider.cs script. It does not yet provide optimization such as parallelization, but should serve as a foundation to base your own optimization code upon.
You can attach the RuntimeAlphaMeshCollider component to your GameObject instead of an AlphaMeshCollider component via the Inspector “Add Component” menu.
Manually Writing a Runtime Collider Generation Script
Please have a look at the script 2DColliderGen/Scripts/AlphaMeshCollider.cs or RuntimeAlphaMeshCollider.cs, where you find three methods that are especially relevant:
GenerateUnreducedColliderMesh(), CalculateUnreducedOutlineForAllColliderRegions() and
- a) Manually create a binary image (a bool[,] array), or
b) create a binary image from a texture via PolygonOutlineFromImageFrontend.BinaryAlphaThresholdImageFromTexture().
- Detect the collider regions via IslandDetector.DetectIslandsFromBinaryImage(). you then have an array of all islands (sorted by size, see IslandDetector.Region class members) and sea-regions. You might want to exclude regions when their size is too small.
- Call mOutlineAlgorithm.UnreducedOutlineFromBinaryImage() with the starting points of each island that you want to include and get a polygon outline with a lot of vertices (one at each pixel corner). Maybe you want to use the class ColliderRegionData in CommonColliderGenerationData.cs and the nested classes AlphaMeshCollider.RegionIndependentParameters and AlphaMeshCollider.ColliderRegionParameters in AlphaMeshCollider.cs, just check the code on how to use them.
- Reduce each unreduced outline by calling mOutlineAlgorithm.ReduceOutline() with the vertex count or by setting mOutlineAlgorithm.VertexReductionDistanceTolerance. The latter might be a better fit for the automatic adaptive process. It will stop when either the mOutlineAlgorithm.MaxPointCount is reached or when the distance tolerance is reached (whichever criterion is fulfilled first).
- Call mOutlineAlgorithm.TriangleFenceFromOutline() to receive the collider triangles (for each island).
- Join the triangle lists of all islands.
- Set the vertices of your MeshCollider component as is best described in these threads: http://answers.unity3d.com/questions/171571/dynamic-mesh-collider.html http://forum.unity3d.com/threads/32467-How-to-update-a-mesh-collider
“We ended up splitting our planet into a 10 x 10 grid, but this was mostly due to updates to the texture rather than limitations from collider recalculation – sending a large texture update to the graphics processor turns out to be quite expensive and caused a large framerate stutter every time it was sent, so using smaller textures helped this.
We did break the calculations into multiple coroutine steps (though not multiple threads). We also severely limited the number of vertices in each collider (since the colliders were quite small due to breaking it into a grid). We also only used the first couple islands in each piece of the grid, since sometimes very small islands would be created due to a few pixels remaining after digging, and these didn’t really need collision on them.”
Check out their trailer below if you want to see their application of runtime collider generation in action, performing in realtime on a mobile device.