diff --git a/assets/models/characters/mig pilot.glb b/assets/models/characters/mig pilot.glb index 559934f..fb257a4 100644 Binary files a/assets/models/characters/mig pilot.glb and b/assets/models/characters/mig pilot.glb differ diff --git a/src/abilities/missile.rs b/src/abilities/missile.rs index 7cf4e93..c61b206 100644 --- a/src/abilities/missile.rs +++ b/src/abilities/missile.rs @@ -137,10 +137,11 @@ fn on_trigger_missile( ), ( Trail::new( - t.translation, + 12, LinearRgba::rgb(1., 0.0, 0.), LinearRgba::rgb(0.9, 0.9, 0.) - ), + ) + .with_pos(t.translation), Gizmo { handle: gizmo_assets.add(GizmoAsset::default()), line_config: GizmoLineConfig { diff --git a/src/character.rs b/src/character.rs index d67f888..61ad642 100644 --- a/src/character.rs +++ b/src/character.rs @@ -1,5 +1,9 @@ -use crate::{GameState, heads_database::HeadsDatabase, loading_assets::GameAssets}; -use bevy::{ecs::system::SystemParam, platform::collections::HashMap, prelude::*}; +use crate::{ + GameState, heads_database::HeadsDatabase, loading_assets::GameAssets, utils::trail::Trail, +}; +use bevy::{ + ecs::system::SystemParam, platform::collections::HashMap, prelude::*, scene::SceneInstanceReady, +}; use std::time::Duration; #[derive(Component, Debug)] @@ -34,12 +38,12 @@ pub struct CharacterAnimations { pub fn plugin(app: &mut App) { app.add_systems( Update, - (spawn, setup_once_loaded, setup_projectile_origin).run_if(in_state(GameState::Playing)), + (spawn, setup_once_loaded).run_if(in_state(GameState::Playing)), ); #[cfg(feature = "dbg")] app.add_systems( Update, - debug_show_projectile_origin.run_if(in_state(GameState::Playing)), + debug_show_projectile_origin_and_trial.run_if(in_state(GameState::Playing)), ); } @@ -63,29 +67,56 @@ fn spawn( }); let asset = gltf_assets.get(handle).unwrap(); - commands.entity(entity).insert(( - Transform::from_translation(Vec3::new(0., -1.45, 0.)).with_scale(Vec3::splat(1.2)), - SceneRoot(asset.scenes[0].clone()), - )); + commands + .entity(entity) + .insert(( + Transform::from_translation(Vec3::new(0., -1.45, 0.)).with_scale(Vec3::splat(1.2)), + SceneRoot(asset.scenes[0].clone()), + )) + .observe(find_marker_bones); } } -fn setup_projectile_origin( +fn find_marker_bones( + trigger: Trigger, mut commands: Commands, - query: Query>, descendants: Query<&Children>, name: Query<&Name>, + mut gizmo_assets: ResMut>, ) { - for character in query.iter() { - for child in descendants.iter_descendants(character) { - let Ok(name) = name.get(child) else { - continue; - }; - if name.as_str() == "ProjectileOrigin" { - commands.entity(child).insert(ProjectileOrigin); - } + let entity = trigger.target(); + + let mut origin_found = false; + for child in descendants.iter_descendants(entity) { + let Ok(name) = name.get(child) else { + continue; + }; + + if name.as_str() == "ProjectileOrigin" { + commands.entity(child).insert(ProjectileOrigin); + origin_found = true; + } else if name.as_str().starts_with("Trail") { + commands.entity(child).insert(( + Trail::new( + 20, + LinearRgba::new(1., 1.0, 1., 0.5), + LinearRgba::new(1., 1., 1., 0.5), + ), + Gizmo { + handle: gizmo_assets.add(GizmoAsset::default()), + line_config: GizmoLineConfig { + width: 20., + ..default() + }, + ..default() + }, + )); } } + + if !origin_found { + error!("ProjectileOrigin not found"); + } } fn setup_once_loaded( @@ -142,9 +173,9 @@ fn setup_once_loaded( } #[cfg(feature = "dbg")] -fn debug_show_projectile_origin( +fn debug_show_projectile_origin_and_trial( mut gizmos: Gizmos, - query: Query<&GlobalTransform, With>, + query: Query<&GlobalTransform, Or<(With, With)>>, ) { for projectile_origin in query.iter() { gizmos.sphere( diff --git a/src/utils/trail.rs b/src/utils/trail.rs index 8602b4d..3cc7db2 100644 --- a/src/utils/trail.rs +++ b/src/utils/trail.rs @@ -10,16 +10,20 @@ pub struct Trail { } impl Trail { - pub fn new(pos: Vec3, col_start: LinearRgba, col_end: LinearRgba) -> Self { - let mut v = Vec::with_capacity(12); - v.push(pos); + pub fn new(points: usize, col_start: LinearRgba, col_end: LinearRgba) -> Self { Self { - points: v, + points: Vec::with_capacity(points), col_start, col_end, } } + pub fn with_pos(self, pos: Vec3) -> Self { + let mut trail = self; + trail.add(pos); + trail + } + pub fn add(&mut self, pos: Vec3) { if self.points.len() >= self.points.capacity() { self.points.pop(); @@ -36,19 +40,21 @@ pub fn plugin(app: &mut App) { } fn update_trail( - mut query: Query<(&mut Trail, &Gizmo, &GlobalTransform, &ChildOf)>, + mut query: Query<(Entity, &mut Trail, &Gizmo, &GlobalTransform)>, global_transform: Query<&GlobalTransform>, mut gizmo_assets: ResMut>, -) -> Result<(), BevyError> { - for (mut trail, gizmo, pos, parent) in query.iter_mut() { +) -> Result { + for (e, mut trail, gizmo, pos) in query.iter_mut() { trail.add(pos.translation()); - let parent_transform = global_transform.get(parent.parent())?; + let parent_transform = global_transform.get(e)?; let Some(gizmo) = gizmo_assets.get_mut(gizmo.handle.id()) else { continue; }; + gizmo.clear(); + let lerp_denom = trail.points.len() as f32; for (i, window) in trail.points.windows(2).enumerate() { let [a, b] = window else {