Skip to content

Commit 06b160f

Browse files
authored
Replace ParticleEffectBundle with required comp. (#426)
Replace the `ParticleEffectBundle` component with a set of `#[require()]` on the `ParticleEffect` itself. This aligns Hanabi with the Bevy approach of required ECS components and removal of bundles.
1 parent edccd95 commit 06b160f

33 files changed

+138
-339
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ perf.data.old
1717

1818
# Other
1919
ignore/
20+
media/

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5151
- `Attribute::PREV` and `Attribute::NEXT` are soft-deprecated.
5252
You can continue to use them, but they do not have any influence anymore on ribbons and trails,
5353
nor any other built-in functionality of Hanabi.
54+
- `ParticleEffect` now requires (in the ECS sense) the `CompiledParticleEffect`, `Visibility`, and `Transform` components.
55+
This means those components are automatically added by Bevy each time a `ParticleEffect` is spawned.
5456

5557
### Fixed
5658

@@ -72,6 +74,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7274
- Similarly, removed `ParticleGroupSet`.
7375
- Removed `EffectAsset::ribbon_group` as well as `with_trails()` and `with_ribbons()`.
7476
Use the `Attribute::RIBBON_ID` instead to assign a per-particle ribbon ID.
77+
- Removed `ParticleEffectBundle`. Use `ParticleEffect` directly instead.
7578

7679
## [0.14.0] 2024-12-09
7780

README.md

+5-7
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,13 @@ fn setup(mut effects: ResMut<Assets<EffectAsset>>) {
113113

114114
### Spawn a particle effect
115115

116-
Use a `ParticleEffect` to create an effect instance from an existing asset. The simplest way is to use the `ParticleEffectBundle` to ensure all required components are spawned together.
116+
Use a `ParticleEffect` to create an effect instance from an existing asset.
117117

118118
```rust
119-
commands
120-
.spawn(ParticleEffectBundle {
121-
effect: ParticleEffect::new(effect_handle),
122-
transform: Transform::from_translation(Vec3::Y),
123-
..Default::default()
124-
});
119+
commands.spawn((
120+
ParticleEffect::new(effect_handle),
121+
Transform::from_translation(Vec3::Y),
122+
));
125123
```
126124

127125
## Examples

docs/migration-v0.14-to-v0.15.md

+6
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,9 @@ See the updated `ribbon.rs` example for a full-featured demo of a single ribbon,
149149
and the `worms.rs` and `firework.rs` examples
150150
for an example of combining hierarchical effects and ribbons,
151151
and use multiple ribbons in the same effect.
152+
153+
## Bundle removal
154+
155+
Following Bevy's own deprecation of the bundle mechanism, `ParticleEffectBundle` has been removed.
156+
Use `ParticleEffect` directly instead, which now supports the ECS `#[require()]` mechanism,
157+
and will automatically add the mandatory components `CompiledParticleEffect`, `Visibility`, and `Transform`.

examples/2d.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,11 @@ fn setup(
9595

9696
// Spawn an instance of the particle effect, and override its Z layer to
9797
// be above the reference white square previously spawned.
98-
commands
99-
.spawn(ParticleEffectBundle {
100-
// Assign the Z layer so it appears in the egui inspector and can be modified at runtime
101-
effect: ParticleEffect::new(effect).with_z_layer_2d(Some(0.1)),
102-
..default()
103-
})
104-
.insert(Name::new("effect:2d"));
98+
commands.spawn((
99+
// Assign the Z layer so it appears in the egui inspector and can be modified at runtime
100+
ParticleEffect::new(effect).with_z_layer_2d(Some(0.1)),
101+
Name::new("effect:2d"),
102+
));
105103
}
106104

107105
fn update_plane(time: Res<Time>, mut query: Query<&mut Transform, With<Mesh2d>>) {

examples/activate.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ fn setup(
130130
);
131131

132132
ball.with_children(|node| {
133-
node.spawn(ParticleEffectBundle::new(effect))
134-
.insert(Name::new("effect"));
133+
node.spawn((ParticleEffect::new(effect), Name::new("effect")));
135134
});
136135

137136
commands.spawn((

examples/billboard.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ fn setup(
150150
));
151151

152152
commands.spawn((
153-
ParticleEffectBundle::new(effect),
153+
ParticleEffect::new(effect),
154154
EffectMaterial {
155155
images: vec![texture_handle],
156156
},

examples/circle.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ fn setup(
148148
));
149149

150150
commands.spawn((
151-
ParticleEffectBundle::new(effect),
151+
ParticleEffect::new(effect),
152152
EffectMaterial {
153153
images: vec![texture_handle],
154154
},

examples/expr.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,5 @@ fn setup(mut commands: Commands, mut effects: ResMut<Assets<EffectAsset>>) {
9696
.render(OrientModifier::new(OrientMode::AlongVelocity)),
9797
);
9898

99-
commands.spawn((
100-
Name::new("whirlwind"),
101-
ParticleEffectBundle {
102-
effect: ParticleEffect::new(effect),
103-
transform: Transform::IDENTITY,
104-
..Default::default()
105-
},
106-
));
99+
commands.spawn((Name::new("whirlwind"), ParticleEffect::new(effect)));
107100
}

examples/firework.rs

+3-15
Original file line numberDiff line numberDiff line change
@@ -245,23 +245,14 @@ fn create_effect(mut commands: Commands, mut effects: ResMut<Assets<EffectAsset>
245245
// Rocket
246246
let rocket_effect = effects.add(create_rocket_effect());
247247
let rocket_entity = commands
248-
.spawn((
249-
Name::new("rocket"),
250-
ParticleEffectBundle {
251-
effect: ParticleEffect::new(rocket_effect),
252-
..Default::default()
253-
},
254-
))
248+
.spawn((Name::new("rocket"), ParticleEffect::new(rocket_effect)))
255249
.id();
256250

257251
// Sparkle trail
258252
let sparkle_trail_effect = effects.add(create_sparkle_trail_effect());
259253
commands.spawn((
260254
Name::new("sparkle_trail"),
261-
ParticleEffectBundle {
262-
effect: ParticleEffect::new(sparkle_trail_effect),
263-
..Default::default()
264-
},
255+
ParticleEffect::new(sparkle_trail_effect),
265256
// Set the rocket effect as parent. This gives access to the rocket effect's particles,
266257
// which in turns allows inheriting their position (and other attributes if
267258
// needed).
@@ -272,10 +263,7 @@ fn create_effect(mut commands: Commands, mut effects: ResMut<Assets<EffectAsset>
272263
let trails_effect = effects.add(create_trails_effect());
273264
commands.spawn((
274265
Name::new("trails"),
275-
ParticleEffectBundle {
276-
effect: ParticleEffect::new(trails_effect),
277-
..Default::default()
278-
},
266+
ParticleEffect::new(trails_effect),
279267
// Set the rocket effect as parent. This gives access to the rocket effect's particles,
280268
// which in turns allows inheriting their position (and other attributes if needed).
281269
EffectParent::new(rocket_entity),

examples/force_field.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ fn setup(
314314
.render(ColorOverLifetimeModifier { gradient }),
315315
);
316316

317-
commands.spawn(ParticleEffectBundle::new(effect));
317+
commands.spawn((ParticleEffect::new(effect), EffectProperties::default()));
318318
}
319319

320320
fn spawn_on_click(

examples/gradient.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ fn setup(
8787
commands
8888
.spawn((
8989
Name::new("effect"),
90-
ParticleEffectBundle::new(effect),
90+
ParticleEffect::new(effect),
9191
// We need to spawn the effect with the same render layer as the camera, otherwise it
9292
// won't be rendered.
9393
RenderLayers::layer(3),

examples/init.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,7 @@ fn spawn_effect(
6565
.with_children(|p| {
6666
p.spawn((
6767
Name::new(name),
68-
ParticleEffectBundle {
69-
effect: ParticleEffect::new(effect),
70-
..Default::default()
71-
},
68+
ParticleEffect::new(effect),
7269
RotateSpeed(speed),
7370
))
7471
.with_children(|p| {

examples/instancing.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -81,19 +81,16 @@ impl InstanceManager {
8181
commands
8282
.spawn((
8383
Name::new(format!("{:?}", pos)),
84-
ParticleEffectBundle {
85-
effect: ParticleEffect::new(if alt {
86-
self.alt_effect.clone()
87-
} else {
88-
self.effect.clone()
89-
}),
90-
transform: Transform::from_translation(Vec3::new(
91-
pos.x as f32 * 10.,
92-
pos.y as f32 * 10.,
93-
0.,
94-
)),
95-
..Default::default()
96-
},
84+
ParticleEffect::new(if alt {
85+
self.alt_effect.clone()
86+
} else {
87+
self.effect.clone()
88+
}),
89+
Transform::from_translation(Vec3::new(
90+
pos.x as f32 * 10.,
91+
pos.y as f32 * 10.,
92+
0.,
93+
)),
9794
// Only used if alt_effect, but just simpler to add all the time for this
9895
// example only.
9996
EffectMaterial {

examples/lifetime.rs

+6-15
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,8 @@ fn setup(
9494
commands
9595
.spawn((
9696
Name::new("burst 12s"),
97-
ParticleEffectBundle {
98-
effect: ParticleEffect::new(effect1),
99-
transform: Transform::from_translation(Vec3::new(-50., 0., 0.)),
100-
..Default::default()
101-
},
97+
ParticleEffect::new(effect1),
98+
Transform::from_translation(Vec3::new(-50., 0., 0.)),
10299
))
103100
.with_children(|p| {
104101
// Reference cube to visualize the emit origin
@@ -146,11 +143,8 @@ fn setup(
146143
commands
147144
.spawn((
148145
Name::new("burst 3s"),
149-
ParticleEffectBundle {
150-
effect: ParticleEffect::new(effect2),
151-
transform: Transform::from_translation(Vec3::new(0., 0., 0.)),
152-
..Default::default()
153-
},
146+
ParticleEffect::new(effect2),
147+
Transform::from_translation(Vec3::new(0., 0., 0.)),
154148
))
155149
.with_children(|p| {
156150
// Reference cube to visualize the emit origin
@@ -198,11 +192,8 @@ fn setup(
198192
commands
199193
.spawn((
200194
Name::new("burst 0.75s"),
201-
ParticleEffectBundle {
202-
effect: ParticleEffect::new(effect3),
203-
transform: Transform::from_translation(Vec3::new(50., 0., 0.)),
204-
..Default::default()
205-
},
195+
ParticleEffect::new(effect3),
196+
Transform::from_translation(Vec3::new(50., 0., 0.)),
206197
))
207198
.with_children(|p| {
208199
// Reference cube to visualize the emit origin

examples/multicam.rs

+6-15
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,8 @@ fn setup(
164164
commands
165165
.spawn((
166166
Name::new("0"),
167-
ParticleEffectBundle {
168-
effect: ParticleEffect::new(effect1),
169-
transform: Transform::from_translation(Vec3::new(-30., 0., 0.)),
170-
..Default::default()
171-
},
167+
ParticleEffect::new(effect1),
168+
Transform::from_translation(Vec3::new(-30., 0., 0.)),
172169
RenderLayers::layer(0),
173170
))
174171
.with_children(|p| {
@@ -186,11 +183,8 @@ fn setup(
186183
commands
187184
.spawn((
188185
Name::new("1"),
189-
ParticleEffectBundle {
190-
effect: ParticleEffect::new(effect2),
191-
transform: Transform::from_translation(Vec3::new(0., 0., 0.)),
192-
..Default::default()
193-
},
186+
ParticleEffect::new(effect2),
187+
Transform::from_translation(Vec3::new(0., 0., 0.)),
194188
RenderLayers::layer(1),
195189
))
196190
.with_children(|p| {
@@ -208,11 +202,8 @@ fn setup(
208202
commands
209203
.spawn((
210204
Name::new("2"),
211-
ParticleEffectBundle {
212-
effect: ParticleEffect::new(effect3),
213-
transform: Transform::from_translation(Vec3::new(30., 0., 0.)),
214-
..Default::default()
215-
},
205+
ParticleEffect::new(effect3),
206+
Transform::from_translation(Vec3::new(30., 0., 0.)),
216207
RenderLayers::layer(2),
217208
))
218209
.with_children(|p| {

examples/ordering.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,9 @@ fn setup(
113113

114114
commands.spawn((
115115
Name::new("firework"),
116-
ParticleEffectBundle {
117-
effect: ParticleEffect::new(effect1),
118-
transform: Transform {
119-
translation: Vec3::Z,
120-
..default()
121-
},
116+
ParticleEffect::new(effect1),
117+
Transform {
118+
translation: Vec3::Z,
122119
..default()
123120
},
124121
));

examples/portal.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,7 @@ fn setup(mut commands: Commands, mut effects: ResMut<Assets<EffectAsset>>) {
9494

9595
commands.spawn((
9696
Name::new("portal"),
97-
ParticleEffectBundle {
98-
effect: ParticleEffect::new(effect1),
99-
transform: Transform::IDENTITY,
100-
..Default::default()
101-
},
97+
ParticleEffect::new(effect1),
98+
Transform::IDENTITY,
10299
));
103100
}

examples/puffs.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,7 @@ fn setup(
9898
let effect = create_effect(mesh, &mut effects);
9999

100100
// Spawn the effect.
101-
commands.spawn((
102-
Name::new("cartoon explosion"),
103-
ParticleEffectBundle {
104-
effect: ParticleEffect::new(effect),
105-
..default()
106-
},
107-
));
101+
commands.spawn((Name::new("cartoon explosion"), ParticleEffect::new(effect)));
108102
}
109103

110104
// Builds the smoke puffs.

examples/random.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,8 @@ fn setup(
8383
commands
8484
.spawn((
8585
Name::new("emit:random"),
86-
ParticleEffectBundle {
87-
effect: ParticleEffect::new(effect),
88-
transform: Transform::from_translation(Vec3::new(0., 0., 0.)),
89-
..Default::default()
90-
},
86+
ParticleEffect::new(effect),
87+
Transform::from_translation(Vec3::new(0., 0., 0.)),
9188
))
9289
.with_children(|p| {
9390
// Reference cube to visualize the emit origin

examples/ribbon.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,7 @@ fn setup(mut commands: Commands, mut effects: ResMut<Assets<EffectAsset>>) {
123123

124124
let effect = effects.add(effect);
125125

126-
commands
127-
.spawn(ParticleEffectBundle {
128-
effect: ParticleEffect::new(effect),
129-
transform: Transform::IDENTITY,
130-
..default()
131-
})
132-
.insert(Name::new("ribbon"));
126+
commands.spawn((ParticleEffect::new(effect), Name::new("ribbon")));
133127
}
134128

135129
fn move_head(mut query: Query<&mut Transform, With<ParticleEffect>>, timer: Res<Time>) {

0 commit comments

Comments
 (0)