-
-
Notifications
You must be signed in to change notification settings - Fork 208
Description
My use-case is a 3D dice-roller where dice are spawned as dynamic bodies and after they settle, I replace RigidBody::Dynamic with RigidBody::Static. Dice should maintain their collider state in both cases.
In Avian 0.3 this behaved properly, meaning the dice would stay as colliders when turned into static and any dice rolled over them would collide but not move the static ones.
In Avian 0.4, changing the rigid body type to static takes effect, but the collision properties are changing so that any collisions happening between new dice rolled as dynamic bodies is penetrating the ones that became static.
Worth mentioning that the collider mesh is a child of the rigid body entity.
Here's the dice spawning code:
let layers =
CollisionLayers::new(HexrollPhysicsLayer::Battlemaps, HexrollPhysicsLayer::Dice);
commands
.spawn((
Dice,
Name::new(dice.dice_name),
SceneRoot(dice_gltf.scenes[dice.scene_index].clone()),
RenderLayers::from_layers(&[RENDER_LAYER_DICE_SHADOW, RENDER_LAYER_DICE]),
origin_point.with_scale(Vec3::new(-5.5, 5.5, 5.5)),
RigidBody::Dynamic,
SleepThreshold {
linear: 2.0,
angular: 2.0,
},
SweptCcd::default(),
ColliderDensity(dice.density),
ColliderConstructorHierarchy::new(None)
.with_constructor_for_name(
dice.collider_name,
ColliderConstructor::TrimeshFromMesh,
)
.with_default_layers(layers),
MaxAngularSpeed(rng.gen_range(18.0..22.0)),
DieTimer {
roll_time: 1.100,
rest_time: 1.0,
},
Pickable {
should_block_lower: false,
is_hoverable: false,
},
))
.insert(Friction::new(0.8))
.insert(Restitution::new(0.1))
.insert(LinearDamping(0.5))
.insert(AngularDamping(0.4))
.observe(apply_render_layers_to_children);
}And here is the code that does the rigid body type switcharoo:
fn detect_roll(
mut commands: Commands,
children: Query<&Children>,
names: Query<&Name>,
gts: Query<&GlobalTransform>,
mut dice: Query<(Entity, &RigidBody, &AngularVelocity, &mut DieTimer), Without<DiceIsResolved>>,
time: Res<Time>,
) {
// ... unrelated code here
for (e, v) in d {
if let Some(n) = v.max_n {
commands.entity(e).try_insert(ColliderDensity(10000.0));
commands.entity(e).try_insert(MaxLinearSpeed(0.2));
commands.entity(e).try_insert(MaxAngularSpeed(0.2));
commands.entity(e).try_insert(RigidBody::Static);
}
}
}