1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//! One call particle effects over the engine's GPU particle presets. Each
//! returns the emitter entity, which moves with [`set_position`]
//! (crate::prelude::set_position), parents like anything else, and stops with
//! [`despawn`](crate::prelude::despawn).
use nightshade::prelude::*;
/// A continuous fire at `position`. Pairs well with
/// [`emit_smoke`](emit_smoke) just above it and a [`point_light`]
/// (crate::prelude::point_light) for the glow.
pub fn emit_fire(world: &mut World, position: Vec3) -> Entity {
spawn_emitter(world, ParticleEmitter::fire(position))
}
/// A continuous smoke column at `position`.
pub fn emit_smoke(world: &mut World, position: Vec3) -> Entity {
spawn_emitter(world, ParticleEmitter::smoke(position))
}
/// A one shot burst of `count` particles in the given color at `position`.
/// The particles fall under gravity and fade. The emitter entity stays after
/// the burst, so despawn it or reuse it for the next burst.
pub fn emit_burst(world: &mut World, position: Vec3, color: [f32; 4], count: u32) -> Entity {
spawn_emitter(
world,
ParticleEmitter::firework_explosion(
position,
Vec3::new(color[0], color[1], color[2]),
count,
),
)
}
/// A continuous fountain of bright sparks at `position`, falling fast under
/// gravity.
pub fn emit_sparks(world: &mut World, position: Vec3) -> Entity {
spawn_emitter(world, ParticleEmitter::sparks(position))
}
/// A firework shell launched from `position` with an upward `velocity` that
/// arcs and bursts on its own.
pub fn emit_firework(world: &mut World, position: Vec3, velocity: Vec3) -> Entity {
spawn_emitter(world, ParticleEmitter::firework_shell(position, velocity))
}
/// A configurable continuous emitter at `position`. `rate` is particles per
/// second, `lifetime` is how long each lives in seconds, `size` is the start
/// size in world units, and `gravity` pulls the particles each frame. For the
/// curated looks reach for [`emit_fire`], [`emit_smoke`], or [`emit_sparks`].
pub fn emit_particles(
world: &mut World,
position: Vec3,
rate: f32,
lifetime: f32,
size: f32,
gravity: Vec3,
) -> Entity {
let mut emitter = ParticleEmitter::smoke(position);
emitter.spawn_rate = rate;
emitter.particle_lifetime_min = lifetime;
emitter.particle_lifetime_max = lifetime;
emitter.size_start = size;
emitter.size_end = size;
emitter.gravity = gravity;
emitter.one_shot = false;
emitter.enabled = true;
spawn_emitter(world, emitter)
}
fn spawn_emitter(world: &mut World, emitter: ParticleEmitter) -> Entity {
let entity = spawn_entities(
world,
PARTICLE_EMITTER | LOCAL_TRANSFORM | LOCAL_TRANSFORM_DIRTY | GLOBAL_TRANSFORM | NAME,
1,
)[0];
world.core.set_name(entity, Name("api::effect".to_string()));
assign_local_transform(
world,
entity,
LocalTransform {
translation: emitter.position,
..Default::default()
},
);
world.core.set_particle_emitter(entity, emitter);
entity
}