88 lines
2.1 KiB
Rust
88 lines
2.1 KiB
Rust
|
|
use bevy::prelude::*;
|
|
use avian3d::prelude::*;
|
|
|
|
use crate::util::ecs::PathTracer;
|
|
|
|
pub struct ProjectilesPlugin;
|
|
|
|
impl Plugin for ProjectilesPlugin
|
|
{
|
|
fn build(&self, app: &mut App)
|
|
{
|
|
app.add_systems(Startup, setup_projectiles);
|
|
|
|
app.add_event::<BulletFiredEvent>();
|
|
app.add_systems(Update, on_bullet_fired_event.run_if(on_event::<BulletFiredEvent>));
|
|
}
|
|
}
|
|
|
|
#[derive(Resource)]
|
|
pub struct BulletResources
|
|
{
|
|
pub mesh: Mesh3d,
|
|
pub material: MeshMaterial3d<StandardMaterial>,
|
|
pub collider: Collider,
|
|
}
|
|
|
|
fn setup_projectiles(
|
|
mut commands: Commands,
|
|
mut meshes: ResMut<Assets<Mesh>>,
|
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
|
) {
|
|
commands.insert_resource(BulletResources {
|
|
mesh: Mesh3d(meshes.add(Sphere::new(1.0))),
|
|
material: MeshMaterial3d(materials.add(StandardMaterial {
|
|
base_color: Color::srgb(0.7, 0.1, 0.1),
|
|
..default()
|
|
})),
|
|
collider: Collider::sphere(1.0),
|
|
});
|
|
}
|
|
|
|
#[derive(Event, Copy, Clone, PartialEq, Debug)]
|
|
pub struct BulletFiredEvent
|
|
{
|
|
pub position: Vec3,
|
|
pub direction: Dir3,
|
|
pub speed: f32,
|
|
pub radius: f32,
|
|
pub density: f32,
|
|
}
|
|
|
|
#[derive(Component)]
|
|
pub struct Bullet;
|
|
|
|
fn on_bullet_fired_event(
|
|
mut commands: Commands,
|
|
mut events: EventReader<BulletFiredEvent>,
|
|
bullet_resources: Res<BulletResources>,
|
|
) {
|
|
let to_projectile = |event: &BulletFiredEvent|
|
|
{
|
|
let transform = Transform::IDENTITY
|
|
.with_translation(event.position)
|
|
.with_scale(Vec3::splat(event.radius))
|
|
.looking_to(event.direction, Vec3::Y);
|
|
|
|
(
|
|
Bullet,
|
|
bullet_resources.mesh.clone(),
|
|
bullet_resources.material.clone(),
|
|
bullet_resources.collider.clone(),
|
|
transform,
|
|
RigidBody::Dynamic,
|
|
ColliderDensity(event.density),
|
|
SpeculativeMargin(event.radius),
|
|
SweptCcd::LINEAR,
|
|
LinearVelocity(event.speed * event.direction),
|
|
PathTracer::default(),
|
|
)
|
|
};
|
|
|
|
commands.spawn_batch(events.read()
|
|
.map(to_projectile)
|
|
.collect::<Vec<_>>()
|
|
);
|
|
}
|