support multiple thrown projectiles

This commit is contained in:
2025-04-08 10:51:46 +02:00
parent bf90ad8caf
commit ae8026588b
7 changed files with 50 additions and 30 deletions

View File

@@ -44,6 +44,7 @@ pub struct TriggerData {
rot: Quat,
pos: Vec3,
target_layer: GameLayer,
head: usize,
}
impl TriggerData {
@@ -53,6 +54,7 @@ impl TriggerData {
rot: Quat,
pos: Vec3,
target_layer: GameLayer,
head: usize,
) -> Self {
Self {
target,
@@ -60,6 +62,7 @@ impl TriggerData {
rot,
pos,
target_layer,
head,
}
}
}
@@ -135,6 +138,7 @@ fn on_trigger_state(
pos: transform.translation,
target: target.0,
target_layer: GameLayer::Npc,
head: state.head,
};
active_heads.use_ammo(time.elapsed_secs());

View File

@@ -15,7 +15,9 @@ use bevy_sprite3d::{Sprite3dBuilder, Sprite3dParams};
use std::f32::consts::PI;
#[derive(Component)]
struct ThrownProjectile;
struct ThrownProjectile {
impact_animation: bool,
}
#[derive(Component, Reflect)]
#[reflect(Component)]
@@ -113,10 +115,17 @@ fn on_trigger_thrown(
let t = Transform::from_translation(state.pos);
let (mesh, explosion_animation) = match state.head {
8 => (assets.hammer.clone(), false),
_ => (assets.molotov.clone(), true),
};
commands
.spawn((
Name::new("projectile-thrown"),
ThrownProjectile,
ThrownProjectile {
impact_animation: explosion_animation,
},
Collider::sphere(0.5),
CollisionLayers::new(
LayerMask(GameLayer::Projectile.to_bits()),
@@ -130,8 +139,7 @@ fn on_trigger_thrown(
))
.with_child((
AutoRotation(Quat::from_rotation_x(0.4) * Quat::from_rotation_z(0.3)),
Transform::from_scale(Vec3::splat(10.)),
SceneRoot(assets.molotov.clone()),
SceneRoot(mesh),
));
}
@@ -149,7 +157,10 @@ fn shot_collision(
let shot_entity = if query_shot.contains(*e1) { *e1 } else { *e2 };
let Ok(shot_pos) = query_shot.get(shot_entity).map(|(_, t)| t.translation) else {
let Ok((shot_pos, animation)) = query_shot
.get(shot_entity)
.map(|(projectile, t)| (t.translation, projectile.impact_animation))
else {
continue;
};
@@ -164,29 +175,32 @@ fn shot_collision(
radius: 5.,
});
commands
.spawn(
Sprite3dBuilder {
image: assets.image.clone(),
pixels_per_metre: 32.,
alpha_mode: AlphaMode::Blend,
unlit: true,
..default()
}
.bundle_with_atlas(
&mut sprite_params,
TextureAtlas {
layout: assets.layout.clone(),
index: 0,
},
),
)
.insert((
Billboard,
Transform::from_translation(shot_pos),
NotShadowCaster,
AnimationTimer::new(Timer::from_seconds(0.02, TimerMode::Repeating)),
));
//TODO: support different impact animations
if animation {
commands
.spawn(
Sprite3dBuilder {
image: assets.image.clone(),
pixels_per_metre: 32.,
alpha_mode: AlphaMode::Blend,
unlit: true,
..default()
}
.bundle_with_atlas(
&mut sprite_params,
TextureAtlas {
layout: assets.layout.clone(),
index: 0,
},
),
)
.insert((
Billboard,
Transform::from_translation(shot_pos),
NotShadowCaster,
AnimationTimer::new(Timer::from_seconds(0.02, TimerMode::Repeating)),
));
}
}
}