Weapon system close to reality. All attachments except optics are good. Weapon collider now becomes a sensor when equipped and a non-sensor when dropped
This commit is contained in:
parent
f4102db009
commit
4ce5aa4219
Binary file not shown.
@ -92,8 +92,7 @@ pub fn drop_slot_in_game_world(
|
|||||||
) {
|
) {
|
||||||
let drop_position = Transform::from_translation(
|
let drop_position = Transform::from_translation(
|
||||||
player_transform.translation
|
player_transform.translation
|
||||||
+ player_transform.up() * 3.0
|
+ player_transform.up() * 5.0
|
||||||
+ player_transform.forward() * 2.0,
|
|
||||||
);
|
);
|
||||||
let drop_impulse = player_transform.translation
|
let drop_impulse = player_transform.translation
|
||||||
+ player_transform.up() * 100.0
|
+ player_transform.up() * 100.0
|
||||||
|
@ -2,7 +2,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use bevy::{prelude::*, gltf::Gltf};
|
use bevy::{prelude::*, gltf::Gltf};
|
||||||
use bevy_inspector_egui::egui::mutex::Mutex;
|
use bevy_inspector_egui::egui::mutex::Mutex;
|
||||||
use bevy_rapier3d::{dynamics::{RigidBody, GravityScale, ExternalImpulse}, geometry::{ColliderMassProperties, Collider}};
|
use bevy_rapier3d::{dynamics::{RigidBody, GravityScale, ExternalImpulse}, geometry::ColliderMassProperties};
|
||||||
|
|
||||||
use crate::{comps::core::{
|
use crate::{comps::core::{
|
||||||
grid::UGrid,
|
grid::UGrid,
|
||||||
@ -105,7 +105,6 @@ impl Item for Ak105GunItem {
|
|||||||
if let Some(initial_attachments) = &self.initial_attachments {
|
if let Some(initial_attachments) = &self.initial_attachments {
|
||||||
commands.entity(firearm_asset_entity).insert(initial_attachments.clone());
|
commands.entity(firearm_asset_entity).insert(initial_attachments.clone());
|
||||||
}
|
}
|
||||||
let firearm_size = firearm.get_size();
|
|
||||||
commands
|
commands
|
||||||
.spawn((
|
.spawn((
|
||||||
firearm.holdable_object_data(),
|
firearm.holdable_object_data(),
|
||||||
@ -121,11 +120,6 @@ impl Item for Ak105GunItem {
|
|||||||
RigidBody::Dynamic,
|
RigidBody::Dynamic,
|
||||||
ColliderMassProperties::Mass(5.0),
|
ColliderMassProperties::Mass(5.0),
|
||||||
GravityScale(4.0),
|
GravityScale(4.0),
|
||||||
Collider::cuboid(
|
|
||||||
firearm_size.x,
|
|
||||||
firearm_size.y,
|
|
||||||
firearm_size.z,
|
|
||||||
),
|
|
||||||
ExternalImpulse {
|
ExternalImpulse {
|
||||||
impulse: with_impulse,
|
impulse: with_impulse,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -2,7 +2,7 @@ use bevy::app::{Plugin, Update};
|
|||||||
|
|
||||||
use crate::{setup::load_state::update_game_load_state, comps::core::weapons::{firearm::Firearm, attachments::{weapon_attachment::WeaponAttachment, optic::Optic, stock::Stock, compensator::Compensator, magazine::Magazine, foregrip::ForeGrip}, parts::{charging_handle::ChargingHandle, fire_selector::FireSelector, firing_point::FiringPoint, trigger::Trigger}, slot::{compensator_slot::CompensatorSlot, fore_grip_slot::ForeGripSlot, magazine_slot::MagazineSlot, sight_placement_start_slot::SightPlacementStartSlot, sight_placement_end_slot::SightPlacementEndSlot, stock_slot::StockSlot, utility_slot::UtilitySlot, slot::WeaponSlot}}};
|
use crate::{setup::load_state::update_game_load_state, comps::core::weapons::{firearm::Firearm, attachments::{weapon_attachment::WeaponAttachment, optic::Optic, stock::Stock, compensator::Compensator, magazine::Magazine, foregrip::ForeGrip}, parts::{charging_handle::ChargingHandle, fire_selector::FireSelector, firing_point::FiringPoint, trigger::Trigger}, slot::{compensator_slot::CompensatorSlot, fore_grip_slot::ForeGripSlot, magazine_slot::MagazineSlot, sight_placement_start_slot::SightPlacementStartSlot, sight_placement_end_slot::SightPlacementEndSlot, stock_slot::StockSlot, utility_slot::UtilitySlot, slot::WeaponSlot}}};
|
||||||
|
|
||||||
use super::{character::{player_hitbox::PlayerHitBox, player_character::PlayerCharacter, player_eye::{PlayerEye, insert_components_into_spawned_player}, in_player_hands_parent::{InPlayerHandsParent, insert_components_into_player_hand}, third_person_camera::ThirdPersonCameraProxy}, physics::{rapier::{AutoAABBCollider, physics_replace_proxies}, self}, weapons::firearm::insert_firearm_state_to_firearms};
|
use super::{character::{player_hitbox::PlayerHitBox, player_character::PlayerCharacter, player_eye::{PlayerEye, insert_components_into_spawned_player}, in_player_hands_parent::{InPlayerHandsParent, insert_components_into_player_hand}, third_person_camera::ThirdPersonCameraProxy}, physics::{rapier::{AutoAABBCollider, physics_replace_proxies}, self}, weapons::{firearm::insert_firearm_state_to_firearms, gun_colliders::{GunFirearmCollider, update_gun_collider}}};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -22,6 +22,7 @@ impl Plugin for ProxyComponentsPlugin {
|
|||||||
|
|
||||||
// Firearms
|
// Firearms
|
||||||
app.register_type::<Firearm>();
|
app.register_type::<Firearm>();
|
||||||
|
app.register_type::<GunFirearmCollider>();
|
||||||
|
|
||||||
// Attachments
|
// Attachments
|
||||||
app.register_type::<WeaponAttachment>();
|
app.register_type::<WeaponAttachment>();
|
||||||
@ -56,5 +57,6 @@ impl Plugin for ProxyComponentsPlugin {
|
|||||||
app.add_systems(Update, insert_components_into_spawned_player);
|
app.add_systems(Update, insert_components_into_spawned_player);
|
||||||
app.add_systems(Update, insert_components_into_player_hand);
|
app.add_systems(Update, insert_components_into_player_hand);
|
||||||
app.add_systems(Update, insert_firearm_state_to_firearms);
|
app.add_systems(Update, insert_firearm_state_to_firearms);
|
||||||
|
app.add_systems(Update, update_gun_collider);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,7 +12,6 @@ pub struct InsertFirearmStateIntoFirearmsParams<'w, 's> {
|
|||||||
attachments_query: Query<'w, 's, (Entity, &'static WeaponAttachment, &'static Parent)>,
|
attachments_query: Query<'w, 's, (Entity, &'static WeaponAttachment, &'static Parent)>,
|
||||||
in_player_hands_query: Query<'w, 's, &'static ItemId, With<InPlayerHands>>,
|
in_player_hands_query: Query<'w, 's, &'static ItemId, With<InPlayerHands>>,
|
||||||
player_inventories_query: Query<'w, 's, &'static PlayerInventory>,
|
player_inventories_query: Query<'w, 's, &'static PlayerInventory>,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This query inserts FirearmState into firearms, updates firearm assets that already have a FirearmState,
|
/// This query inserts FirearmState into firearms, updates firearm assets that already have a FirearmState,
|
||||||
|
37
src/comps/core/markers/proxy/weapons/gun_colliders.rs
Normal file
37
src/comps/core/markers/proxy/weapons/gun_colliders.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy_rapier3d::geometry::Sensor;
|
||||||
|
|
||||||
|
use crate::{comps::core::markers::holdable::InPlayerHands, utils::hierarchy::find_child_in_parent_children};
|
||||||
|
|
||||||
|
|
||||||
|
/// This marker is to find the gun's collider that should be a sensor when equipped and a non-sensor when on the ground
|
||||||
|
#[derive(Component, Clone, Reflect, Default, Debug)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct GunFirearmCollider;
|
||||||
|
|
||||||
|
|
||||||
|
/*for (gun_firearm_collider_entity, _) in gun_firearm_collider_query.iter() {
|
||||||
|
println!("a");
|
||||||
|
if find_child_in_parent_children(commands, firearm_asset_entity, gun_firearm_collider_entity, &children) {
|
||||||
|
println!("Sensor");
|
||||||
|
commands.entity(gun_firearm_collider_entity).insert(Sensor);
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
pub fn update_gun_collider(
|
||||||
|
mut commands: Commands,
|
||||||
|
gun_firearm_collider_query: Query<Entity, Added<GunFirearmCollider>>,
|
||||||
|
in_player_hands_query: Query<Entity, Added<InPlayerHands>>,
|
||||||
|
children: Query<&Children>,
|
||||||
|
) {
|
||||||
|
for gun_firearm_collider_entity in gun_firearm_collider_query.iter() {
|
||||||
|
let mut found = false;
|
||||||
|
for in_player_hands_entity in in_player_hands_query.iter() {
|
||||||
|
if find_child_in_parent_children(&mut commands, in_player_hands_entity, gun_firearm_collider_entity, &children) {
|
||||||
|
commands.entity(gun_firearm_collider_entity).insert(Sensor);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if found { continue; }
|
||||||
|
commands.entity(gun_firearm_collider_entity).remove::<Sensor>();
|
||||||
|
}
|
||||||
|
}
|
@ -1,2 +1,3 @@
|
|||||||
pub mod firearm;
|
pub mod firearm;
|
||||||
pub mod initial_attachments;
|
pub mod initial_attachments;
|
||||||
|
pub mod gun_colliders;
|
9
src/comps/core/weapons/attachments/attachment.rs
Normal file
9
src/comps/core/weapons/attachments/attachment.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
/// Trait that will contain all the SHARED properties in between all attachments
|
||||||
|
/// - Recoil reduction Vert and Horizontal
|
||||||
|
/// - Aim Speed
|
||||||
|
/// -
|
||||||
|
pub trait Attachment {
|
||||||
|
|
||||||
|
}
|
@ -3,4 +3,6 @@ pub mod optic;
|
|||||||
pub mod magazine;
|
pub mod magazine;
|
||||||
pub mod compensator;
|
pub mod compensator;
|
||||||
pub mod stock;
|
pub mod stock;
|
||||||
pub mod foregrip;
|
pub mod foregrip;
|
||||||
|
pub mod silencer;
|
||||||
|
pub mod attachment;
|
9
src/comps/core/weapons/attachments/silencer.rs
Normal file
9
src/comps/core/weapons/attachments/silencer.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
use bevy::{reflect::{Reflect, std_traits::ReflectDefault}, ecs::{component::Component, reflect::ReflectComponent}};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Reflect, Component, Debug, Default)]
|
||||||
|
#[reflect(Component, Default)]
|
||||||
|
pub enum Silencer {
|
||||||
|
#[default]
|
||||||
|
FirstSilencer
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
use crate::comps::core::markers::{bullet::BulletMarker, muzzle_flash::MuzzleFlashMarker};
|
use crate::comps::core::markers::{bullet::BulletMarker, muzzle_flash::MuzzleFlashMarker};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_rapier3d::prelude::*;
|
use bevy_rapier3d::{prelude::*, rapier::geometry::CollisionEventFlags};
|
||||||
|
|
||||||
pub fn despawn_muzzle_flashes(
|
pub fn despawn_muzzle_flashes(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
@ -20,6 +20,7 @@ pub fn despawn_stray_bullets(
|
|||||||
mut meshes: ResMut<Assets<Mesh>>,
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||||
mut query: Query<(&mut BulletMarker, Entity, &Transform)>,
|
mut query: Query<(&mut BulletMarker, Entity, &Transform)>,
|
||||||
|
|
||||||
mut collisions: EventReader<CollisionEvent>,
|
mut collisions: EventReader<CollisionEvent>,
|
||||||
//res: Res<IntegrationParameters>,
|
//res: Res<IntegrationParameters>,
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
@ -29,7 +30,10 @@ pub fn despawn_stray_bullets(
|
|||||||
bullet.timer.tick(time.delta());
|
bullet.timer.tick(time.delta());
|
||||||
for event in collisions_read.iter() {
|
for event in collisions_read.iter() {
|
||||||
match event {
|
match event {
|
||||||
CollisionEvent::Started(entity_a, entity_b, _) => {
|
CollisionEvent::Started(entity_a, entity_b, flags) => {
|
||||||
|
if flags.contains(CollisionEventFlags::SENSOR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if entity_a == entity_b {
|
if entity_a == entity_b {
|
||||||
// Avoid inner collisions
|
// Avoid inner collisions
|
||||||
continue;
|
continue;
|
||||||
@ -45,7 +49,10 @@ pub fn despawn_stray_bullets(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CollisionEvent::Stopped(entity_a, entity_b, _) => {
|
CollisionEvent::Stopped(entity_a, entity_b, flags) => {
|
||||||
|
if flags.contains(CollisionEventFlags::SENSOR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if entity_a == entity_b {
|
if entity_a == entity_b {
|
||||||
// Avoid inner collisions
|
// Avoid inner collisions
|
||||||
continue;
|
continue;
|
||||||
|
@ -2,14 +2,19 @@ use bevy::prelude::*;
|
|||||||
|
|
||||||
use crate::comps::core::markers::{camera::MainCamera, proxy::character::third_person_camera::ThirdPersonCamera};
|
use crate::comps::core::markers::{camera::MainCamera, proxy::character::third_person_camera::ThirdPersonCamera};
|
||||||
|
|
||||||
|
use super::player_settings::PlayerSettings;
|
||||||
|
|
||||||
pub fn switch_camera(
|
pub fn switch_camera(
|
||||||
// mut commands: Commands,
|
// mut commands: Commands,
|
||||||
mut main_camera_query: Query<&mut Camera, With<MainCamera>>,
|
mut main_camera_query: Query<&mut Camera, With<MainCamera>>,
|
||||||
mut tpc_query: Query<&mut Camera, (With<ThirdPersonCamera>, Without<MainCamera>)>,
|
mut tpc_query: Query<&mut Camera, (With<ThirdPersonCamera>, Without<MainCamera>)>,
|
||||||
keyboard_input: Res<Input<KeyCode>>,
|
keyboard_input: Res<Input<KeyCode>>,
|
||||||
|
player_settings: Res<PlayerSettings>,
|
||||||
) {
|
) {
|
||||||
if keyboard_input.just_pressed(KeyCode::Key0) {
|
if !player_settings.third_person_toggle {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
if keyboard_input.just_pressed(KeyCode::Key0) {
|
||||||
for mut main_cam in main_camera_query.iter_mut() {
|
for mut main_cam in main_camera_query.iter_mut() {
|
||||||
main_cam.is_active = !main_cam.is_active;
|
main_cam.is_active = !main_cam.is_active;
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ pub fn capture_hand_usage(
|
|||||||
.full_auto_timer
|
.full_auto_timer
|
||||||
.tick(resources.time.delta());
|
.tick(resources.time.delta());
|
||||||
|
|
||||||
for (firearm_entity, firearm_transform, firearm, mut firearm_state) in
|
for (firearm_entity, _, firearm, mut firearm_state) in
|
||||||
queries.firearms_query.iter_mut()
|
queries.firearms_query.iter_mut()
|
||||||
{
|
{
|
||||||
for (mut hand_transform, hand_entity) in queries.hand_query.iter_mut() {
|
for (mut hand_transform, hand_entity) in queries.hand_query.iter_mut() {
|
||||||
@ -304,7 +304,7 @@ pub fn interact_action(
|
|||||||
QueryFilter::default().exclude_collider(player_collider_entity),
|
QueryFilter::default().exclude_collider(player_collider_entity),
|
||||||
) {
|
) {
|
||||||
for (interactable_entity, interactable) in query.interactables_query.iter() {
|
for (interactable_entity, interactable) in query.interactables_query.iter() {
|
||||||
if interactable_entity == entity {
|
if interactable_entity == entity || find_child_in_parent_children(&mut commands, interactable_entity, entity, &children) {
|
||||||
hud_state.interaction_clue_shown = true;
|
hud_state.interaction_clue_shown = true;
|
||||||
hud_state.interaction_clue_text = interactable.to_string();
|
hud_state.interaction_clue_text = interactable.to_string();
|
||||||
if keyboard_input.just_pressed(KeyCode::F) && !game_ui_state.any_window() {
|
if keyboard_input.just_pressed(KeyCode::F) && !game_ui_state.any_window() {
|
||||||
|
@ -31,7 +31,7 @@ fn setup_plugins(application: &mut App) {
|
|||||||
.add_plugins(DefaultPlugins.set(AssetPlugin::default()))
|
.add_plugins(DefaultPlugins.set(AssetPlugin::default()))
|
||||||
//.add_plugins(DefaultInspectorConfigPlugin)
|
//.add_plugins(DefaultInspectorConfigPlugin)
|
||||||
.add_plugins(RapierPhysicsPlugin::<NoUserData>::default())
|
.add_plugins(RapierPhysicsPlugin::<NoUserData>::default())
|
||||||
//.add_plugins(RapierDebugRenderPlugin::default())
|
.add_plugins(RapierDebugRenderPlugin::default())
|
||||||
.add_plugins(ComponentsFromGltfPlugin)
|
.add_plugins(ComponentsFromGltfPlugin)
|
||||||
//.add_plugins(bevy_egui::EguiPlugin)
|
//.add_plugins(bevy_egui::EguiPlugin)
|
||||||
//.add_plugins(WorldInspectorPlugin::new())
|
//.add_plugins(WorldInspectorPlugin::new())
|
||||||
|
@ -8,7 +8,7 @@ use crate::{
|
|||||||
player::Player, proxy::character::in_player_hands_parent::InPlayerHandsParent,
|
player::Player, proxy::character::in_player_hands_parent::InPlayerHandsParent,
|
||||||
}, weapons::{firearm::Firearm, firearm_data::FirearmData, firearm_state::FirearmState}, events::pickup_item::ItemState, items::item::ItemId},
|
}, weapons::{firearm::Firearm, firearm_data::FirearmData, firearm_state::FirearmState}, events::pickup_item::ItemState, items::item::ItemId},
|
||||||
logic::core::guns::player_firing::PlayerFiringInfo,
|
logic::core::guns::player_firing::PlayerFiringInfo,
|
||||||
utils,
|
utils::{self},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::assets::{GltfAssetType, GltfAssets};
|
use super::assets::{GltfAssetType, GltfAssets};
|
||||||
@ -44,6 +44,7 @@ pub fn change_equipment(
|
|||||||
commands.entity(player_hands).despawn_descendants(); // TODO: Don't do this without keeping the state from the last mag
|
commands.entity(player_hands).despawn_descendants(); // TODO: Don't do this without keeping the state from the last mag
|
||||||
|
|
||||||
if let Equipment::Firearm(new_firearm, firearm_state) = equipment_change_event.0.clone() {
|
if let Equipment::Firearm(new_firearm, firearm_state) = equipment_change_event.0.clone() {
|
||||||
|
// Add sensor to firearm collider if it is a child of player_hands
|
||||||
spawn_firearm_on_player_hands(
|
spawn_firearm_on_player_hands(
|
||||||
&mut commands,
|
&mut commands,
|
||||||
player_firing_info,
|
player_firing_info,
|
||||||
@ -52,7 +53,7 @@ pub fn change_equipment(
|
|||||||
&loaded_gltf_assets,
|
&loaded_gltf_assets,
|
||||||
new_firearm,
|
new_firearm,
|
||||||
firearm_state,
|
firearm_state,
|
||||||
equipment_change_event.1.clone().expect("Spawning firearm on player hands without an ItemId")
|
equipment_change_event.1.clone().expect("Spawning firearm on player hands without an ItemId"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user