NEW: Experimental RuntimeAlphaMeshCollider.cs script
I’ve just recently written an experimental script (without any performance optimizations, so no parallel or coroutine stuff yet!) which should basically do the job and could serve as a base for your code.
Download the RuntimeAlphaMeshCollider.cs file here.
Just attach the script to your GameObject instead of a ‘normal’ AlphaMeshCollider (there’s no menu entry for it yet, sorry).
General
For now there is some coding involved with generating colliders at runtime. This page provides a rather informal step-by-step description which covers the necessary steps (Note that some method-names could have changed a little in upcoming updates after version 1.2, but it should serve as a basic guideline). It’s not perfect but should help you pretty well with the implementation. If any questions arise from reading this, just drop us a message and we’ll help you out.
Necessary Steps
[divider_advanced color=”#0067A3″ paddingTop=”0″ paddingBottom=”10″ thickness=”4″ width=”100%” top=”true”]
I suggest you have a look at the 2DColliderGen/Scripts/AlphaMeshCollider.cs script, there you find two methods that might especially be interesting for you:
GenerateUnreducedColliderMesh() and especially CalculateUnreducedOutlineForAllColliderRegions() and
ReduceAndStoreColliderMesh().
- a) you manually create a binary image (bool[,] array)
or b) create one from a texture via PolygonOutlineFromImageFrontend.BinaryAlphaThresholdImageFromTexture(). - you then 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.
- you then 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.
- you then reduce each unreduced outline by calling mOutlineAlgorithm.ReduceOutline() with the vertex count or by setting the mOutlineAlgorithm.VertexReductionDistanceTolerance (might be handy for you!) – this way might fit the automatic adaptive process better! It will stop when either the mOutlineAlgorithm.MaxPointCountis reached or when the distance tolerance is reached (the more restrictive one wins..).
- you call mOutlineAlgorithm.TriangleFenceFromOutline() to receive the collider triangles (for each island).
- you join the triangle lists of all islands.
- you 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
This should be it.
[divider_padding]
Performance Optimization
[divider_advanced color=”#0067A3″ paddingTop=”0″ paddingBottom=”10″ thickness=”4″ width=”100%” top=”true”]
I have asked Sarah from Orbit Games about what kind of optimizations they have applied for their planet-digging game ‘Plannit’, she told me the following:
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.
Hope this helps, if you need any additional help on the subject, just ask!