Unity Version: 2019.4.2f1
Unity Physics Version: preview.5 - 0.4.0
Entities Version: preview.4 - 0.11.1
Summary:
Collisions between a Capsule Collider and Mesh Colliders is inconsistent.
Details:
I have a custom terrain system which generates its own terrain meshes, in segments of 64x64 units. The terrain uses Mesh Colliders to add physics. These colliders work for some segments, but do not work for others.
I have tried, and failed, to discern what may be causing this inconsistent behaviour. It occurs even when the terrain is flat, and even when the same mesh is used to build the collider for all of the segments. Some will generate collisions, others will not and the player falls through. Interestingly, sometimes direction entering/traversing the terrain matters. Going from segment A to B may fail, but C to B works.
Some details about these meshes:
- Approximately 7,000 to 28,000 vertices with a third that many triangles, depending on segment complexity.
- Have tried both a mesh of only the terrain surface as well as a “complete” mesh (all sides).
- All terrain entities have the same components, including: PhysicsMass, RenderBounds, PhysicsCollider, Rotation, Translation, etc.
The only components that vary in value between the segments are: WorldRenderBounds, LocalToWorld, Translation, and ChunkWorldRenderBounds. As would be expected.
Raycasts also fail to return any hits for these problem segments as well, in addition to the player falling through.
I have a bunch of code surrounding my implementation, so it is hard to give a good, simple code snippet. However the most relevant section is below.
protected override void OnUpdate()
{
Entities.ForEach((
Entity entity,
ref TerrainColliderProxyComponent proxy,
ref Translation position,
ref RenderBounds bounds) =>
{
if (proxy.RequiresColliderUpdate)
{
Material material = GetMaterial(entity);
CollisionFilter filter = GetCollisionFilter(entity);
TerrainSegment segment = ...;
UpdatePhysicsMeshCollider(entity, segment.TerrainMesh, material, filter);
proxy.RequiresColliderUpdate = false;
}
});
}
private void UpdatePhysicsMeshCollider(Entity entity, CustomMesh mesh, Material material, CollisionFilter filter)
{
mesh.FetchPhysicsData(out NativeArray<float3> vertices, out NativeArray<int3> triangles);
var collider = MeshCollider.Create(vertices, triangles, filter, material);
var component = new PhysicsCollider() { Value = collider };
if (!EntityManager.HasComponent<PhysicsCollider>(entity))
{
PostUpdateCommands.AddComponent(entity, component);
}
else
{
EntityManager.SetComponentData(entity, component);
}
triangles.Dispose();
vertices.Dispose();
}
private Material GetMaterial(Entity entity)
{
if (EntityManager.HasComponent<PhysicsMaterialProxyComponent>(entity))
{
return EntityManager.GetComponentData<PhysicsMaterialProxyComponent>(entity).ToMaterial();
}
return Material.Default;
}
private CollisionFilter GetCollisionFilter(Entity entity)
{
if (EntityManager.HasComponent<CollisionFilterProxyComponent>(entity))
{
return EntityManager.GetComponentData<CollisionFilterProxyComponent>(entity).ToCollisionFilter();
}
return CollisionFilter.Default;
}
And finally, a GIF. It shows where four segments meet, and the top two segments are OK while the bottom two the collisions fail.
Questions:
- Any ideas why the same mesh which works as the source of the Mesh Collider for Entity A but it fails for Entity B?
- Are there any limitations to the mesh data supplied to the MeshCollider.Create method? For example, Unity Meshes have a limit of 65536 vertices. Though I do not think this is the issue since the identical meshes work for some entities, but fails for others.
- The documentation states that the Mesh Collider is a “triangle soup.” Can the mesh have holes? Can it be a single plane (ie terrain surface)?
- Are there any limitations/concerns with when a mesh collider is made/timing of creating multiple mesh colliders? I assume it is safe to do so within a system?
- Does winding order matter for mesh colliders? From my experience it does not seem so.
Thank you for your time.