High ready + Low ready system. With animations and logic flows with sprinting, shooting, reloading, and aiming
This commit is contained in:
parent
1a7a5e6024
commit
24df81424b
|
@ -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.
|
@ -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>,
|
||||
>,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
pub mod despawn_shots;
|
||||
pub mod player_firing;
|
||||
pub mod shoot;
|
||||
pub mod inspect;
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue