[ECS] How to dynamically update body friction

Hello,

I have a problem with updating ECS PhysicsCollider material.

For now, while I am creating new phycis entity I am simply doing:

Unity.Physics.Material someMaterial = new Unity.Physics.Material {
    Friction = 1,
    Restitution = 0.5f
};

BlobAssetReference<Unity.Physics.Collider> collider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry {
    Radius = baseDiameter/2,
    Vertex0 = new float3(0, 0.0f, 0),
    Vertex1 = new float3(0, height, 0)
}, CollisionFilter.Default, someMaterial);

EntityManager.SetComponentData<PhysicsCollider>(e, new PhysicsCollider { Value = collider });

And this is working perfectly fine. But the problem is when I want to change body collider, but use the same material. Here is some system to update colliders:

protected override void OnUpdate()
{
    var ecb = m_EndSimulationEcbSystem.CreateCommandBuffer().AsParallelWriter();
    
    List<RenderMesh> renderes = new List<RenderMesh>();
    EntityManager.GetAllUniqueSharedComponentData<RenderMesh>(renderes);
    foreach (RenderMesh render in renderes)
    {
        if (render.mesh == null) continue;
        var meshBounds = render.mesh.bounds;
        var center = (float3) meshBounds.center;
        
        Entities.WithSharedComponentFilter(render)
            .WithAll<UpdateColliderByMesh_TAG>()
            .ForEach((Entity e, int entityInQueryIndex, ref PhysicsCollider colliderComponent) => {
                var collider = Unity.Physics.BoxCollider.Create(new BoxGeometry {
                    Center = meshBounds.center,
                    Size = meshBounds.size,
                    Orientation = quaternion.Euler(0, 0, 0),
                    BevelRadius = 0.01f
                }); // <--- how to pass material from previous collider here????
                colliderComponent.Value = collider;
                ecb.RemoveComponent<UpdateColliderByMesh_TAG>(entityInQueryIndex, e);                       
            })
            .ScheduleParallel();
    }

    m_EndSimulationEcbSystem.AddJobHandleForProducer(this.Dependency);
}

And this is also working fine BUT it resets collider material to default one, so it means body has no friction.
So the question is how to get previous material and apply it to the new collider?

Any help will be more than welcome :wink:

@wiiiteekk
the easy way would be to setup "prefabs for the material to be called later

 [ReadOnly] static Unity.Physics.Material[] MaterialPrefabs = new Unity.Physics.Material /*continue here*/

But if you’re trying to access the data dynamically then you would have to cast the PhysicsCollider pointer to the matching collider you used to create it.

something like…

unsafe{
Unity.Physics.CapsuleColider* capsule_p = (Unity.Physics.CapsuleColider*)colliderComponent.ColliderPtr;            
var collider = Unity.Physics.BoxCollider.Create(new BoxGeometry {
                     Center = meshBounds.center,
                     Size = meshBounds.size,
                     Orientation = quaternion.Euler(0, 0, 0),
                     BevelRadius = 0.01f
                 },capsule_p->Filter,capsule_p->Material); // <--- add pointer values
                 colliderComponent.Value = collider;
                 ecb.RemoveComponent<UpdateColliderByMesh_TAG>(entityInQueryIndex, e);                     
}  

Though i don’t recommend this unless you know what your doing.