Hey guys,
I’m new to DOTS and starting to experiment with physics. I’m trying to build a simple wall built from many blocks. Those blocks should be influenced by gravity only after a collision with a cannonball. For that purpose, I’m trying to switch from motion type “Kinematic” to “Dynamic”.
The code below works almost as expected except that, for some reasons I don’t understand, the angular velocity of each block remains 0 after being set to Dynamic. Also, and this is very likely for another reason, I would like these block to correctly react to the collision with the cannonball, while at the moment, they just fall straight.
Any help would be much appreciated
[UpdateAfter(typeof(EndFramePhysicsSystem))]
public class CollisionEventSystem : JobComponentSystem
{
BuildPhysicsWorld BuildPhysicsWorldSystem;
StepPhysicsWorld StepPhysicsWorldSystem;
protected override void OnCreate()
{
BuildPhysicsWorldSystem = World.GetOrCreateSystem<BuildPhysicsWorld>();
StepPhysicsWorldSystem = World.GetOrCreateSystem<StepPhysicsWorld>();
}
[BurstCompile]
struct CollisionEventDataJob : ICollisionEventsJob
{
[ReadOnly] public PhysicsWorld PhysicsWorld;
public ComponentDataFromEntity<CollisionEventData> CollisionEventDataGroup;
public void Execute(CollisionEvent collisionEvent)
{
Entity entity = collisionEvent.Entities.EntityA;
if (CollisionEventDataGroup.Exists(entity))
{
CollisionEvent.Details d = collisionEvent.CalculateDetails(ref PhysicsWorld);
if (d.EstimatedImpulse > 0f)
{
var data = CollisionEventDataGroup[entity];
data.MotionType = BodyMotionType.Dynamic;
CollisionEventDataGroup[entity] = data;
}
}
}
}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
var job = new CollisionEventDataJob
{
PhysicsWorld = BuildPhysicsWorldSystem.PhysicsWorld,
CollisionEventDataGroup = GetComponentDataFromEntity<CollisionEventData>()
};
var jobHandle = job.Schedule(StepPhysicsWorldSystem.Simulation, ref BuildPhysicsWorldSystem.PhysicsWorld, inputDeps);
jobHandle.Complete();
return default;
}
}
[UpdateAfter(typeof(BuildPhysicsWorld))]
public class ChangeMotionTypeSystem : ComponentSystem
{
protected override void OnUpdate()
{
Entities.ForEach((Entity entity, ref CollisionEventData modifier) =>
{
if (modifier.MotionType == BodyMotionType.Dynamic)
{
PhysicsMass m = EntityManager.GetComponentData<PhysicsMass>(entity);
float desiredDynamicMass = math.rcp(1f);
if(m.InverseMass != desiredDynamicMass)
{
m.InverseMass = desiredDynamicMass;
PhysicsGravityFactor g = EntityManager.GetComponentData<PhysicsGravityFactor>(entity);
g.Value = 1f;
PostUpdateCommands.AddComponent(entity, m);
PostUpdateCommands.AddComponent(entity, g);
}
}
});
}
}