trails and better missile origin

This commit is contained in:
2025-04-30 00:02:45 +02:00
parent f6eb652fd2
commit 4b8cc8bb71
4 changed files with 68 additions and 30 deletions

View File

@@ -137,10 +137,11 @@ fn on_trigger_missile(
), ),
( (
Trail::new( Trail::new(
t.translation, 12,
LinearRgba::rgb(1., 0.0, 0.), LinearRgba::rgb(1., 0.0, 0.),
LinearRgba::rgb(0.9, 0.9, 0.) LinearRgba::rgb(0.9, 0.9, 0.)
), )
.with_pos(t.translation),
Gizmo { Gizmo {
handle: gizmo_assets.add(GizmoAsset::default()), handle: gizmo_assets.add(GizmoAsset::default()),
line_config: GizmoLineConfig { line_config: GizmoLineConfig {

View File

@@ -1,5 +1,9 @@
use crate::{GameState, heads_database::HeadsDatabase, loading_assets::GameAssets}; use crate::{
use bevy::{ecs::system::SystemParam, platform::collections::HashMap, prelude::*}; 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; use std::time::Duration;
#[derive(Component, Debug)] #[derive(Component, Debug)]
@@ -34,12 +38,12 @@ pub struct CharacterAnimations {
pub fn plugin(app: &mut App) { pub fn plugin(app: &mut App) {
app.add_systems( app.add_systems(
Update, 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")] #[cfg(feature = "dbg")]
app.add_systems( app.add_systems(
Update, Update,
debug_show_projectile_origin.run_if(in_state(GameState::Playing)), debug_show_projectile_origin_and_trial.run_if(in_state(GameState::Playing)),
); );
} }
@@ -63,28 +67,55 @@ fn spawn(
}); });
let asset = gltf_assets.get(handle).unwrap(); let asset = gltf_assets.get(handle).unwrap();
commands.entity(entity).insert(( commands
.entity(entity)
.insert((
Transform::from_translation(Vec3::new(0., -1.45, 0.)).with_scale(Vec3::splat(1.2)), Transform::from_translation(Vec3::new(0., -1.45, 0.)).with_scale(Vec3::splat(1.2)),
SceneRoot(asset.scenes[0].clone()), SceneRoot(asset.scenes[0].clone()),
))
.observe(find_marker_bones);
}
}
fn find_marker_bones(
trigger: Trigger<SceneInstanceReady>,
mut commands: Commands,
descendants: Query<&Children>,
name: Query<&Name>,
mut gizmo_assets: ResMut<Assets<GizmoAsset>>,
) {
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()
},
)); ));
} }
} }
fn setup_projectile_origin( if !origin_found {
mut commands: Commands, error!("ProjectileOrigin not found");
query: Query<Entity, Added<AnimationPlayer>>,
descendants: Query<&Children>,
name: Query<&Name>,
) {
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);
}
}
} }
} }
@@ -142,9 +173,9 @@ fn setup_once_loaded(
} }
#[cfg(feature = "dbg")] #[cfg(feature = "dbg")]
fn debug_show_projectile_origin( fn debug_show_projectile_origin_and_trial(
mut gizmos: Gizmos, mut gizmos: Gizmos,
query: Query<&GlobalTransform, With<ProjectileOrigin>>, query: Query<&GlobalTransform, Or<(With<ProjectileOrigin>, With<Trail>)>>,
) { ) {
for projectile_origin in query.iter() { for projectile_origin in query.iter() {
gizmos.sphere( gizmos.sphere(

View File

@@ -10,16 +10,20 @@ pub struct Trail {
} }
impl Trail { impl Trail {
pub fn new(pos: Vec3, col_start: LinearRgba, col_end: LinearRgba) -> Self { pub fn new(points: usize, col_start: LinearRgba, col_end: LinearRgba) -> Self {
let mut v = Vec::with_capacity(12);
v.push(pos);
Self { Self {
points: v, points: Vec::with_capacity(points),
col_start, col_start,
col_end, 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) { pub fn add(&mut self, pos: Vec3) {
if self.points.len() >= self.points.capacity() { if self.points.len() >= self.points.capacity() {
self.points.pop(); self.points.pop();
@@ -36,19 +40,21 @@ pub fn plugin(app: &mut App) {
} }
fn update_trail( fn update_trail(
mut query: Query<(&mut Trail, &Gizmo, &GlobalTransform, &ChildOf)>, mut query: Query<(Entity, &mut Trail, &Gizmo, &GlobalTransform)>,
global_transform: Query<&GlobalTransform>, global_transform: Query<&GlobalTransform>,
mut gizmo_assets: ResMut<Assets<GizmoAsset>>, mut gizmo_assets: ResMut<Assets<GizmoAsset>>,
) -> Result<(), BevyError> { ) -> Result {
for (mut trail, gizmo, pos, parent) in query.iter_mut() { for (e, mut trail, gizmo, pos) in query.iter_mut() {
trail.add(pos.translation()); 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 { let Some(gizmo) = gizmo_assets.get_mut(gizmo.handle.id()) else {
continue; continue;
}; };
gizmo.clear();
let lerp_denom = trail.points.len() as f32; let lerp_denom = trail.points.len() as f32;
for (i, window) in trail.points.windows(2).enumerate() { for (i, window) in trail.points.windows(2).enumerate() {
let [a, b] = window else { let [a, b] = window else {