When spawning tuple bundles it can sometimes difficult to identify their purpose:
// What am I?
commands.spawn((
Position::new(),
Velocity::new()
))
If we used an inspector such as the bevy-inspector-egui then it would be hard to identify which component is what just by their component list.
Remember that even when we use a named bundle, the bundle itself is ephemeral and only the components will remain afterwards.
One common alternative is to create components such as Player
that can make
querying easier. But some components won’t be queried and many component types
can clutter up our code base.
So it can be useful to create a Name
component that makes this debugging much
easier:
commands.spawn((
Name::new("Player"),
Position::new(),
Velocity::new()
))
Another useful metadata component is to create components that tag entities to be cleaned up at specific points in our apps.
commands.spawn((
Name::new("Player"),
Position::new(),
Velocity::new(),
CleanupOnGameExit
))
This can be used in combination with generic systems to trigger a cleanup for multiple component types:
use bevy::{
prelude::*,
ecs::component::Component,
};
#[derive(Component)]
struct CleanupOnGameExit;
#[derive(Debug, Clone, Eq, PartialEq, Hash, Default, States)]
enum AppState {
#[default]
MainMenu,
InGame,
Paused,
}
impl AppState {
fn next(&self) -> Self {
match *self {
AppState::MainMenu => AppState::InGame,
AppState::InGame => AppState::Paused,
AppState::Paused => AppState::InGame
}
}
}
fn cleanup_system<T: Component>(
mut commands: Commands,
q: Query<Entity, With<T>>,
) {
for e in q.iter() {
commands.entity(e).despawn_recursive();
}
}
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.init_state::<AppState>()
.add_systems(
OnExit(AppState::InGame),
cleanup_system::<CleanupOnGameExit>
);
}