RELOAD SYSTEM WITH ANIMATION DONE!
This commit is contained in:
parent
c186019b52
commit
7783c4a165
Binary file not shown.
@ -14,6 +14,7 @@ pub struct PlayerFiringInfo {
|
|||||||
/// Decreases with time, each gun has its own rebound time
|
/// Decreases with time, each gun has its own rebound time
|
||||||
pub current_round_index: usize,
|
pub current_round_index: usize,
|
||||||
pub full_auto_timer: Timer,
|
pub full_auto_timer: Timer,
|
||||||
|
pub is_reloading: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PlayerFiringInfo {
|
impl Default for PlayerFiringInfo {
|
||||||
@ -23,6 +24,7 @@ impl Default for PlayerFiringInfo {
|
|||||||
rounds_in_last_spray: Default::default(),
|
rounds_in_last_spray: Default::default(),
|
||||||
current_round_index: Default::default(),
|
current_round_index: Default::default(),
|
||||||
full_auto_timer: Timer::new(Duration::from_secs_f32(0.0), TimerMode::Repeating),
|
full_auto_timer: Timer::new(Duration::from_secs_f32(0.0), TimerMode::Repeating),
|
||||||
|
is_reloading: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,6 @@ pub fn spawn_firearm_on_player_hands(
|
|||||||
TimerMode::Once,
|
TimerMode::Once,
|
||||||
);
|
);
|
||||||
// Load animations
|
// Load animations
|
||||||
commands.insert_resource(FirearmAnimations { reload_magazine: asset_server.load(format!("{}#Animation0", DEFAULT_PLAYER_FIREARM.firearm_data().asset_path)),
|
commands.insert_resource(FirearmAnimations { reload_magazine: asset_server.load(format!("{}#Animation0", DEFAULT_PLAYER_FIREARM.firearm_data().asset_path))})
|
||||||
rock_charging_handle: asset_server.load(format!("{}#Animation1", DEFAULT_PLAYER_FIREARM.firearm_data().asset_path)) })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
use bevy::prelude::*;
|
|
||||||
|
|
||||||
use crate::setup::animations::FirearmAnimations;
|
|
||||||
|
|
||||||
pub fn setup_scene_once_loaded(
|
|
||||||
animations: Res<FirearmAnimations>,
|
|
||||||
mut players: Query<&mut AnimationPlayer, Added<AnimationPlayer>>,
|
|
||||||
) {
|
|
||||||
for mut player in &mut players {
|
|
||||||
player.play(animations.reload_magazine.clone_weak()).repeat();
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,11 +2,12 @@ use bevy::prelude::*;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
comps::core::markers::{firearm::{FirearmData, MagazineData}, holdable::InPlayerHands, player::PlayerHand},
|
comps::core::markers::{firearm::{FirearmData, MagazineData}, holdable::InPlayerHands, player::PlayerHand},
|
||||||
logic::core::guns::player_firing::PlayerFiringInfo, utils::rad_deg::radians_from_degrees,
|
logic::core::guns::player_firing::PlayerFiringInfo, utils::rad_deg::radians_from_degrees, setup::animations::FirearmAnimations,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn capture_hand_usage(
|
pub fn capture_hand_usage(
|
||||||
mouse_buttons: Res<Input<MouseButton>>,
|
mouse_buttons: Res<Input<MouseButton>>,
|
||||||
|
keyboard_input: Res<Input<KeyCode>>,
|
||||||
mut hand_query: Query<&mut Transform, With<PlayerHand>>,
|
mut hand_query: Query<&mut Transform, With<PlayerHand>>,
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
|
|
||||||
@ -15,69 +16,97 @@ pub fn capture_hand_usage(
|
|||||||
(&mut Transform, &'static FirearmData, &mut MagazineData),
|
(&mut Transform, &'static FirearmData, &mut MagazineData),
|
||||||
(With<InPlayerHands>, Without<PlayerHand>),
|
(With<InPlayerHands>, Without<PlayerHand>),
|
||||||
>,
|
>,
|
||||||
|
|
||||||
|
animation_clips: Res<Assets<AnimationClip>>,
|
||||||
|
|
||||||
|
animations: Res<FirearmAnimations>,
|
||||||
|
mut players: Query<&mut AnimationPlayer>,
|
||||||
) {
|
) {
|
||||||
player_firing_info.full_auto_timer.tick(time.delta());
|
player_firing_info.full_auto_timer.tick(time.delta());
|
||||||
|
|
||||||
for (mut _firearm_transform, firearm_data, mut magazine_data) in firearm_query.iter_mut() {
|
for (mut _firearm_transform, firearm_data, mut magazine_data) in firearm_query.iter_mut() {
|
||||||
for mut hand_transform in hand_query.iter_mut() {
|
for mut hand_transform in hand_query.iter_mut() {
|
||||||
// AIMING IN/OUT
|
|
||||||
if mouse_buttons.pressed(MouseButton::Right) {
|
|
||||||
let rotation_lerp_quat = hand_transform.rotation.lerp(
|
|
||||||
firearm_data.final_aimed_rotation,
|
|
||||||
(time.delta_seconds() / firearm_data.rebound_time_seconds).clamp(0.0, 1.0),
|
|
||||||
);
|
|
||||||
let position_lerp_vec3 = hand_transform.translation.lerp(
|
|
||||||
firearm_data.final_aimed_position,
|
|
||||||
(time.delta_seconds() / firearm_data.rebound_time_seconds).clamp(0.0, 1.0),
|
|
||||||
);
|
|
||||||
hand_transform.rotation = rotation_lerp_quat;
|
|
||||||
hand_transform.translation = position_lerp_vec3;
|
|
||||||
} else {
|
|
||||||
hand_transform.rotation = hand_transform
|
|
||||||
.rotation
|
|
||||||
.lerp(firearm_data.final_rotation, (time.delta_seconds() / firearm_data.rebound_time_seconds).clamp(0.0, 1.0));
|
|
||||||
hand_transform.translation = hand_transform.translation.lerp(
|
|
||||||
firearm_data.final_position,
|
|
||||||
(time.delta_seconds() / firearm_data.rebound_time_seconds).clamp(0.0, 1.0),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// SHOOTING & RECOIL
|
|
||||||
if mouse_buttons.pressed(MouseButton::Left) {
|
|
||||||
if player_firing_info.full_auto_timer.finished() {
|
|
||||||
if magazine_data.rounds_shot < magazine_data.max_capacity {
|
|
||||||
// Get recoil numbers from patterns
|
|
||||||
let vertical_recoil_number: f32 = match firearm_data.recoil_pattern.vertical.get(player_firing_info.current_round_index) {
|
|
||||||
Some(vert_recoil_number) => *vert_recoil_number,
|
|
||||||
None => {
|
|
||||||
*firearm_data.recoil_pattern.vertical.last().expect("FOUND A FIREARM_DATA WITHOUT ANY FIREARM_RECOIL_PATTERN.")
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let horizontal_recoil_number: f32 = match firearm_data.recoil_pattern.horizontal.get(player_firing_info.current_round_index) {
|
|
||||||
Some(horizontal_recoil_number) => *horizontal_recoil_number,
|
|
||||||
None => {
|
|
||||||
*firearm_data.recoil_pattern.horizontal.last().expect("FOUND A FIREARM_DATA WITHOUT ANY FIREARM_RECOIL_PATTERN.")
|
|
||||||
},
|
|
||||||
};
|
|
||||||
// Increment indexes and timers
|
|
||||||
player_firing_info.current_round_index += 1;
|
|
||||||
player_firing_info.last_shot_timestamp = time.elapsed_seconds();
|
|
||||||
player_firing_info.full_auto_timer.reset();
|
|
||||||
magazine_data.rounds_shot += 1;
|
|
||||||
|
|
||||||
// Apply recoil
|
if player_firing_info.is_reloading {
|
||||||
hand_transform
|
for mut player in &mut players {
|
||||||
.rotate_x(radians_from_degrees(firearm_data.vertical_recoil_modifier * vertical_recoil_number));
|
if let Some(reload_animation) = animation_clips.get(&animations.reload_magazine) {
|
||||||
hand_transform.rotate_y(radians_from_degrees(firearm_data.horizontal_recoil_modifier * horizontal_recoil_number));
|
if player.elapsed() >= reload_animation.duration() {
|
||||||
} else {
|
magazine_data.rounds_shot = 0;
|
||||||
//TODO: play magazine empty sound
|
player_firing_info.is_reloading = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} else { // Player is not in a reload animation
|
||||||
|
if keyboard_input.just_pressed(KeyCode::R) {
|
||||||
|
// Start reload animation
|
||||||
|
for mut player in &mut players {
|
||||||
|
player.start(animations.reload_magazine.clone_weak());
|
||||||
|
player_firing_info.is_reloading = true;
|
||||||
|
}
|
||||||
|
// Set is_reloading = true
|
||||||
|
// At the end of reload animation, set magazine data to capacity = 0
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
// AIMING IN/OUT
|
||||||
if player_firing_info.full_auto_timer.finished() {
|
if mouse_buttons.pressed(MouseButton::Right) {
|
||||||
player_firing_info.current_round_index = 0;
|
let rotation_lerp_quat = hand_transform.rotation.lerp(
|
||||||
|
firearm_data.final_aimed_rotation,
|
||||||
|
(time.delta_seconds() / firearm_data.rebound_time_seconds).clamp(0.0, 1.0),
|
||||||
|
);
|
||||||
|
let position_lerp_vec3 = hand_transform.translation.lerp(
|
||||||
|
firearm_data.final_aimed_position,
|
||||||
|
(time.delta_seconds() / firearm_data.rebound_time_seconds).clamp(0.0, 1.0),
|
||||||
|
);
|
||||||
|
hand_transform.rotation = rotation_lerp_quat;
|
||||||
|
hand_transform.translation = position_lerp_vec3;
|
||||||
|
} else {
|
||||||
|
hand_transform.rotation = hand_transform
|
||||||
|
.rotation
|
||||||
|
.lerp(firearm_data.final_rotation, (time.delta_seconds() / firearm_data.rebound_time_seconds).clamp(0.0, 1.0));
|
||||||
|
hand_transform.translation = hand_transform.translation.lerp(
|
||||||
|
firearm_data.final_position,
|
||||||
|
(time.delta_seconds() / firearm_data.rebound_time_seconds).clamp(0.0, 1.0),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// SHOOTING & RECOIL
|
||||||
|
if mouse_buttons.pressed(MouseButton::Left) {
|
||||||
|
if player_firing_info.full_auto_timer.finished() {
|
||||||
|
if magazine_data.rounds_shot < magazine_data.max_capacity {
|
||||||
|
// Get recoil numbers from patterns
|
||||||
|
let vertical_recoil_number: f32 = match firearm_data.recoil_pattern.vertical.get(player_firing_info.current_round_index) {
|
||||||
|
Some(vert_recoil_number) => *vert_recoil_number,
|
||||||
|
None => {
|
||||||
|
*firearm_data.recoil_pattern.vertical.last().expect("FOUND A FIREARM_DATA WITHOUT ANY FIREARM_RECOIL_PATTERN.")
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let horizontal_recoil_number: f32 = match firearm_data.recoil_pattern.horizontal.get(player_firing_info.current_round_index) {
|
||||||
|
Some(horizontal_recoil_number) => *horizontal_recoil_number,
|
||||||
|
None => {
|
||||||
|
*firearm_data.recoil_pattern.horizontal.last().expect("FOUND A FIREARM_DATA WITHOUT ANY FIREARM_RECOIL_PATTERN.")
|
||||||
|
},
|
||||||
|
};
|
||||||
|
// Increment indexes and timers
|
||||||
|
player_firing_info.current_round_index += 1;
|
||||||
|
player_firing_info.last_shot_timestamp = time.elapsed_seconds();
|
||||||
|
player_firing_info.full_auto_timer.reset();
|
||||||
|
magazine_data.rounds_shot += 1;
|
||||||
|
|
||||||
|
// Apply recoil
|
||||||
|
hand_transform
|
||||||
|
.rotate_x(radians_from_degrees(firearm_data.vertical_recoil_modifier * vertical_recoil_number));
|
||||||
|
hand_transform.rotate_y(radians_from_degrees(firearm_data.horizontal_recoil_modifier * horizontal_recoil_number));
|
||||||
|
} else {
|
||||||
|
//TODO: play magazine empty sound
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if player_firing_info.full_auto_timer.finished() {
|
||||||
|
player_firing_info.current_round_index = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
hands::capture_hand_usage,
|
hands::capture_hand_usage,
|
||||||
player_vertical_sync::sync_player_y_state,
|
player_vertical_sync::sync_player_y_state,
|
||||||
spawn_player::spawn_player, camera_effects::setup_scene_once_loaded,
|
spawn_player::spawn_player,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -43,6 +43,6 @@ pub fn load_scene(application: &mut App) {
|
|||||||
application.add_systems(Update, capture_hand_usage);
|
application.add_systems(Update, capture_hand_usage);
|
||||||
|
|
||||||
application.add_systems(Startup, setup_lighting);
|
application.add_systems(Startup, setup_lighting);
|
||||||
application.add_systems(Update, setup_scene_once_loaded);
|
//application.add_systems(Update, setup_scene_once_loaded);
|
||||||
//application.add_systems(Update, play_animation);
|
//application.add_systems(Update, play_animation);
|
||||||
}
|
}
|
||||||
|
@ -3,5 +3,5 @@ use bevy::prelude::*;
|
|||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct FirearmAnimations {
|
pub struct FirearmAnimations {
|
||||||
pub reload_magazine: Handle<AnimationClip>,
|
pub reload_magazine: Handle<AnimationClip>,
|
||||||
pub rock_charging_handle: Handle<AnimationClip>,
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user