dimforge / dimforge/bevy_rapier

Despawn events are missed in fixed timestep simulation with low tick rate

Open
#343 0 comments 5 reactions 0 assignees View on GitHub
A-Integration C-Bug D-Medium P-Medium S-not-started
Dominant language
Rust
Stars
1.6k
Forks
282
PR merge metrics
No merged PRs in 30d

Description

Detection for despawns/removed components are now backed by events (#324). However, since events only persist for 2 frames, they will likely be missed by a fixed timestep simulation with low tick rate. This results in colliders/rigid bodies still persisting when they should have been despawned.

Here is an example where a cube is despawned, but the collider remains visible:

Example

```rust
use bevy::prelude::*;
use bevy_rapier3d::prelude::*;

const PHYSICS_DELTA: f32 = 1.0 / 4.0;

fn main() {
App::new()
.insert_resource(ClearColor(Color::BLACK))
.insert_resource(RapierConfiguration {
timestep_mode: TimestepMode::Fixed {
dt: PHYSICS_DELTA,
substeps: 1,
},
..Default::default()
})
.insert_resource(FixedTime::new_from_secs(PHYSICS_DELTA))
.add_plugins(DefaultPlugins)
.add_plugin(RapierPhysicsPlugin::::default().with_default_system_setup(false))
.add_plugin(RapierDebugRenderPlugin::default())
.add_startup_system(setup)
.edit_schedule(CoreSchedule::FixedUpdate, |schedule| {
schedule
.configure_sets(
(
PhysicsSet::SyncBackend,
PhysicsSet::SyncBackendFlush,
PhysicsSet::StepSimulation,
PhysicsSet::Writeback,
)
.chain(),
)
.add_systems(
RapierPhysicsPlugin::::get_systems(PhysicsSet::SyncBackend)
.in_base_set(PhysicsSet::SyncBackend),
)
.add_systems(
RapierPhysicsPlugin::::get_systems(PhysicsSet::SyncBackendFlush)
.in_base_set(PhysicsSet::SyncBackendFlush),
)
.add_systems(
RapierPhysicsPlugin::::get_systems(PhysicsSet::StepSimulation)
.in_base_set(PhysicsSet::StepSimulation),
)
.add_system(despawn.in_base_set(PhysicsSet::StepSimulation))
.add_systems(
RapierPhysicsPlugin::::get_systems(PhysicsSet::Writeback)
.in_base_set(PhysicsSet::Writeback),
);
})
// .add_system(systems::sync_removals.in_base_set(CoreSet::Last))
.run();
}

fn setup(mut commands: Commands) {
// Camera
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(5.0, 5.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
..Default::default()
});

// Cube
commands.spawn((TransformBundle::IDENTITY, Collider::cuboid(1.0, 1.0, 1.0)));
}

fn despawn(cube_q: Query>, mut commands: Commands) {
if let Ok(entity) = cube_q.get_single() {
println!("Despawn!");
commands.entity(entity).despawn();
}
}
```

Adding the `sync_removals` system to `CoreSet::Last` resolves this issue. Should this perhaps be the default, as it was before with the `DetectDespawn` stage?

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.