Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
hikikones opened this issue Mar 15, 2023 · 0 comments
Open

Comments

@hikikones
Copy link

hikikones commented Mar 15, 2023

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
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::<NoUserData>::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::<NoUserData>::get_systems(PhysicsSet::SyncBackend)
                        .in_base_set(PhysicsSet::SyncBackend),
                )
                .add_systems(
                    RapierPhysicsPlugin::<NoUserData>::get_systems(PhysicsSet::SyncBackendFlush)
                        .in_base_set(PhysicsSet::SyncBackendFlush),
                )
                .add_systems(
                    RapierPhysicsPlugin::<NoUserData>::get_systems(PhysicsSet::StepSimulation)
                        .in_base_set(PhysicsSet::StepSimulation),
                )
                .add_system(despawn.in_base_set(PhysicsSet::StepSimulation))
                .add_systems(
                    RapierPhysicsPlugin::<NoUserData>::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<Entity, With<Collider>>, 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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant