|
1 | 1 | //! This example shows how you can know when a [`Component`] has been removed, so you can react to it.
|
2 |
| -
|
| 2 | +//! |
| 3 | +//! When a [`Component`] is removed from an [`Entity`], all [`Observer`] with an [`OnRemove`] trigger for |
| 4 | +//! that [`Component`] will be notified. These observers will be called immediately after the |
| 5 | +//! [`Component`] is removed. For more info on observers, see the |
| 6 | +//! [observers example](https://github.com/bevyengine/bevy/blob/main/examples/ecs/observers.rs). |
| 7 | +//! |
| 8 | +//! Advanced users may also consider using a lifecycle hook |
| 9 | +//! instead of an observer, as it incurs less overhead for a case like this. |
| 10 | +//! See the [component hooks example](https://github.com/bevyengine/bevy/blob/main/examples/ecs/component_hooks.rs). |
3 | 11 | use bevy::prelude::*;
|
4 | 12 |
|
5 | 13 | fn main() {
|
6 |
| - // Information regarding removed `Component`s is discarded at the end of each frame, so you need |
7 |
| - // to react to the removal before the frame is over. |
8 |
| - // |
9 |
| - // Also, `Components` are removed via a `Command`, which are not applied immediately. |
10 |
| - // So you need to react to the removal at some stage after `apply_deferred` has run, |
11 |
| - // and the Component` is removed. |
12 |
| - // |
13 |
| - // With these constraints in mind we make sure to place the system that removes a `Component` in |
14 |
| - // `Update', and the system that reacts on the removal in `PostUpdate`. |
15 | 14 | App::new()
|
16 | 15 | .add_plugins(DefaultPlugins)
|
17 | 16 | .add_systems(Startup, setup)
|
| 17 | + // This system will remove a component after two seconds. |
18 | 18 | .add_systems(Update, remove_component)
|
19 |
| - .add_systems(PostUpdate, react_on_removal) |
| 19 | + // This observer will react to the removal of the component. |
| 20 | + .observe(react_on_removal) |
20 | 21 | .run();
|
21 | 22 | }
|
22 | 23 |
|
23 |
| -// This `Struct` is just used for convenience in this example. This is the `Component` we'll be |
24 |
| -// giving to the `Entity` so we have a `Component` to remove in `remove_component()`. |
| 24 | +/// This `struct` is just used for convenience in this example. This is the [`Component`] we'll be |
| 25 | +/// giving to the `Entity` so we have a [`Component`] to remove in `remove_component()`. |
25 | 26 | #[derive(Component)]
|
26 | 27 | struct MyComponent;
|
27 | 28 |
|
@@ -50,12 +51,10 @@ fn remove_component(
|
50 | 51 | }
|
51 | 52 | }
|
52 | 53 |
|
53 |
| -fn react_on_removal(mut removed: RemovedComponents<MyComponent>, mut query: Query<&mut Sprite>) { |
54 |
| - // `RemovedComponents<T>::read()` returns an iterator with the `Entity`s that had their |
55 |
| - // `Component` `T` (in this case `MyComponent`) removed at some point earlier during the frame. |
56 |
| - for entity in removed.read() { |
57 |
| - if let Ok(mut sprite) = query.get_mut(entity) { |
58 |
| - sprite.color = Color::srgb(0.5, 1., 1.); |
59 |
| - } |
| 54 | +fn react_on_removal(trigger: Trigger<OnRemove, MyComponent>, mut query: Query<&mut Sprite>) { |
| 55 | + // The `OnRemove` trigger was automatically called on the `Entity` that had its `MyComponent` removed. |
| 56 | + let entity = trigger.entity(); |
| 57 | + if let Ok(mut sprite) = query.get_mut(entity) { |
| 58 | + sprite.color = Color::srgb(0.5, 1., 1.); |
60 | 59 | }
|
61 | 60 | }
|
0 commit comments