New bullet system #1
|
@ -47,7 +47,7 @@ Multiplayer
|
|||
- [ ] Gun Bob on walk
|
||||
- [ ] Reload animation (procedural)
|
||||
- [ ] Real world magazines
|
||||
- [ ] Rewriting bullet physics to use raycasts & kinematic rigidbodies (logic controlled)
|
||||
- [x] Rewriting bullet physics to use raycasts & kinematic rigidbodies (logic controlled)
|
||||
- [x] Create a Controls struct that holds mappings to all the game keys and replace them in all the game's code
|
||||
- [x] Gun dropping drops on only one side of player
|
||||
- [x] Gun dropping does not apply impulse for some reason...
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
use bevy::{
|
||||
prelude::{Component, Vec3},
|
||||
reflect::Reflect,
|
||||
time::Timer, ecs::reflect::ReflectComponent,
|
||||
time::Timer, ecs::{reflect::ReflectComponent, entity::Entity},
|
||||
};
|
||||
|
||||
use crate::comps::core::weapons::caliber::Caliber;
|
||||
|
||||
#[derive(PartialEq, Clone, Reflect)]
|
||||
pub struct BulletHit {
|
||||
pub entity: Entity,
|
||||
pub position: Vec3,
|
||||
}
|
||||
|
||||
#[derive(Component, Reflect, Default)]
|
||||
#[reflect(Component)]
|
||||
pub struct BulletMarker {
|
||||
|
@ -13,4 +19,5 @@ pub struct BulletMarker {
|
|||
pub starting_point: Vec3,
|
||||
pub timer: Timer,
|
||||
pub current_velocity: Vec3,
|
||||
pub hits: Vec<BulletHit>,
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ pub fn despawn_stray_bullets(
|
|||
}
|
||||
}
|
||||
|
||||
fn spawn_bullet_hit_marker(
|
||||
pub fn spawn_bullet_hit_marker(
|
||||
commands: &mut Commands,
|
||||
at: Vec3,
|
||||
meshes: &mut ResMut<Assets<Mesh>>,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use bevy::{prelude::*, render::render_resource::PrimitiveTopology};
|
||||
use bevy::prelude::*;
|
||||
use bevy_rapier3d::prelude::*;
|
||||
|
||||
use crate::{comps::core::{markers::{bullet::BulletMarker, muzzle_flash::MuzzleFlashMarker, collider_flags::ColliderFlags}, weapons::caliber::Caliber}, logic::core::player::player_settings::PlayerSettings};
|
||||
use crate::comps::core::{markers::{bullet::BulletMarker, muzzle_flash::MuzzleFlashMarker, collider_flags::ColliderFlags}, weapons::caliber::Caliber};
|
||||
|
||||
|
||||
pub fn shoot_bullet(
|
||||
|
@ -14,7 +14,6 @@ pub fn shoot_bullet(
|
|||
forward: Vec3,
|
||||
up: Vec3,
|
||||
caliber: Caliber,
|
||||
player_settings: &Res<PlayerSettings>
|
||||
) {
|
||||
// Spawn muzzle flash LIGHT
|
||||
commands.spawn((
|
||||
|
@ -40,7 +39,7 @@ pub fn shoot_bullet(
|
|||
));
|
||||
|
||||
// Spawn Line
|
||||
if player_settings.shot_lines_enabled {
|
||||
/*if player_settings.shot_lines_enabled {
|
||||
commands.spawn(
|
||||
MaterialMeshBundle {
|
||||
mesh: {
|
||||
|
@ -57,13 +56,15 @@ pub fn shoot_bullet(
|
|||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
}*/
|
||||
|
||||
spawn_bullet(
|
||||
commands,
|
||||
meshes,
|
||||
materials,
|
||||
firing_point,
|
||||
up,
|
||||
forward,
|
||||
caliber,
|
||||
);
|
||||
}
|
||||
|
@ -73,6 +74,8 @@ pub fn spawn_bullet(
|
|||
meshes: &mut ResMut<Assets<Mesh>>,
|
||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||
firing_point: Transform,
|
||||
_up: Vec3,
|
||||
forward: Vec3,
|
||||
caliber: Caliber,
|
||||
) {
|
||||
commands.spawn((
|
||||
|
@ -84,7 +87,8 @@ pub fn spawn_bullet(
|
|||
Duration::from_secs_f32(caliber.max_airtime_secs()),
|
||||
TimerMode::Once,
|
||||
),
|
||||
current_velocity: firing_point.forward() * caliber.muzzle_velocity(),
|
||||
current_velocity: forward * caliber.muzzle_velocity(),
|
||||
hits: Vec::new()
|
||||
},
|
||||
MaterialMeshBundle {
|
||||
mesh: {
|
||||
|
|
|
@ -1,17 +1,83 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy::{prelude::*, render::render_resource::PrimitiveTopology, ecs::system::SystemParam};
|
||||
use bevy_rapier3d::prelude::*;
|
||||
|
||||
use crate::comps::core::markers::bullet::BulletMarker;
|
||||
use crate::{comps::core::{markers::{bullet::{BulletMarker, BulletHit}, proxy::weapons::gun_colliders::GunFirearmCollider}, events::{bullet_collision::BulletCollisionEvent, collision_event_type::CollisionEventType}}, logic::core::player::player_settings::PlayerSettings};
|
||||
|
||||
#[derive(SystemParam)]
|
||||
pub struct UpdateBulletQueryParams<'w, 's> {
|
||||
bullets: Query<'w, 's, (Entity, &'static mut BulletMarker, &'static mut Transform)>,
|
||||
firearm_colliders: Query<'w, 's, Entity, With<GunFirearmCollider>>,
|
||||
}
|
||||
|
||||
pub fn update_bullet(
|
||||
mut commands: Commands,
|
||||
mut bullets: Query<(Entity, &mut BulletMarker, &mut Transform)>,
|
||||
time: Res<Time>,
|
||||
rapier_context: Res<RapierContext>,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
player_settings: Res<PlayerSettings>,
|
||||
mut query: UpdateBulletQueryParams,
|
||||
mut bullet_collision_event: EventWriter<BulletCollisionEvent>,
|
||||
) {
|
||||
for (bullet, mut marker, mut transform) in query.bullets.iter_mut() {
|
||||
let future_frame_pos = (marker.current_velocity * time.delta_seconds()) + (Vec3 { x: 0.0, y: -9.81, z: 0.0 } * time.delta_seconds() * marker.caliber.mass());
|
||||
|
||||
for (bullet, mut marker, mut transform) in bullets.iter_mut() {
|
||||
transform.translation += (marker.current_velocity * time.delta_seconds()) + (Vec3 { x: 0.0, y: -9.81, z: 0.0 } * time.delta_seconds() * marker.caliber.mass());
|
||||
let vel_shed = marker.caliber.velocity_shed();
|
||||
marker.current_velocity -= transform.forward() * vel_shed * time.delta_seconds();
|
||||
let max_toi = transform.translation.distance(future_frame_pos + transform.translation);
|
||||
|
||||
let mut query_filter = QueryFilter::default();
|
||||
for firearm_collider in query.firearm_colliders.iter() {
|
||||
query_filter = query_filter.exclude_collider(firearm_collider);
|
||||
}
|
||||
|
||||
if let Some(bullet_hit) = raycast_until_destination(&rapier_context, query_filter, transform.translation, future_frame_pos, max_toi) {
|
||||
if marker.hits.iter().find(|hit| hit.entity == bullet_hit.entity).is_none() {
|
||||
marker.hits.push(bullet_hit.clone());
|
||||
bullet_collision_event.send(BulletCollisionEvent { bullet, other: bullet_hit.entity, at: Transform::from_translation(bullet_hit.position), collision_type: CollisionEventType::Start })
|
||||
}
|
||||
}
|
||||
|
||||
if player_settings.shot_lines_enabled {
|
||||
commands.spawn(
|
||||
MaterialMeshBundle {
|
||||
mesh: {
|
||||
let mut mesh = Mesh::new(PrimitiveTopology::LineStrip);
|
||||
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, Vec::from([Vec3::ZERO, (future_frame_pos.normalize_or_zero() * max_toi)]));
|
||||
meshes.add(mesh)
|
||||
},
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::RED,
|
||||
emissive: Color::RED,
|
||||
..Default::default()
|
||||
}),
|
||||
visibility: Visibility::Visible,
|
||||
transform: *transform,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Raycast to future frame pos
|
||||
transform.translation += future_frame_pos;
|
||||
let vel_shed = marker.caliber.velocity_shed() * marker.current_velocity.normalize() * time.delta_seconds();
|
||||
marker.current_velocity -= vel_shed;
|
||||
}
|
||||
}
|
||||
|
||||
fn raycast_until_destination(
|
||||
rapier_context: &RapierContext,
|
||||
query_filter: QueryFilter<'_>,
|
||||
origin: Vec3,
|
||||
dir: Vec3,
|
||||
max_toi: f32,
|
||||
) -> Option<BulletHit> {
|
||||
if let Some((entity, toi)) = rapier_context.cast_ray(
|
||||
origin,
|
||||
dir,
|
||||
max_toi,
|
||||
true,
|
||||
query_filter,
|
||||
) {
|
||||
return Some(BulletHit { entity, position: origin + dir * toi });
|
||||
}
|
||||
None
|
||||
}
|
|
@ -266,7 +266,6 @@ pub fn capture_hand_usage(
|
|||
forward,
|
||||
up,
|
||||
firearm_data.caliber.clone(),
|
||||
&resources.player_settings
|
||||
);
|
||||
// Increment indexes and timers
|
||||
player_firing_info.current_round_index += 1;
|
||||
|
@ -336,7 +335,7 @@ pub fn interact_action(
|
|||
for player_entity in query.player_query.iter() {
|
||||
for global_transform in query.camera_query.iter() {
|
||||
let ray_pos = global_transform.translation();
|
||||
let ray_dir = global_transform.forward() * 2.0; // TODO: Move this into global Resource state
|
||||
let ray_dir = global_transform.forward() * 3.0; // TODO: Move this into global Resource state
|
||||
let max_toi = 4.0;
|
||||
let solid = true;
|
||||
|
||||
|
|
Loading…
Reference in New Issue