How to correctly change the transforms of child colliders in the compound collider?
How was it originally intended to do this, if the bone and collider transforms become two different objects after baking. And animation systems (animation clips) have links only to the transformations of the bone object. ![]()
Is it possible to forbid the child collider to detach so that it has same transform with a bone entity?
UpdateCompColAuth.cs (3.5 KB)
Like this?
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics;
using Unity.Physics.Systems;
using Unity.Transforms;
using UnityEngine;
using static Unity.Physics.CompoundCollider;
using Collider = Unity.Physics.Collider;
using CompoundCollider = Unity.Physics.CompoundCollider;
using Material = Unity.Physics.Material; // Import Material
public class UpdateCompColAuth : MonoBehaviour
{
public int childIndex;
public float moveSpeed;
public float sineMul;
}
public class UpdateCompColAuthBaker : Baker<UpdateCompColAuth>
{
public override void Bake(UpdateCompColAuth authoring)
{
var ent = GetEntity(authoring.gameObject, TransformUsageFlags.Dynamic);
AddComponent(ent, new MoveChildColliderComponent()
{
ChildIndex = authoring.childIndex,
MoveSpeed = authoring.moveSpeed,
sineMul = authoring.sineMul
});
}
}
// Example component to hold child index and move speed
public struct MoveChildColliderComponent : IComponentData
{
public int ChildIndex;
public float MoveSpeed;
public float sineMul;
}
// Example system to move a child collider
[BurstCompile]
[RequireMatchingQueriesForUpdate]
[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
[UpdateBefore(typeof(PhysicsSystemGroup))]
public partial struct MoveChildColliderSystem : ISystem
{
float deltaTime;
float time;
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
deltaTime = SystemAPI.Time.DeltaTime;
time = (float)SystemAPI.Time.ElapsedTime % 100f;
foreach (var (physicsCollider, moveData, pairData) in
SystemAPI.Query < RefRW<PhysicsCollider>, MoveChildColliderComponent, DynamicBuffer<PhysicsColliderKeyEntityPair>> ())
{
if (physicsCollider.ValueRO.IsValid)
{
MoveChild(ref physicsCollider.ValueRW, in moveData, deltaTime, time);
}
}
}
private readonly unsafe void MoveChild(ref PhysicsCollider physicsCollider, in MoveChildColliderComponent moveData, float deltaTime, float time)
{
BlobAssetReference<Collider> colliderBlob = physicsCollider.Value;
if (colliderBlob.Value.Type == ColliderType.Compound)
{
//CompoundCollider compoundCollider = colliderBlob.Value.GetCompoundCollider();
CompoundCollider* compoundCollider = (CompoundCollider*)physicsCollider.ColliderPtr;
// Assuming you have a way to get the child index
int childIndex = moveData.ChildIndex;
if (childIndex >= 0 && childIndex < compoundCollider->NumChildren)
{
// Get the child collider data
CompoundCollider.Child child = compoundCollider->Children[childIndex];
// Modify the transform (example: move it up)
quaternion rot = quaternion.EulerXYZ(0f, moveData.MoveSpeed * deltaTime, 0f);
rot = math.mul(rot, child.CompoundFromChild.rot);
child.CompoundFromChild.rot = rot;
child.CompoundFromChild.pos.y = math.sin(time) * moveData.sineMul;
// Update the child in the compound collider (important!)
compoundCollider->Children[childIndex] = child; // not needed in latest versions of the API
//Update compoundCollider
compoundCollider->Update();
}
}
}
}
You could update children this way, yes.
This is the approach used to alter wheel positions relative to the chassis in Unity Vehicles, our official vehicle controller solution for ECS.
If the displacements become too large, however, this could potentially lead to slight slowdowns in the collision detection and in collision queries since the compound’s bounding volume hierarchy and its axis aligned bounding box might become suboptimal. This is also documented in the CompoundCollider.Update() function. This is not the case for vehicle wheels but might be the case for characters.
So, it might be best in your case to enforce individual colliders for each bone by inserting additional kinematic Rigidbody components alongside each child collider in your GameObject hierarchy which you want to keep as a seperate, movable rigid body entity (that’s is, not becoming baked into a compound collider as a child collider).
You might need to slightly restructure your GameObject hierarchy for this approach. Without further details on your exact setup it’s difficult to confirm though.