diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index 4cb6d61bc0..7f0d7d84de 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -1618,6 +1618,63 @@ impl<'a> EntityCommands<'a> { self.queue_handled(entity_command::remove::(), warn) } + /// Removes a [`Bundle`] of components from the entity if the predicate returns true. + /// + /// This is useful for chaining method calls. + /// + /// # Example + /// + /// ``` + /// # use bevy_ecs::prelude::*; + /// # #[derive(Resource)] + /// # struct PlayerEntity { entity: Entity } + /// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } } + /// #[derive(Component)] + /// struct Health(u32); + /// #[derive(Component)] + /// struct Strength(u32); + /// #[derive(Component)] + /// struct Defense(u32); + /// + /// #[derive(Bundle)] + /// struct CombatBundle { + /// health: Health, + /// strength: Strength, + /// } + /// + /// fn remove_combat_stats_system(mut commands: Commands, player: Res) { + /// commands + /// .entity(player.entity) + /// .remove_if::<(Defense, CombatBundle)>(|| !player.is_spectator()); + /// } + /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system); + /// ``` + #[track_caller] + pub fn remove_if(&mut self, condition: impl FnOnce() -> bool) -> &mut Self { + if condition() { + self.remove::() + } else { + self + } + } + + /// Removes a [`Bundle`] of components from the entity if the predicate returns true. + /// + /// This is useful for chaining method calls. + /// + /// # Note + /// + /// If the entity does not exist when this command is executed, + /// the resulting error will be ignored. + #[track_caller] + pub fn try_remove_if(&mut self, condition: impl FnOnce() -> bool) -> &mut Self { + if condition() { + self.try_remove::() + } else { + self + } + } + /// Removes a [`Bundle`] of components from the entity. /// /// This will remove all components that intersect with the provided bundle;