Perfect bullet going through colliders system now.

This commit is contained in:
Franklin 2023-11-11 13:00:55 -04:00
parent 901c30154b
commit 4e8bddfade
9 changed files with 467 additions and 276 deletions

553
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -15,8 +15,8 @@ opt-level = 3
opt-level = 3 opt-level = 3
[dependencies] [dependencies]
bevy = { version = "0.11", features = ["dynamic_linking"]} bevy = { version = "0.12", features = ["dynamic_linking"]}
bevy-inspector-egui = "0.20.0" bevy-inspector-egui = "0.21.0"
bevy_editor_pls = "0.5" bevy_editor_pls = "0.6"
bevy_rapier3d = { version = "0.22.0", features = ["debug-render-3d"] } bevy_rapier3d = { path = "../bevy_rapier/bevy_rapier3d", features = ["debug-render-3d"] }
bevy_hanabi = { version = "0.7", default-features = false, features = [ "3d" ] } bevy_hanabi = { version = "0.8", default-features = false, features = [ "3d" ] }

View File

@ -1,10 +1,11 @@
use bevy::{prelude::Component, reflect::Reflect}; use bevy::{prelude::{Component, Vec3}, reflect::Reflect, time::Timer};
use crate::logic::core::guns::caliber::Caliber; use crate::logic::core::guns::caliber::Caliber;
#[derive(Component, Reflect)] #[derive(Component, Reflect)]
pub struct BulletMarker { pub struct BulletMarker {
pub caliber: Caliber pub caliber: Caliber,
pub starting_point: Vec3,
pub timer: Timer,
} }

View File

@ -9,8 +9,44 @@ pub enum Caliber {
impl Caliber { impl Caliber {
pub fn range(&self) -> f32 { pub fn range(&self) -> f32 {
match self { match self {
Caliber::NATO556 => 750.0, Caliber::NATO556 => 7500.0,
Caliber::Parabellum9mm => 250.0, Caliber::Parabellum9mm => 2500.0,
}
}
pub fn max_airtime_secs(&self) -> f32 {
match self {
Caliber::NATO556 => 3.0,
Caliber::Parabellum9mm => 3.0,
}
}
pub fn impulse(&self) -> f32 {
match self {
Caliber::NATO556 => 100.0,
Caliber::Parabellum9mm => 50.0,
}
}
pub fn mass(&self) -> f32 {
match self {
Caliber::NATO556 => 0.1,
Caliber::Parabellum9mm => 0.05,
}
}
pub fn linear_damping(&self) -> f32 {
match self {
Caliber::NATO556 => 1.0,
Caliber::Parabellum9mm => 2.0,
}
}
pub fn angular_damping(&self) -> f32 {
match self {
Caliber::NATO556 => 1.0,
Caliber::Parabellum9mm => 1.0,
}
}
pub fn size(&self) -> f32 {
match self {
Caliber::NATO556 => 0.07,
Caliber::Parabellum9mm => 0.05,
} }
} }
} }

View File

@ -1,6 +1,6 @@
use bevy::prelude::*; use bevy::prelude::*;
use bevy_rapier3d::prelude::*;
use crate::comps::core::markers::muzzle_flash::MuzzleFlashMarker; use crate::comps::core::markers::{muzzle_flash::MuzzleFlashMarker, bullet::BulletMarker};
pub fn despawn_muzzle_flashes(mut commands: Commands, mut query: Query<(&mut MuzzleFlashMarker, Entity)>, time: Res<Time>) { pub fn despawn_muzzle_flashes(mut commands: Commands, mut query: Query<(&mut MuzzleFlashMarker, Entity)>, time: Res<Time>) {
for (mut muzzle_flash, entity) in query.iter_mut() { for (mut muzzle_flash, entity) in query.iter_mut() {
@ -10,3 +10,90 @@ pub fn despawn_muzzle_flashes(mut commands: Commands, mut query: Query<(&mut Muz
} }
} }
} }
pub fn despawn_stray_bullets(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
mut query: Query<(&mut BulletMarker, Entity, &Transform)>,
mut collisions: EventReader<CollisionEvent>,
time: Res<Time>,
) {
let collisions_read: Vec<&CollisionEvent> = collisions.read().collect();
for (mut bullet, bullet_entity, transform) in query.iter_mut() {
bullet.timer.tick(time.delta());
for event in collisions_read.iter() {
match event {
CollisionEvent::Started(entity_a, entity_b, _) => {
println!("AA");
if entity_a == entity_b { // Avoid inner collisions
continue;
}
if entity_a == &bullet_entity {
commands.entity(bullet_entity).remove::<Collider>();
//commands.entity(*entity_b).despawn();
spawn_bullet_hit_marker(&mut commands, transform.translation, &mut meshes, &mut materials);
continue;
}
else if entity_b == &bullet_entity {
commands.entity(bullet_entity).remove::<Collider>();
//commands.entity(*entity_a).despawn();
spawn_bullet_hit_marker(&mut commands, transform.translation, &mut meshes, &mut materials);
continue;
}
},
CollisionEvent::Stopped(entity_a, entity_b, _) => {
println!("AAB");
if entity_a == &bullet_entity {
commands.entity(bullet_entity).insert(Collider::ball(bullet.caliber.size()));
//commands.entity(*entity_b).despawn();
//spawn_bullet_hit_marker(&mut commands, transform.translation, &mut meshes, &mut materials);
continue;
}
else if entity_b == &bullet_entity {
commands.entity(bullet_entity).insert(Collider::ball(bullet.caliber.size()));
//commands.entity(*entity_a).despawn();
//spawn_bullet_hit_marker(&mut commands, transform.translation, &mut meshes, &mut materials);
continue;
}
}
_ => {}
}
}
if bullet.timer.finished() {
commands.entity(bullet_entity).despawn();
}
if transform.translation.distance(bullet.starting_point) > bullet.caliber.range() {
commands.entity(bullet_entity).despawn();
}
}
}
fn spawn_bullet_hit_marker(
commands: &mut Commands,
at: Vec3,
meshes: &mut ResMut<Assets<Mesh>>,
materials: &mut ResMut<Assets<StandardMaterial>>,
) {
commands.spawn(
(
MaterialMeshBundle {
mesh: {
meshes.add(
shape::UVSphere { radius: 0.05, sectors: 36, stacks: 18 }.into()
)
},
material: materials.add(StandardMaterial {
base_color: Color::BLUE,
//base_color_texture: Some(Color::GREEN),
emissive: Color::GREEN,
..Default::default()
}),
visibility: Visibility::Visible,
transform: Transform::from_translation(at),
..Default::default()
},
)
);
}

View File

@ -1,6 +1,6 @@
use std::time::Duration; use std::time::Duration;
use bevy::{prelude::*, render::render_resource::PrimitiveTopology}; use bevy::prelude::*;
use bevy_rapier3d::prelude::*; use bevy_rapier3d::prelude::*;
use crate::comps::core::markers::{muzzle_flash::MuzzleFlashMarker, bullet::BulletMarker}; use crate::comps::core::markers::{muzzle_flash::MuzzleFlashMarker, bullet::BulletMarker};
@ -32,7 +32,8 @@ pub fn shoot_bullet(
..Default::default() ..Default::default()
}, MuzzleFlashMarker(Timer::new(Duration::from_millis(10), TimerMode::Once))) }, MuzzleFlashMarker(Timer::new(Duration::from_millis(10), TimerMode::Once)))
); );
commands.spawn( // Spawn Line
/*commands.spawn(
MaterialMeshBundle { MaterialMeshBundle {
mesh: { mesh: {
let mut mesh = Mesh::new(PrimitiveTopology::LineStrip); let mut mesh = Mesh::new(PrimitiveTopology::LineStrip);
@ -47,7 +48,7 @@ pub fn shoot_bullet(
transform: firing_point, transform: firing_point,
..Default::default() ..Default::default()
} }
); );*/
spawn_bullet(commands, meshes, materials, firing_point, forward, up, caliber); spawn_bullet(commands, meshes, materials, firing_point, forward, up, caliber);
} }
@ -58,23 +59,25 @@ pub fn spawn_bullet(
materials: &mut ResMut<Assets<StandardMaterial>>, materials: &mut ResMut<Assets<StandardMaterial>>,
firing_point: Transform, firing_point: Transform,
forward: Vec3, forward: Vec3,
up: Vec3, _up: Vec3,
caliber: Caliber caliber: Caliber
) { ) {
commands.spawn( commands.spawn(
( (
Name::new("Bullet"), Name::new("Bullet"),
BulletMarker { BulletMarker {
caliber caliber: caliber.clone(),
starting_point: firing_point.translation,
timer: Timer::new(Duration::from_secs_f32(caliber.max_airtime_secs()), TimerMode::Once)
}, },
MaterialMeshBundle { MaterialMeshBundle {
mesh: { mesh: {
meshes.add( meshes.add(
shape::UVSphere { radius: 0.2, sectors: 36, stacks: 18 }.into() shape::UVSphere { radius: caliber.size(), sectors: 36, stacks: 18 }.into()
) )
}, },
material: materials.add(StandardMaterial { material: materials.add(StandardMaterial {
base_color: Color::GREEN, base_color: Color::Rgba { red: 253., green: 207., blue: 88., alpha: 1.0 },
..Default::default() ..Default::default()
}), }),
visibility: Visibility::Visible, visibility: Visibility::Visible,
@ -82,18 +85,20 @@ pub fn spawn_bullet(
..Default::default() ..Default::default()
}, },
RigidBody::Dynamic, RigidBody::Dynamic,
GravityScale(1.0), GravityScale(4.0),
Collider::ball(0.2), Collider::ball(caliber.size()),
Velocity::zero(), Velocity::zero(),
Damping { Damping {
linear_damping: 1.0, linear_damping: caliber.linear_damping(),
angular_damping: 1.0, angular_damping: caliber.angular_damping(),
}, },
ColliderMassProperties::Mass(0.001), ColliderMassProperties::Mass(caliber.mass()),
ExternalImpulse { ExternalImpulse {
impulse: forward * 0.1 , impulse: forward * caliber.impulse(),
torque_impulse: Vec3::ZERO, torque_impulse: Vec3::ZERO,
}, },
ActiveEvents::COLLISION_EVENTS,
Ccd::enabled()
) )
); );
} }

View File

@ -8,7 +8,7 @@ use crate::{
}, },
hands::capture_hand_usage, hands::capture_hand_usage,
player_vertical_sync::sync_player_y_state, player_values_state::PlayerValuesState, player_vertical_sync::sync_player_y_state, player_values_state::PlayerValuesState,
}, guns::despawn_shots::despawn_muzzle_flashes}, setup::{assets::load_all_assets, load_state::GameLoadState, spawn::add_all_spawners, animations::{load_animations, AllFirearmAnimations}, equipment::{EquipmentChangeEvent, change_equipment}, spawners::player::player_spawner}, }, guns::despawn_shots::{despawn_muzzle_flashes, despawn_stray_bullets}}, setup::{assets::load_all_assets, load_state::GameLoadState, spawn::add_all_spawners, animations::{load_animations, AllFirearmAnimations}, equipment::{EquipmentChangeEvent, change_equipment}, spawners::player::player_spawner},
}; };
use super::{ use super::{
@ -38,7 +38,8 @@ pub fn load_scene(application: &mut App) {
application.add_systems(Update, capture_hand_usage); application.add_systems(Update, capture_hand_usage);
application.add_systems(Update, change_equipment.before(player_spawner)); application.add_systems(Update, change_equipment.before(player_spawner));
application.add_systems(Update, despawn_muzzle_flashes); application.add_systems(Update, (despawn_muzzle_flashes, despawn_stray_bullets));
//application.add_systems(Update, register_bullet_hits);
application.add_event::<EquipmentChangeEvent>(); application.add_event::<EquipmentChangeEvent>();
} }

View File

@ -27,7 +27,7 @@ pub fn set_skybox_if_loaded(
mut cubemap: ResMut<Cubemap>, mut cubemap: ResMut<Cubemap>,
mut camera_query: Query<Entity, With<MainCamera>>, mut camera_query: Query<Entity, With<MainCamera>>,
) { ) {
if !cubemap.is_loaded && asset_server.get_load_state(&cubemap.image_handle) == LoadState::Loaded if !cubemap.is_loaded && asset_server.get_load_state(&cubemap.image_handle) == Some(LoadState::Loaded)
{ {
let image = images.get_mut(&cubemap.image_handle).unwrap(); let image = images.get_mut(&cubemap.image_handle).unwrap();
// NOTE: PNGs do not have any metadata that could indicate they contain a cubemap texture, // NOTE: PNGs do not have any metadata that could indicate they contain a cubemap texture,

View File

@ -24,7 +24,7 @@ pub fn change_equipment(
assets_gltf: Res<GltfAssets>, assets_gltf: Res<GltfAssets>,
loaded_gltf_assets: Res<Assets<Gltf>>, loaded_gltf_assets: Res<Assets<Gltf>>,
) { ) {
for equipment_change_event in equipment_change_event_reader.iter() { for equipment_change_event in equipment_change_event_reader.read() {
// TODO: Equipment change // TODO: Equipment change
let Ok((mut player, player_firing_info)) = player_query.get_single_mut() else { let Ok((mut player, player_firing_info)) = player_query.get_single_mut() else {
return; return;
@ -86,7 +86,7 @@ fn spawn_firearm_on_player_hands(
VisibilityBundle { VisibilityBundle {
visibility: Visibility::Inherited, visibility: Visibility::Inherited,
..Default::default() ..Default::default()
} },
)).push_children(&[firearm_asset_entity]) )).push_children(&[firearm_asset_entity])
.id(); .id();