Perfect bullet going through colliders system now.
This commit is contained in:
parent
901c30154b
commit
4e8bddfade
553
Cargo.lock
generated
553
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
10
Cargo.toml
10
Cargo.toml
@ -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" ] }
|
@ -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,
|
||||||
}
|
}
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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() {
|
||||||
@ -9,4 +9,91 @@ pub fn despawn_muzzle_flashes(mut commands: Commands, mut query: Query<(&mut Muz
|
|||||||
commands.entity(entity).despawn();
|
commands.entity(entity).despawn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
@ -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()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -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>();
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user