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

Despawning Entities that have a NoAutoCenterOfMass, NoAutoAngularInertia, or NoAutoMass component causes panic #607

Closed
ramirezmike opened this issue Dec 28, 2024 · 0 comments · Fixed by #608
Labels
A-Dynamics Relates to rigid body dynamics: motion, mass, constraint solving, joints, CCD, and so on P-Crash A sudden unexpected crash

Comments

@ramirezmike
Copy link
Contributor

If you despawn an entity that has a NoAutoCenterOfMass, NoAutoAngularInertia, or NoAutoMass component the following panic occurs:

if let Some(entity_commands) = commands.get_entity(entity) {
    entity_commands.despawn_recursive();
}
thread 'main' panicked at /bevy_ecs-0.15.0/src/system/commands/mod.rs:1982:13:
error[B0003]: crates/avian3d/../../src/dynamics/rigid_body/mass_properties/components/mod.rs:979:10: 
Could not insert a bundle (of type `avian3d::dynamics::rigid_body::mass_properties::components::RecomputeMassProperties`) 
for entity 14v1#4294967310 because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003

There are probably more graceful ways to handle despawning entities, but I've typically gotten by with doing the above, which panics if the entity has one of the mentioned components.

Here's a modified version of the cubes example that shows the issue. It attempts to despawn the cubes when you press the Spacebar

#![allow(clippy::unnecessary_cast)]

use avian3d::prelude::*;
use bevy::prelude::*;
use examples_common_3d::ExampleCommonPlugin;

fn main() {
    App::new()
        .add_plugins((
            DefaultPlugins,
            ExampleCommonPlugin,
            PhysicsPlugins::default(),
        ))
        .insert_resource(ClearColor(Color::srgb(0.05, 0.05, 0.1)))
        .add_systems(Startup, setup)
        .add_systems(Update, despawn_on_space)
        .run();
}

#[derive(Component)]
struct IsCube;

fn setup(
    mut commands: Commands,
    mut materials: ResMut<Assets<StandardMaterial>>,
    mut meshes: ResMut<Assets<Mesh>>,
) {
    let cube_mesh = meshes.add(Cuboid::default());

    // Ground
    commands.spawn((
        Mesh3d(cube_mesh.clone()),
        MeshMaterial3d(materials.add(Color::srgb(0.7, 0.7, 0.8))),
        Transform::from_xyz(0.0, -2.0, 0.0).with_scale(Vec3::new(100.0, 1.0, 100.0)),
        RigidBody::Static,
        Collider::cuboid(1.0, 1.0, 1.0),
    ));

    let cube_size = 2.0;

    // Spawn cube stacks
    for x in -2..2 {
        for y in -2..2 {
            for z in -2..2 {
                let position = Vec3::new(x as f32, y as f32 + 3.0, z as f32) * (cube_size + 0.05);
                commands.spawn((
                    Mesh3d(cube_mesh.clone()),
                    MeshMaterial3d(materials.add(Color::srgb(0.2, 0.7, 0.9))),
                    Transform::from_translation(position).with_scale(Vec3::splat(cube_size as f32)),
                    RigidBody::Dynamic,
                    IsCube,
                    NoAutoCenterOfMass,
                    Collider::cuboid(1.0, 1.0, 1.0),
                ));
            }
        }
    }

    // Directional light
    commands.spawn((
        DirectionalLight {
            illuminance: 5000.0,
            shadows_enabled: true,
            ..default()
        },
        Transform::default().looking_at(Vec3::new(-1.0, -2.5, -1.5), Vec3::Y),
    ));

    // Camera
    commands.spawn((
        Camera3d::default(),
        Transform::from_translation(Vec3::new(0.0, 12.0, 40.0)).looking_at(Vec3::Y * 5.0, Vec3::Y),
    ));
}

fn despawn_on_space(
    mut commands: Commands,
    keyboard_input: Res<ButtonInput<KeyCode>>,
    mut query: Query<Entity, With<IsCube>>,
) {
    if keyboard_input.pressed(KeyCode::Space) {
        for entity in &mut query {
            if let Some(entity_commands) = commands.get_entity(entity) {
                entity_commands.despawn_recursive();
            }
        }
    }
}
@Jondolf Jondolf added A-Dynamics Relates to rigid body dynamics: motion, mass, constraint solving, joints, CCD, and so on P-Crash A sudden unexpected crash labels Dec 28, 2024
Jondolf pushed a commit that referenced this issue Dec 28, 2024
# Objective

- This prevents a panic that can occur if an entity with one of the NoAuto components is despawned.
- Fixes #607 

## Solution

This solution to the problem just uses the non-panicking versions of retrieving an entity from the world and inserting a component in the on_remove_no_auto_mass_property function that runs when the component is removed. 

I think an argument could be made that this silently hides an issue of code trying to operate on an entity that no longer exists or that the on_remove shouldn't fire if it's happening because an entity is being despawned.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Dynamics Relates to rigid body dynamics: motion, mass, constraint solving, joints, CCD, and so on P-Crash A sudden unexpected crash
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants