Problems generating runtime mesh collider - ECS Physics

Hello everyone!

I want to achieve following:

  1. Generate mesh on MonoBehaviour side
  2. Transfer mesh to ECS
  3. Generate mesh collider based on obtained mesh data
  4. I want to attach generated collider to the entity which is child of another entity. I don’t want the generated collider to be visible

What I did so far:

  1. Created managed component containing Mesh property:
    public class MeshDataComponent : IComponentData, IDisposable
    {
        public Mesh Mesh;

        public void Dispose()
        {
            UnityEngine.Object.Destroy(Mesh);
        }
    }
  1. I filled Mesh property with valid mesh data and attached MeshDataComponent to the entity on which I want the collider to be generated
  2. Then I created system for the collider generation:
[BurstCompile]
    [UpdateInGroup(typeof(InitializationSystemGroup))]
    public partial struct MeshColliderInitializationSystem : ISystem, ISystemStartStop
    {
        private BlobAssetReference<Unity.Physics.Collider> _createdColliderBlob;
        private EntityQuery _entityQuery;

        [BurstCompile]
        public void OnCreate(ref SystemState state)
        {
            state.RequireForUpdate<MeshDataComponent >();
        }

        private void ISystemStartStop.OnStartRunning(ref SystemState state)
        {
            _entityQuery = SystemAPI.QueryBuilder()
                .WithAll<MeshDataComponent>()
                .Build();
        }

        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            // Make sure this system runs only once
            state.Enabled = false;

            EntityCommandBuffer ecb = new EntityCommandBuffer(Allocator.Temp);

            // Get relevant entity and component
            Entity targetColliderEntity = _entityQuery.GetSingletonEntity();
            MeshDataComponent meshData = _entityQuery.GetSingleton<MeshDataComponent>();

            // Creation of collider blob
            _createdColliderBlob = Unity.Physics.MeshCollider.Create(meshData.Mesh,
                CollisionFilter.Default, Unity.Physics.Material.Default);
            
            // Create physics collider based on blob data and assign it to the entity
            PhysicsCollider collider = new PhysicsCollider() { Value = _createdColliderBlob };
            ecb.AddComponent<PhysicsCollider>(targetColliderEntity, collider);

            ecb.Playback(state.EntityManager);
            ecb.Dispose();
        }

        [BurstCompile]
        public void OnDestroy(ref SystemState state)
        {
            _createdColliderBlob.Dispose();
        }

        public void OnStopRunning(ref SystemState state) { }
    }

Result:

  • Expected collider is not in the scene and I experience no additional collisions, although if I go and inspect the target entity in the editor I can see that PhysicsCollider component has been sucessfully added to the entity, it just seems like it’s collisions are completely non-working.

I double checked Mesh property in MeshDataComponent and this seems to be assigned correctly, so I think my problem is related to the System code - probably I am missing some important part? Can please someone suggest me where the problem could be?

Thanks in advance for your answers!

Make sure the additional mandatory components are also added to the collision entity. There’s a list of components here. Most importantly you need a PhysicsWorldIndex and LocalTransform (dynamic/static) or LocalToWorld (static).

Thanks for the response, in the end I found out where the problem is - I was trying to attach the collider on the child entity, where the parent entity already got PhysicsBody. This parent entity was already using compound collider composed from other child colliders and when I created my new mesh collider runtime nothing happened, as I was probably doing something not supported by ECS physic.

The solutions could theoretically be:

  1. Recreate compound collider on the parent entity again after runtime collider has been added
  2. Break the structure of my object so I am actually not creating collider on a child entity, but on a separate one (In this case I would indeed have to add some of the components you mentioned) and then simulate it’s parent-child relationship through dedicated system

For my case I was able to completely avoid runtime generated colliders in the end, so I didn’t need to deal with any of the proposed solutions