So I believe as of version 1 I can add RigidBodies to my “baker” sub-scene objects and these are converted appropriately for the ECS system at runtime.
When I convert my Spheres in the Physics Samples Events - Collisons, to traditional RigidBodies, rather than PhysicsBodys things work as expected. However my floor HAS to remain as a PhysicsShape to trigger any collisions. I.E. I can’t seem to convert that to a normal Box Collider (with or without a rigidbody), and still get events triggered.
Q1) Because the PhysicsBody and Physics shape are now part of the samples package, I assume we’re supposed to move towards authoring using the traditional RigidBody (this is implied in the docs), and allow the baking system to create the necessary ECS components?
Q2) But then how do I get collision events without using the PhysicsShape/Body stuff?
RigidBodies are not raising CollisionEvents (TriggerEvents are raised correctly if the IsTrigger checkbox is checked).
Also RigidBody constrains are ignored.
This can be checked with a very simple test with two entities, one using Collider + RigidBody (doesn’t work) and the other Physics Shape + Physics Body (does work but needs physics samples to be imported).
It looks like Constrains are not being correctly baked into Intertia Tensors and the “Collision Raise collision Events” is not set either.
Thanks for reporting this feature gap.
I can confirm that currently built-in physics only uses either CollisionResponsePolicy.Collide (default) or CollisionResponsePolicy.RaiseTriggerEvents (if the built-in collider’s isTrigger property is true) as value for Material.CollisionResponse in the corresponding baked collider.
In other words, unless you manually change this property in your Entities’ baked collider components through a system post-baking (or via a baking system that runs after the EndColliderBakingSystem, you can not use the desired response type (CollisionResponsePolicy.CollideRaiseCollisionEvents) for built-in colliders at this time.
Note that this is not a regression but was simply never implemented.
@SergioTurGil : To confirm my understanding, I assume you mean these Constraints, right?
Update here:
In an upcoming release, CollisionEvents will now be produced for built-in Collider authoring components which are not triggers (“Is Trigger”: false) and which have the “Provide Contacts” option enabled.
The events can be picked up with a ICollisionEventsJob as usual.
In com.unity.entities@1.3.14 the issue with rigidbody constraints not working is still pressent.
For everyone as troubled with the issue, I found a workaround. Enjoy!
I created additional rigidbody authoring to store the constraints data as a component.
Also I created PhysicsVelocityConstraintsSystem that basucally nullifies all the changes to PhysicsVelocity at the end of a PhysicsSystemGroup. Idealy it should execute right before the velocity is applyed by untiy.physics but I didn’t fount the system responsible for that.
If anyone finds the proper place, please contribute.
PhysicsConstraints Autoring:
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
namespace ProjectTools.Ecs
{
public struct PhysicsConstraints : IComponentData
{
public bool3 freezePosition;
public bool3 freezeRotation;
}
public class RigidbodyBaker : Baker<Rigidbody>
{
public override void Bake(Rigidbody authoring)
{
var entity = GetEntity(TransformUsageFlags.Dynamic);
var constraints = authoring.constraints;
AddComponent(entity, new PhysicsConstraints
{
freezePosition = constraints.HasFlag(RigidbodyConstraints.FreezePosition) ? new bool3(true, true, true) :
new bool3(
constraints.HasFlag(RigidbodyConstraints.FreezePositionX),
constraints.HasFlag(RigidbodyConstraints.FreezePositionY),
constraints.HasFlag(RigidbodyConstraints.FreezePositionZ)
),
freezeRotation = constraints.HasFlag(RigidbodyConstraints.FreezeRotation) ? new bool3(true, true, true) :
new bool3(
constraints.HasFlag(RigidbodyConstraints.FreezeRotationX),
constraints.HasFlag(RigidbodyConstraints.FreezeRotationY),
constraints.HasFlag(RigidbodyConstraints.FreezeRotationZ)
),
});
}
}
}
PhysicsVelocityConstraints System:
using Unity.Burst;
using Unity.Entities;
using Unity.Physics;
using Unity.Physics.Systems;
namespace ProjectTools.Ecs
{
[UpdateInGroup(typeof(PhysicsSystemGroup), OrderLast = true)]
[BurstCompile]
public partial struct PhysicsVelocityConstraintsSystem : ISystem
{
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<PhysicsConstraints>();
state.RequireForUpdate<PhysicsVelocity>();
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
var positionJobHandle = new PositionConstraintsJob().ScheduleParallel(state.Dependency);
state.Dependency = positionJobHandle;
}
}
[BurstCompile]
public partial struct PositionConstraintsJob : IJobEntity
{
[BurstCompile]
public void Execute(ref PhysicsVelocity velocity, in PhysicsConstraints constraints)
{
var freezePosition = constraints.freezePosition;
if (freezePosition.x) velocity.Linear.x = 0;
if (freezePosition.y) velocity.Linear.y = 0;
if (freezePosition.z) velocity.Linear.z = 0;
var freezeRotation = constraints.freezeRotation;
if (freezeRotation.x) velocity.Angular.x = 0;
if (freezeRotation.y) velocity.Angular.y = 0;
if (freezeRotation.z) velocity.Angular.z = 0;
}
}
}