~starkingdoms/starkingdoms

ref: bf1ffce5e6655cd5b432bd1abf6eb0fc2cd8f09e starkingdoms/crates/unified/src/particle_editor/spawn.rs -rw-r--r-- 2.6 KiB
bf1ffce5ghostly_zsh sampling now clamps to the end of the spline correctly 5 months ago
                                                                                
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
use std::time::Duration;

use bevy::prelude::*;
use bevy_rapier2d::prelude::{RigidBody, Velocity};

use crate::{particle_editor::ecs::{CircleMesh, LifetimeTimer, ParentEffect, Particle, SpawnDelayTimer}, particles::ParticleEffect};

pub fn spawn_plugin(app: &mut App) {
    app.add_systems(Update, spawn_particles);
    app.add_systems(Update, lifetime_particles);
}

fn spawn_particles(
    mut commands: Commands,
    particle_effects: Query<(&Transform, &ParticleEffect, &mut SpawnDelayTimer)>,
    time: ResMut<Time>,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
    for (transform, effect, mut delay_timer) in particle_effects {
        delay_timer.0.tick(time.delta());
        let circle = CircleMesh(meshes.add(Circle::new(1.0)),
            materials.add(effect.color.sample(effect.color.clamp_time(0.0).unwrap()).unwrap()));
        if delay_timer.0.just_finished() {
            commands.spawn((
                RigidBody::Dynamic,
                Particle,
                transform.with_scale(Vec3::splat(effect.scale.sample(effect.scale.clamp_time(0.0).unwrap()).unwrap())),
                Mesh2d(circle.0.clone()),
                MeshMaterial2d(circle.1.clone()),
                Velocity {
                    linvel: effect.initial_linear_velocity.sample(&mut rand::rng()),
                    angvel: effect.initial_angular_velocity.sample(&mut rand::rng()),
                },
                LifetimeTimer(Timer::from_seconds(effect.lifetime_seconds.sample(&mut rand::rng()), TimerMode::Once)),
                circle,
                ParentEffect(effect.clone()),
            ));
            delay_timer.0.set_duration(Duration::from_secs_f32(effect.batch_spawn_delay_seconds.sample(&mut rand::rng())));
            delay_timer.0.reset();
        }
    }
}

fn lifetime_particles(
    mut commands: Commands,
    mut particles: Query<(Entity, &mut LifetimeTimer, &mut Transform, &CircleMesh, &ParentEffect), With<Particle>>,
    time: ResMut<Time>,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
    for (entity, mut timer, mut transform, circle, parent) in &mut particles {
        timer.0.tick(time.delta());
        transform.scale = Vec3::splat(parent.0.scale.sample(parent.0.scale.clamp_time(timer.0.elapsed_secs()).unwrap()).unwrap());
        materials.get_mut(&circle.1).unwrap().color = parent.0.color.sample(parent.0.color.clamp_time(timer.0.elapsed_secs()).unwrap()).unwrap();
        if timer.0.just_finished() {
            commands.entity(entity).despawn();
            meshes.remove(&circle.0);
            materials.remove(&circle.1);
        }
    }
}