Third person camera added

This commit is contained in:
Franklin 2023-11-18 21:40:37 -04:00
parent a121c738b7
commit b3abd36eff
16 changed files with 169 additions and 27 deletions

Binary file not shown.

View File

@ -1,4 +1,5 @@
pub mod player_character;
pub mod player_hitbox;
pub mod in_player_hands_parent;
pub mod player_eye;
pub mod player_eye;
pub mod third_person_camera;

View File

@ -3,6 +3,8 @@ use bevy_rapier3d::prelude::*;
use crate::{comps::core::markers::{proxy::physics::rapier::LinkToPlayer, camera::MainCamera}, logic::core::player::player_values_state::PlayerValuesState};
use super::third_person_camera::{ThirdPersonCameraProxy, ThirdPersonCamera};
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
@ -11,6 +13,7 @@ pub struct PlayerEye;
pub fn insert_components_into_spawned_player(
mut commands: Commands,
eye_query: Query<Entity, Added<PlayerEye>>,
third_person_camera_query: Query<Entity, Added<ThirdPersonCameraProxy>>,
player_collider_query: Query<Entity, (With<LinkToPlayer>, With<Collider>, Added<Collider>)>,
player_values_state: Res<PlayerValuesState>,
) {
@ -31,6 +34,29 @@ pub fn insert_components_into_spawned_player(
.id();
commands.entity(eye).add_child(camera);
}
for third_person_camera in third_person_camera_query.iter() {
let mut cam_bundle = Camera3dBundle {
transform: Transform::from_translation(Vec3::ZERO),
..Default::default()
};
cam_bundle.camera.is_active = false;
cam_bundle.camera.order = 1;
// Spawn camera
let camera = commands
.spawn(cam_bundle)
//s.insert(Skybox(skybox_handle.clone()))
.insert(VisibilityBundle {
visibility: Visibility::Inherited,
..Default::default()
})
.insert(ThirdPersonCamera)
//.push_children(&[player_hand])
.id();
commands.entity(third_person_camera).add_child(camera);
}
for entity in player_collider_query.iter() {
commands.entity(entity)
.insert(Restitution::coefficient(0.0))

View File

@ -0,0 +1,10 @@
use bevy::prelude::*;
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
pub struct ThirdPersonCameraProxy;
#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
pub struct ThirdPersonCamera;

View File

@ -2,7 +2,7 @@ use bevy::app::{Plugin, Update};
use crate::setup::load_state::update_game_load_state;
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}}, physics::{rapier::{AutoAABBCollider, physics_replace_proxies}, self}};
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}};
@ -18,6 +18,7 @@ impl Plugin for ProxyComponentsPlugin {
app.register_type::<PlayerCharacter>();
app.register_type::<PlayerEye>();
app.register_type::<InPlayerHandsParent>();
app.register_type::<ThirdPersonCameraProxy>();
// Physics
app.register_type::<AutoAABBCollider>();

View File

@ -0,0 +1,49 @@
use std::time::Duration;
use bevy::prelude::*;
use bevy_rapier3d::dynamics::Velocity;
use crate::{setup::{animations::AllAnimations, assets::GltfAssets}, comps::core::markers::{player::Player, proxy::character::player_character::PlayerCharacter}, ui::game::game_ui_state::GameUiState};
use super::player_movement::{PlayerLinearYState, PlayerLinearXZState};
#[allow(unused)]
pub fn animate_player(
all_animations: Res<AllAnimations>,
assets_gltf: Res<GltfAssets>,
player_query: Query<
(
&Velocity,
&PlayerLinearYState,
&PlayerLinearXZState,
),
(
With<Player>,
Changed<PlayerLinearXZState>,
Changed<PlayerLinearYState>
)
>,
mut player_character_animation_player_query: Query<&mut AnimationPlayer, With<PlayerCharacter>>,
time: Res<Time>,
game_ui_state: Res<GameUiState>,
) {
for (player_velocity, player_linear_y_state, player_linear_xz_state) in player_query.iter() {
for mut animation_player in player_character_animation_player_query.iter_mut() {
if player_linear_xz_state.is_sprinting() {
let clip_to_play = all_animations.character_animations.clone().expect("No Character animations in all_animations Resource").run_animation.clone_weak();
if !animation_player.is_playing_clip(&clip_to_play) {
animation_player.start_with_transition(clip_to_play, Duration::from_millis(100));
animation_player.set_speed(1.8);
animation_player.repeat();
}
} else {
let clip_to_play = all_animations.character_animations.clone().expect("No Character animations in all_animations Resource").idle_animation.clone_weak();
if !animation_player.is_playing_clip(&clip_to_play) {
animation_player.play(clip_to_play);
animation_player.set_speed(0.4);
animation_player.repeat();
}
}
}
}
}

View File

@ -0,0 +1,19 @@
use bevy::prelude::*;
use crate::comps::core::markers::{camera::MainCamera, proxy::character::third_person_camera::ThirdPersonCamera};
pub fn switch_camera(
// mut commands: Commands,
mut main_camera_query: Query<&mut Camera, With<MainCamera>>,
mut tpc_query: Query<&mut Camera, (With<ThirdPersonCamera>, Without<MainCamera>)>,
keyboard_input: Res<Input<KeyCode>>,
) {
if keyboard_input.just_pressed(KeyCode::Key0) {
for mut main_cam in main_camera_query.iter_mut() {
main_cam.is_active = !main_cam.is_active;
}
for mut tpc in tpc_query.iter_mut() {
tpc.is_active = !tpc.is_active;
}
}
}

View File

@ -15,9 +15,8 @@ use crate::{
},
logic::core::guns::{player_firing::PlayerFiringInfo, shoot::shoot_bullet},
setup::{
animations::AllFirearmAnimations,
equipment::{Equipment, EquipmentChangeEvent},
load_state::GameLoadState, assets::GltfAssets,
load_state::GameLoadState, assets::GltfAssets, animations::AllAnimations,
},
ui::game::{game_ui_state::GameUiState, hud::hud::HudState},
utils::{self, rad_deg::radians_from_degrees},
@ -32,7 +31,7 @@ pub struct CaptureHandUsageResourcesParams<'w> {
meshes: ResMut<'w, Assets<Mesh>>,
materials: ResMut<'w, Assets<StandardMaterial>>,
animation_clips: Res<'w, Assets<AnimationClip>>,
all_firearm_animations: Res<'w, AllFirearmAnimations>,
all_animations: Res<'w, AllAnimations>,
time: Res<'w, Time>,
assets_gltf: Res<'w, GltfAssets>,
loaded_gltf_assets: Res<'w, Assets<Gltf>>,
@ -136,8 +135,8 @@ pub fn capture_hand_usage(
&children,
) {
if let Some(firearm_animations) = resources
.all_firearm_animations
.animations
.all_animations
.firearm_animations
.iter()
.find(|animation| &animation.firearm == &player_firearm)
{
@ -170,8 +169,8 @@ pub fn capture_hand_usage(
&children,
) {
if let Some(firearm_animations) = resources
.all_firearm_animations
.animations
.all_animations
.firearm_animations
.iter()
.find(|animation| &animation.firearm == &player_firearm)
{

View File

@ -5,3 +5,5 @@ pub mod inventory;
pub mod player_movement;
pub mod player_values_state;
pub mod player_vertical_sync;
pub mod animate_player;
pub mod camera_switching;

View File

@ -94,6 +94,12 @@ pub struct PlayerMovementInput {
pub sprint: bool,
}
/*
if let Some(animations) = &resources.all_animations.character_animations {
animation_player.start(animations.run_animation.clone_weak());
}
*/
/// Applies game logic to determine how player should move.
pub fn move_player(
player_movement_input: PlayerMovementInput,

View File

@ -31,7 +31,7 @@ fn setup_plugins(application: &mut App) {
.add_plugins(DefaultPlugins.set(AssetPlugin::default()))
//.add_plugins(DefaultInspectorConfigPlugin)
.add_plugins(RapierPhysicsPlugin::<NoUserData>::default())
.add_plugins(RapierDebugRenderPlugin::default())
//.add_plugins(RapierDebugRenderPlugin::default())
.add_plugins(ComponentsFromGltfPlugin)
//.add_plugins(bevy_egui::EguiPlugin)
//.add_plugins(WorldInspectorPlugin::new())

View File

@ -14,11 +14,11 @@ use crate::{
},
hands::{capture_hand_usage, interact_action},
player_values_state::PlayerValuesState,
player_vertical_sync::sync_player_y_state,
player_vertical_sync::sync_player_y_state, animate_player::animate_player, camera_switching::switch_camera,
},
},
setup::{
animations::{load_animations, AllFirearmAnimations},
animations::{load_animations, AllAnimations},
assets::load_all_assets,
equipment::{change_equipment, EquipmentChangeEvent},
load_state::GameLoadState,
@ -33,7 +33,7 @@ use super::{
pub fn load_scene(application: &mut App) {
application.insert_resource(GameLoadState::default());
application.insert_resource(MouseMovementSettings::default());
application.insert_resource(AllFirearmAnimations::default());
application.insert_resource(AllAnimations::default());
application.insert_resource(PlayerValuesState::default());
application.add_plugins(SpawnerPlugin);
@ -55,9 +55,12 @@ pub fn load_scene(application: &mut App) {
application.add_systems(Update, update_camera_vertical_position);
application.add_systems(Update, capture_hand_usage);
application.add_systems(Update, interact_action);
application.add_systems(Update, switch_camera);
application.add_systems(Update, change_equipment.before(player_spawner));
application.add_systems(Update, (despawn_muzzle_flashes, despawn_stray_bullets));
application.add_systems(Update, animate_player);
//application.add_systems(Update, register_bullet_hits);
application.add_event::<EquipmentChangeEvent>();

View File

@ -8,7 +8,7 @@ use bevy::{
},
};
use crate::comps::core::markers::camera::MainCamera;
use crate::comps::core::markers::{camera::MainCamera, proxy::character::third_person_camera::ThirdPersonCamera};
pub const CUBEMAPS: &[(&str, CompressedImageFormats)] =
&[("skybox/skybox.png", CompressedImageFormats::NONE)];
@ -25,7 +25,7 @@ pub fn set_skybox_if_loaded(
mut commands: Commands,
mut images: ResMut<Assets<Image>>,
mut cubemap: ResMut<Cubemap>,
mut camera_query: Query<Entity, With<MainCamera>>,
mut camera_query: Query<Entity, Or<(With<MainCamera>, With<ThirdPersonCamera>)>>,
) {
if !cubemap.is_loaded
&& asset_server.get_load_state(&cubemap.image_handle) == Some(LoadState::Loaded)

View File

@ -4,18 +4,26 @@ use crate::logic::core::guns::firearm::Firearm;
use super::{assets::GltfAssets, load_state::GameLoadState};
#[derive(Resource, Default, Reflect)]
#[derive(Resource, Default, Reflect, Clone)]
#[reflect(Resource)]
pub struct AllFirearmAnimations {
pub animations: Vec<FirearmAnimations>,
pub struct AllAnimations {
pub firearm_animations: Vec<FirearmAnimations>,
pub character_animations: Option<CharacterAnimations>,
}
#[derive(Reflect)]
#[derive(Reflect, Clone)]
pub struct FirearmAnimations {
pub firearm: Firearm,
pub reload_magazine: Handle<AnimationClip>,
}
#[derive(Reflect, Default, Clone)]
pub struct CharacterAnimations {
pub run_animation: Handle<AnimationClip>,
pub idle_animation: Handle<AnimationClip>,
pub initial_pose: Handle<AnimationClip>,
}
/// System to load animations once the Gltf file is loaded.
pub fn load_animations(
mut commands: Commands,
@ -30,21 +38,33 @@ pub fn load_animations(
if assets_gltf.assets.len() != loaded_gltf_assets.len() {
return;
}
let mut all_firearm_animations = AllFirearmAnimations {
animations: Vec::new(),
};
let mut firearm_animations = Vec::new();
let mut character_animations = None;
for gltf_asset in assets_gltf.assets.iter() {
if gltf_asset.asset_type.is_firearm() {
if let Some(loaded_gltf) = loaded_gltf_assets.get(&gltf_asset.asset) {
// Needs to have all firearm animations
let reload_animation = &loaded_gltf.animations[0];
all_firearm_animations.animations.push(FirearmAnimations {
firearm_animations.push(FirearmAnimations {
firearm: gltf_asset.asset_type.get_firearm().clone(),
reload_magazine: reload_animation.clone(),
})
});
}
}
if gltf_asset.asset_type.is_character() {
if let Some(loaded_gltf) = loaded_gltf_assets.get(&gltf_asset.asset) {
// Needs to have all player_animations
let initial_pose = &loaded_gltf.animations[0];
let player_idle = &loaded_gltf.animations[1];
let player_run = &loaded_gltf.animations[2];
character_animations = Some(CharacterAnimations { run_animation: player_run.clone(), idle_animation: player_idle.clone(), initial_pose: initial_pose.clone() });
}
}
}
commands.insert_resource(all_firearm_animations);
let all_animations = AllAnimations {
firearm_animations: Vec::new(),
character_animations
};
commands.insert_resource(all_animations);
game_load_state.animations_loaded = true;
}

View File

@ -65,4 +65,10 @@ impl GltfAssetType {
_ => panic!("Called get_firearm on Non-Firearm GltfAssetType"),
}
}
pub fn is_character(&self) -> bool {
match self {
GltfAssetType::Character => true,
_ => false,
}
}
}

View File

@ -21,7 +21,7 @@ use crate::{
},
scenes::scene1::skybox::Cubemap,
setup::{
animations::{AllFirearmAnimations, FirearmAnimations},
animations::{FirearmAnimations, AllAnimations},
assets::{GltfAssetType, GltfAssets},
equipment::Equipment,
load_state::GameLoadState,
@ -55,7 +55,7 @@ impl Plugin for MainEditorUiPlugin {
.register_type::<PlayerLinearXZState>()
.register_type::<PlayerMovementInput>()
.register_type::<Cubemap>()
.register_type::<AllFirearmAnimations>()
.register_type::<AllAnimations>()
.register_type::<FirearmAnimations>()
.register_type::<GltfAssetType>()
.register_type::<GltfAssets>()