Skip to content

Changing entity from RigidBody::Dynamic to RigidBody::Static in runtime stopped working when moving from 0.3 to 0.4 #911

@hexroll

Description

@hexroll

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);
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions