High ready + Low ready system. With animations and logic flows with sprinting, shooting, reloading, and aiming

This commit is contained in:
Franklin 2023-11-23 17:28:48 -04:00
parent 1a7a5e6024
commit 24df81424b
12 changed files with 145 additions and 36 deletions

View File

@ -23,12 +23,17 @@ Multiplayer
- [x] Snap back leaning too quick
- [x] Issue with moving around quickly
- [x] Bring Crouching back
- [ ] Inspect animation (procedural)
- [x] Inspect animation & state (procedural)
- [ ] Attachment editor system when in inspect mode
- [x] High Ready & Low Ready system with state
- [x] High ready animation (procedural)
- [x] Low ready animation (procedural)
- [ ] Reload animation (procedural)
- [ ] Real world magazines
- [ ] Rewriting bullet physics to use raycasts & kinematic rigidbodies (logic controlled)
- [ ] Low Ready & High ready (low ready == more speed | high ready == more accuracy)
- [ ] Auto Low ready when gun collider hits object OR when player starts sprinting
- [ ] Create a Controls struct that holds mappings to all the game keys and replace them in all the game's code
# Design

Binary file not shown.

View File

@ -2,12 +2,12 @@ use bevy::prelude::*;
use bevy_rapier3d::prelude::*;
use crate::{
logic::core::player::{
logic::core::{player::{
player_movement::{
move_player, PlayerLinearXZState, PlayerLinearYState, PlayerMovementInput,
},
player_values_state::PlayerValuesState,
},
}, guns::player_firing::PlayerFiringInfo},
ui::game::game_ui_state::GameUiState,
};
@ -24,6 +24,7 @@ pub fn capture_input(
&mut PlayerLinearXZState,
&mut Transform,
&mut Damping,
&mut PlayerFiringInfo,
),
With<Player>,
>,

View File

@ -0,0 +1,31 @@
use bevy::prelude::*;
use crate::comps::core::markers::{proxy::{character::in_player_hands_parent::InPlayerHandsParent, physics::utils::TransformExt}, player::Player};
use super::player_firing::PlayerFiringInfo;
pub fn inspect_firearm(
//mut commands: Commands,
mut in_player_hands_parent_query: Query<&mut Transform, With<InPlayerHandsParent>>,
mut player_firing_info_query: Query<&mut PlayerFiringInfo, With<Player>>,
time: Res<Time>,
keyboard_input: Res<Input<KeyCode>>,
) {
for mut player_firing_info in player_firing_info_query.iter_mut() {
for mut in_player_hands_parent_transform in in_player_hands_parent_query.iter_mut() {
if player_firing_info.is_inspecting {
let inspect_hand_transform: Transform = Transform {
translation: Vec3 { x: 0.0, y: -0.1, z: -0.8 },
rotation: Quat::from_euler(EulerRot::XYZ, -2.6, -1.0, -2.5),
..Default::default()
};
*in_player_hands_parent_transform = in_player_hands_parent_transform.lerp(inspect_hand_transform, time.delta_seconds() / 0.5);
if keyboard_input.just_pressed(KeyCode::Return) {
player_firing_info.is_inspecting = false;
}
}
}
}
}

View File

@ -1,3 +1,4 @@
pub mod despawn_shots;
pub mod player_firing;
pub mod shoot;
pub mod inspect;

View File

@ -2,6 +2,13 @@ use std::time::Duration;
use bevy::prelude::*;
#[derive(Reflect, Default, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum GunReadyPose {
#[default]
LowReady,
HighReady,
}
#[derive(Component, Reflect)]
#[reflect(Component)]
pub struct PlayerFiringInfo {
@ -15,6 +22,8 @@ pub struct PlayerFiringInfo {
pub current_round_index: usize,
pub full_auto_timer: Timer,
pub is_reloading: bool,
pub gun_ready_pose: GunReadyPose,
pub is_inspecting: bool,
}
impl Default for PlayerFiringInfo {
@ -25,6 +34,8 @@ impl Default for PlayerFiringInfo {
current_round_index: Default::default(),
full_auto_timer: Timer::new(Duration::from_secs_f32(0.0), TimerMode::Repeating),
is_reloading: false,
gun_ready_pose: GunReadyPose::LowReady,
is_inspecting: false,
}
}
}

View File

@ -38,24 +38,26 @@ pub fn shoot_bullet(
},
MuzzleFlashMarker(Timer::new(Duration::from_millis(10), TimerMode::Once)),
));
// Spawn Line
commands.spawn(
MaterialMeshBundle {
mesh: {
let mut mesh = Mesh::new(PrimitiveTopology::LineStrip);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, Vec::from([Vec3::ZERO, forward * caliber.range()]));
meshes.add(mesh)
},
material: materials.add(StandardMaterial {
base_color: Color::GREEN,
// Spawn Line
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, forward * caliber.range()]));
meshes.add(mesh)
},
material: materials.add(StandardMaterial {
base_color: Color::GREEN,
..Default::default()
}),
visibility: Visibility::Visible,
transform: firing_point,
..Default::default()
}),
visibility: Visibility::Visible,
transform: firing_point,
..Default::default()
}
);
}
);
}
spawn_bullet(
commands,

View File

@ -1,4 +1,4 @@
use bevy::{ecs::system::SystemParam, prelude::*, gltf::Gltf};
use bevy::{ecs::system::SystemParam, prelude::*, gltf::Gltf, input::mouse::MouseWheel};
use bevy_rapier3d::prelude::*;
use crate::{
@ -9,10 +9,10 @@ use crate::{
camera::MainCamera,
holdable::InPlayerHands,
interactable::Interactable,
player::Player, proxy::{character::in_player_hands_parent::InPlayerHandsParent, physics::rapier::LinkToPlayer},
player::Player, proxy::{character::in_player_hands_parent::InPlayerHandsParent, physics::{rapier::LinkToPlayer, utils::TransformExt}},
}, weapons::{firearm::Firearm, firearm_state::FirearmState, parts::firing_point::FiringPoint},
},
logic::core::guns::{player_firing::PlayerFiringInfo, shoot::shoot_bullet},
logic::core::guns::{player_firing::{PlayerFiringInfo, GunReadyPose}, shoot::shoot_bullet},
setup::{
equipment::{Equipment, EquipmentChangeEvent},
load_state::GameLoadState, assets::GltfAssets, //animations::AllAnimations,
@ -21,7 +21,7 @@ use crate::{
utils::{rad_deg::radians_from_degrees, hierarchy::find_child_in_parent_children},
};
use super::player_settings::PlayerSettings;
use super::{player_settings::PlayerSettings, player_movement::PlayerLinearXZState};
#[derive(SystemParam)]
pub struct CaptureHandUsageResourcesParams<'w> {
@ -45,7 +45,7 @@ pub struct CaptureHandUsageQueryParams<'w, 's> {
in_hand_query: Query<'w, 's, (&'static Parent, &'static mut Transform), (With<InPlayerHands>, Without<InPlayerHandsParent>, Without<PlayerInventory>)>,
firearms_query: Query<'w, 's, (Entity, &'static GlobalTransform, &'static Firearm, &'static mut FirearmState),>,
firing_point_query: Query<'w, 's, (&'static GlobalTransform, &'static Parent), With<FiringPoint>>,
player_query: Query<'w, 's, (&'static Player, &'static mut PlayerInventory, Entity, &'static Transform, &'static mut PlayerFiringInfo), Without<InPlayerHands>>,
player_query: Query<'w, 's, (&'static Player, &'static mut PlayerInventory, Entity, &'static Transform, &'static mut PlayerFiringInfo, &'static PlayerLinearXZState), Without<InPlayerHands>>,
children: Query<'w, 's, &'static Children>,
}
@ -58,6 +58,7 @@ pub fn capture_hand_usage(
mut equipment_change_event_writer: EventWriter<EquipmentChangeEvent>,
mut inventory_changed_events: EventWriter<PlayerInventoryChangedEvent>,
mut mouse_wheel_events: EventReader<MouseWheel>,
) {
if !resources.game_load_state.player_loaded {
return;
@ -65,9 +66,32 @@ pub fn capture_hand_usage(
// Equipping stuff
for (player, mut player_inventory, player_entity, player_transform, mut player_firing_info) in queries.player_query.iter_mut() {
for (player, mut player_inventory, player_entity, player_transform, mut player_firing_info, player_linear_xz_state) in queries.player_query.iter_mut() {
// Equipping gun
// Validate player has primary item, and secondary item in inventory
if player_firing_info.is_inspecting {
continue;
}
for (mut hand_transform, _) in queries.hand_query.iter_mut() {
let default_hand_transform: Transform = match player_firing_info.gun_ready_pose {
GunReadyPose::LowReady => {
Transform {
translation: Vec3 { x: -0.2, y: -0.3, z: -0.8 },
rotation: Quat::from_euler(EulerRot::XYZ, -3.6, -0.6, -3.3),
..Default::default()
}
},
GunReadyPose::HighReady => {
Transform {
translation: Vec3 { x: 0.039, y: -0.193, z: -0.453 },
rotation: Quat::from_euler(EulerRot::XYZ, -180.0f32.to_radians(), 0.0, -180.0f32.to_radians()),
..Default::default()
}
},
};
*hand_transform = hand_transform.lerp(default_hand_transform, resources.time.delta_seconds() / 0.25);
}
if !resources.game_ui_state.any_window() && !player_firing_info.is_reloading {
if resources.keyboard_input.just_pressed(KeyCode::Key1) {
if let Some(primary_item) = player_inventory.get_primary() {
@ -113,6 +137,20 @@ pub fn capture_hand_usage(
},
None => {},
}
} else if resources.keyboard_input.just_pressed(KeyCode::I) {
if player.0.equipment.is_firearm() {
player_firing_info.is_inspecting = true;
}
} else if !mouse_wheel_events.is_empty() {
if player.0.equipment.is_firearm() {
for mouse_wheel_event in mouse_wheel_events.read() {
if mouse_wheel_event.y >= 0.0 {
player_firing_info.gun_ready_pose = GunReadyPose::HighReady;
} else {
player_firing_info.gun_ready_pose = GunReadyPose::LowReady;
}
}
}
}
}
@ -158,8 +196,9 @@ pub fn capture_hand_usage(
}
};
if resources.mouse_buttons.pressed(MouseButton::Right)
&& !resources.game_ui_state.any_window()
&& !resources.game_ui_state.any_window() && !player_linear_xz_state.is_sprinting()
{
player_firing_info.gun_ready_pose = GunReadyPose::HighReady;
let rotation_lerp_quat = in_hand_transform.rotation.lerp(
firearm_data.final_aimed_rotation + resources.player_settings.rot_aimed_offset,
(resources.time.delta_seconds()
@ -191,7 +230,7 @@ pub fn capture_hand_usage(
// SHOOTING & RECOIL
if resources.mouse_buttons.pressed(MouseButton::Left)
&& !resources.game_ui_state.any_window()
&& !resources.game_ui_state.any_window() && player_firing_info.gun_ready_pose == GunReadyPose::HighReady
{
if let Some(magazine_data) = &mut firearm_state.magazine_data {
if player_firing_info.full_auto_timer.finished() {

View File

@ -1,7 +1,7 @@
use bevy::prelude::*;
use bevy_rapier3d::prelude::*;
use crate::comps::core::markers::player::Player;
use crate::{comps::core::markers::player::Player, logic::core::guns::player_firing::{PlayerFiringInfo, GunReadyPose}};
use super::player_values_state::PlayerValuesState;
@ -111,6 +111,7 @@ pub fn move_player(
&mut PlayerLinearXZState,
&mut Transform,
&mut Damping,
&mut PlayerFiringInfo,
),
With<Player>,
>,
@ -124,16 +125,21 @@ pub fn move_player(
mut player_linear_xz_state,
player_transform,
mut player_damping,
mut player_firing_info,
) in &mut query
{
if player_linear_xz_state.is_sprinting() {
player_firing_info.gun_ready_pose = GunReadyPose::LowReady;
}
if player_movement_input.down {
player_linear_xz_state.toggle_crouch(time.elapsed().as_secs_f32());
}
let crouch_multiplier = if player_linear_xz_state.is_crouched() {
player_values_state.player_crouch_speed_multiplier
} else {
1.0
};
let crouch_multiplier =
if player_linear_xz_state.is_crouched() {
player_values_state.player_crouch_speed_multiplier
} else {
1.0
};
let sprint_multiplier =
if player_movement_input.sprint && !player_linear_xz_state.is_crouched() {
player_values_state.player_sprint_speed_multiplier

View File

@ -8,7 +8,7 @@ pub struct PlayerSettings {
//pub gun_offset: f32,
pub fov: f32,
/// Debug thing for me
/// Debug things for me
pub pos_aimed_offset: Vec3,
pub pos_offset: Vec3,
@ -16,6 +16,8 @@ pub struct PlayerSettings {
pub rot_offset: Quat,
pub third_person_toggle: bool,
pub shot_lines_enabled: bool,
}
impl Default for PlayerSettings {
@ -26,7 +28,8 @@ impl Default for PlayerSettings {
pos_offset: Vec3::ZERO,
rot_aimed_offset: Quat::default(),
rot_offset: Quat::default(),
third_person_toggle: false
third_person_toggle: false,
shot_lines_enabled: false,
}
}
}

View File

@ -7,7 +7,7 @@ use crate::{
spawners::{player::player_spawner, spawn::SpawnerPlugin},
},
logic::core::{
guns::despawn_shots::{despawn_muzzle_flashes, despawn_stray_bullets},
guns::{despawn_shots::{despawn_muzzle_flashes, despawn_stray_bullets}, inspect::inspect_firearm},
player::{
camera_player_sync::{
follow_cursor_with_camera, update_camera_vertical_position, MouseMovementSettings,
@ -59,6 +59,7 @@ pub fn load_scene(application: &mut App) {
application.add_systems(Update, change_equipment.before(player_spawner));
application.add_systems(Update, (despawn_muzzle_flashes, despawn_stray_bullets));
application.add_systems(Update, inspect_firearm);
//application.add_systems(Update, animate_player);
//application.add_systems(Update, register_bullet_hits);

View File

@ -23,6 +23,15 @@ pub enum Equipment {
Nothing,
}
impl Equipment {
pub fn is_firearm(&self) -> bool {
match self {
Equipment::Firearm(_, _) => true,
Equipment::Nothing => false,
}
}
}
/// Called whenever player wants to change equipment
pub fn change_equipment(
mut commands: Commands,