diff --git a/godot/Scenes/Characters/remy.tscn b/godot/Scenes/Characters/remy.tscn index 2f423f2..334e6cc 100644 --- a/godot/Scenes/Characters/remy.tscn +++ b/godot/Scenes/Characters/remy.tscn @@ -314,12 +314,13 @@ states/Start/position = Vector2(107.334, 120.683) transitions = ["Start", "Movement", SubResource("AnimationNodeStateMachineTransition_d2yto"), "JumpBlend", "Movement", SubResource("AnimationNodeStateMachineTransition_04hs0"), "Movement", "JumpBlend", SubResource("AnimationNodeStateMachineTransition_a4m5g")] graph_offset = Vector2(18, 52) -[node name="Player" type="CharacterBody3D"] +[node name="Player" type="Player"] collision_layer = 2 collision_mask = 3 [node name="Head" type="Node3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.55647, 0) +visible = false [node name="FPV" parent="Head" instance=ExtResource("9_0cwor")] transform = Transform3D(-1, 0, -1.50996e-07, 0, 1, 0, 1.50996e-07, 0, -1, 0, -1.55647, 0) diff --git a/include/client/Player.h b/include/client/Player.h index 17a418a..7f690a2 100644 --- a/include/client/Player.h +++ b/include/client/Player.h @@ -1,17 +1,18 @@ #pragma once +#include #include #include #include -#include namespace blitz { class World; +class PlayerController; -class Player : public godot::Node { +class Player : public godot::CharacterBody3D { - GDCLASS(Player, godot::Node); + GDCLASS(Player, godot::CharacterBody3D); protected: static void _bind_methods(); @@ -39,9 +40,7 @@ class Player : public godot::Node { protected: godot::Node3D* m_Mesh; - godot::Node3D* m_Head; godot::AnimationTree* m_AnimationTree; - godot::CharacterBody3D* m_Player; godot::Vector3 m_SnapVector; PeerID m_PeerId; @@ -51,5 +50,6 @@ class Player : public godot::Node { void BlendAnimation(const godot::String& a_AnimationName, float a_Goal, float a_Delta); friend class World; + friend class PlayerController; }; } // namespace blitz diff --git a/include/client/FirstPersonPlayer.h b/include/client/PlayerController.h similarity index 68% rename from include/client/FirstPersonPlayer.h rename to include/client/PlayerController.h index 2acbd41..9bdea60 100644 --- a/include/client/FirstPersonPlayer.h +++ b/include/client/PlayerController.h @@ -5,29 +5,31 @@ namespace blitz { -class FirstPersonPlayer : public Player { - GDCLASS(FirstPersonPlayer, godot::Node) +class PlayerController : public godot::Node { + GDCLASS(PlayerController, godot::Node) protected: static void _bind_methods(); public: - FirstPersonPlayer(); - ~FirstPersonPlayer(); + PlayerController(); + ~PlayerController(); // Godot overrides void _unhandled_input(const godot::Ref&); - void _physics_process(float delta) override; + void _process(float delta); void _ready(); private: godot::Camera3D* m_Camera; float m_BobTime; float m_Speed; + Player* m_Player; + godot::Node3D* m_Head; void UpdateBobbing(float delta); void UpdateFOV(float delta); void UpdateCamera(const godot::InputEventMouseMotion&); - void UpdatePosition(float delta); + void UpdateVelocity(float delta); void Shoot(); }; diff --git a/src/blitz/godot/World.cpp b/src/blitz/godot/World.cpp index 1b7c4b6..63a8734 100644 --- a/src/blitz/godot/World.cpp +++ b/src/blitz/godot/World.cpp @@ -1,8 +1,8 @@ #include #include -#include #include +#include #include #include #include @@ -65,28 +65,18 @@ void World::HandlePacket(const protocol::packets::PlayerLeave& a_PlayerLeave) { void World::AddPlayer(PlayerID a_PlayerId, String a_PlayerName) { UtilityFunctions::print("New Player with id : ", a_PlayerId, " and name ", a_PlayerName); + + Ref serverScene = ResourceLoader::get_singleton()->load(PlayerScenePath); + + Player* player = Object::cast_to(serverScene->instantiate()); + player->set_name(UtilityFunctions::var_to_str(a_PlayerId)); + player->m_PeerId = a_PlayerId; + + m_Players->add_child(player); + if (a_PlayerId == get_multiplayer()->get_unique_id()) { - Ref serverScene = ResourceLoader::get_singleton()->load(PlayerScenePath); - - Node* playerContent = serverScene->instantiate(); - - FirstPersonPlayer* player = memnew(FirstPersonPlayer); - player->set_name(UtilityFunctions::var_to_str(a_PlayerId)); - player->m_PeerId = a_PlayerId; - player->add_child(playerContent); - - m_Players->add_child(player); - } else { - Ref serverScene = ResourceLoader::get_singleton()->load(PlayerScenePath); - - Node* playerContent = serverScene->instantiate(); - - Player* player = memnew(Player); - player->set_name(UtilityFunctions::var_to_str(a_PlayerId)); - player->m_PeerId = a_PlayerId; - player->add_child(playerContent); - - m_Players->add_child(player); + PlayerController* playerController = memnew(PlayerController); + player->add_child(playerController); } } diff --git a/src/client/Player.cpp b/src/client/Player.cpp index f6d716f..6fcb664 100644 --- a/src/client/Player.cpp +++ b/src/client/Player.cpp @@ -31,19 +31,13 @@ void Player::_ready() { return; } - m_Player = get_node("Player"); - DEV_ASSERT(m_Player); - // we set the player to an invalid position - m_Player->set_position({-99999, -999999, -999999}); + set_position({-99999, -999999, -999999}); - m_Head = get_node("Player/Head"); - DEV_ASSERT(m_Head); - - m_Mesh = get_node("Player/Armature"); + m_Mesh = get_node("Armature"); DEV_ASSERT(m_Mesh); - m_AnimationTree = get_node("Player/AnimationTree"); + m_AnimationTree = get_node("AnimationTree"); DEV_ASSERT(m_AnimationTree); } @@ -51,29 +45,29 @@ void Player::_physics_process(float delta) { if (godot::Engine::get_singleton()->is_editor_hint()) return; - m_Player->move_and_slide(); + move_and_slide(); UpdateAnimation(delta); } Vector3 Player::GetPosition() const { - return m_Player->get_position(); + return get_position(); } void Player::SetPosition(const Vector3& a_Position) { - m_Player->set_position(a_Position); + set_position(a_Position); } Vector3 Player::GetVelocity() const { - return m_Player->get_velocity(); + return get_velocity(); } void Player::SetVelocity(const Vector3& a_Velocity) { - m_Player->set_velocity(a_Velocity); + set_velocity(a_Velocity); } void Player::UpdateAnimation(float a_Delta) { - Vector3 velocity = m_Player->get_velocity(); - float angle = m_Player->get_rotation().y; + Vector3 velocity = get_velocity(); + float angle = get_rotation().y; Vector3 direction = velocity.rotated({0, 1, 0}, -angle); if (direction.length() < 1.0f) { @@ -91,8 +85,8 @@ void Player::UpdateAnimation(float a_Delta) { float ratio = 0.5f - (UtilityFunctions::absf(direction.z) - UtilityFunctions::absf(direction.x)) * 0.5f; BlendAnimation("parameters/Movement/Walking/blend_amount", ratio, a_Delta); - m_AnimationTree->set("parameters/conditions/jump", !m_Player->is_on_floor() && m_Player->get_velocity().y > 0.0f); - m_AnimationTree->set("parameters/conditions/is_on_floor", m_Player->is_on_floor()); + m_AnimationTree->set("parameters/conditions/jump", !is_on_floor() && get_velocity().y > 0.0f); + m_AnimationTree->set("parameters/conditions/is_on_floor", is_on_floor()); } void Player::BlendAnimation(const godot::String& a_AnimationName, float a_Goal, float a_Delta) { @@ -117,11 +111,11 @@ void Player::SetModelVisible(bool a_Visible) { } Vector3 Player::GetCameraRotation() const { - return m_Player->get_rotation(); + return get_rotation(); } void Player::SetCameraRotation(const Vector3& a_Rotation) { - m_Player->set_rotation(a_Rotation); + set_rotation(a_Rotation); } } // namespace blitz diff --git a/src/client/FirstPersonPlayer.cpp b/src/client/PlayerController.cpp similarity index 65% rename from src/client/FirstPersonPlayer.cpp rename to src/client/PlayerController.cpp index 491cf7a..6fddd17 100644 --- a/src/client/FirstPersonPlayer.cpp +++ b/src/client/PlayerController.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -41,15 +41,13 @@ static const float AnimationBlend = 7.0; static const char BulletScenePath[] = "res://Scenes/Weapons/pen.tscn"; -void FirstPersonPlayer::_bind_methods() {} +void PlayerController::_bind_methods() {} -FirstPersonPlayer::FirstPersonPlayer() : Player(), m_BobTime(0) {} +PlayerController::PlayerController() : m_BobTime(0) {} -FirstPersonPlayer::~FirstPersonPlayer() {} - -void FirstPersonPlayer::_ready() { - Player::_ready(); +PlayerController::~PlayerController() {} +void PlayerController::_ready() { InputMap::get_singleton()->load_from_project_settings(); if (!Engine::get_singleton()->is_editor_hint()) { Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); @@ -57,18 +55,25 @@ void FirstPersonPlayer::_ready() { return; } + m_Player = Object::cast_to(get_parent()); + + m_Head = m_Player->get_node("Head"); + DEV_ASSERT(m_Head); + + m_Head->set_visible(true); + m_Camera = memnew(Camera3D); m_Camera->set_name("FirstPersonCamera"); m_Head->add_child(m_Camera); m_Camera->make_current(); - SetModelVisible(false); + m_Player->SetModelVisible(false); - SetPosition({0, 100, 0}); - SetVelocity({0, 0, 0}); + m_Player->SetPosition({0, 1, 0}); + m_Player->SetVelocity({0, 0, 0}); } -void FirstPersonPlayer::_unhandled_input(const godot::Ref& a_Event) { +void PlayerController::_unhandled_input(const godot::Ref& a_Event) { auto* event = Object::cast_to(a_Event.ptr()); if (event) UpdateCamera(*event); @@ -81,7 +86,7 @@ void FirstPersonPlayer::_unhandled_input(const godot::Ref& a_ } } -void FirstPersonPlayer::_physics_process(float a_Delta) { +void PlayerController::_process(float a_Delta) { #if DEBUG_ENABLED if (Engine::get_singleton()->is_editor_hint()) { return; @@ -91,26 +96,21 @@ void FirstPersonPlayer::_physics_process(float a_Delta) { auto* Input = Input::get_singleton(); if (!m_Player->is_on_floor()) - SetVelocity(GetVelocity() - Vector3{0, GRAVITY * a_Delta, 0}); + m_Player->SetVelocity(m_Player->GetVelocity() - Vector3{0, GRAVITY * a_Delta, 0}); if (Input->is_action_pressed("jump") && m_Player->is_on_floor()) - SetVelocity({GetVelocity().x, JUMP_VELOCITY, GetVelocity().z}); + m_Player->SetVelocity({m_Player->GetVelocity().x, JUMP_VELOCITY, m_Player->GetVelocity().z}); m_Speed = Input->is_action_pressed("sprint") ? SPRINT_SPEED : WALK_SPEED; - UpdatePosition(a_Delta); - UpdateFOV(a_Delta); UpdateBobbing(a_Delta); - - m_Player->move_and_slide(); - - UpdateAnimation(a_Delta); + UpdateVelocity(a_Delta); Shoot(); } -void FirstPersonPlayer::Shoot() { +void PlayerController::Shoot() { if (Input::get_singleton()->is_action_pressed("shoot")) { Ref bulletScene = ResourceLoader::get_singleton()->load(BulletScenePath); auto* bullet = Object::cast_to(bulletScene->instantiate()); @@ -118,13 +118,13 @@ void FirstPersonPlayer::Shoot() { bullet->set_position(m_Camera->get_global_position()); bullet->set_transform(m_Camera->get_global_transform()); - Node* entities = get_node("../../Entities"); + Node* entities = m_Player->get_node("../../Entities"); entities->add_child(bullet); } } -void FirstPersonPlayer::UpdateBobbing(float a_Delta) { - m_BobTime += a_Delta * GetVelocity().length() * m_Player->is_on_floor(); +void PlayerController::UpdateBobbing(float a_Delta) { + m_BobTime += a_Delta * m_Player->GetVelocity().length() * m_Player->is_on_floor(); Vector3 newPos{static_cast(Math::cos(m_BobTime * BOB_FREQ / 2.0) * BOB_AMP), static_cast(Math::sin(m_BobTime * BOB_FREQ) * BOB_AMP), 0}; @@ -132,7 +132,7 @@ void FirstPersonPlayer::UpdateBobbing(float a_Delta) { // m_Camera->set_transform({m_Camera->get_transform().basis, newPos}); } -void FirstPersonPlayer::UpdateCamera(const InputEventMouseMotion& a_Event) { +void PlayerController::UpdateCamera(const InputEventMouseMotion& a_Event) { m_Player->rotate_y(-a_Event.get_relative().x * SENSITIVITY); m_Head->rotate_x(-a_Event.get_relative().y * SENSITIVITY); @@ -141,7 +141,7 @@ void FirstPersonPlayer::UpdateCamera(const InputEventMouseMotion& a_Event) { m_Head->set_rotation({rotationX, m_Head->get_rotation().y, m_Head->get_rotation().z}); } -void FirstPersonPlayer::UpdatePosition(float delta) { +void PlayerController::UpdateVelocity(float delta) { auto* Input = Input::get_singleton(); Vector2 inputDirection = Input->get_vector("move_left", "move_right", "move_forwards", "move_backwards"); @@ -149,25 +149,25 @@ void FirstPersonPlayer::UpdatePosition(float delta) { if (m_Player->is_on_floor()) { if (!direction.is_zero_approx()) { - SetVelocity({direction.x * m_Speed, GetVelocity().y, direction.z * m_Speed}); + m_Player->SetVelocity({direction.x * m_Speed, m_Player->GetVelocity().y, direction.z * m_Speed}); } else { - SetVelocity({Math::lerp(static_cast(GetVelocity().x), static_cast(direction.x * m_Speed), - static_cast(delta * GROUND_FRICTION)), - GetVelocity().y, - Math::lerp(static_cast(GetVelocity().z), static_cast(direction.z * m_Speed), + m_Player->SetVelocity({Math::lerp(static_cast(m_Player->GetVelocity().x), static_cast(direction.x * m_Speed), + static_cast(delta * GROUND_FRICTION)), + m_Player->GetVelocity().y, + Math::lerp(static_cast(m_Player->GetVelocity().z), static_cast(direction.z * m_Speed), static_cast(delta * GROUND_FRICTION))}); } } else { - SetVelocity({Math::lerp(static_cast(GetVelocity().x), static_cast(direction.x * m_Speed), - static_cast(delta * AIR_MOVEMENT)), - GetVelocity().y, - Math::lerp(static_cast(GetVelocity().z), static_cast(direction.z * m_Speed), + m_Player->SetVelocity({Math::lerp(static_cast(m_Player->GetVelocity().x), static_cast(direction.x * m_Speed), + static_cast(delta * AIR_MOVEMENT)), + m_Player->GetVelocity().y, + Math::lerp(static_cast(m_Player->GetVelocity().z), static_cast(direction.z * m_Speed), static_cast(delta * AIR_MOVEMENT))}); } } -void FirstPersonPlayer::UpdateFOV(float a_Delta) { - float velocityClamped = Math::clamp(GetVelocity().length(), MIN_FOV_VELOCITY, MAX_FOV_VELOCITY); +void PlayerController::UpdateFOV(float a_Delta) { + float velocityClamped = Math::clamp(m_Player->GetVelocity().length(), MIN_FOV_VELOCITY, MAX_FOV_VELOCITY); float targetFOV = BASE_FOV + FOV_CHANGE * velocityClamped; m_Camera->set_fov(Math::lerp(static_cast(m_Camera->get_fov()), targetFOV, a_Delta * FOV_TRANSITION)); } diff --git a/src/client/register_types.cpp b/src/client/register_types.cpp index d920a65..0d07421 100644 --- a/src/client/register_types.cpp +++ b/src/client/register_types.cpp @@ -1,10 +1,10 @@ #include #include #include -#include #include #include #include +#include #include #include @@ -16,7 +16,7 @@ using namespace godot; static void RegisterClasses() { GDREGISTER_CLASS(blitz::Player); - GDREGISTER_CLASS(blitz::FirstPersonPlayer); + GDREGISTER_CLASS(blitz::PlayerController); GDREGISTER_CLASS(blitz::MainMenu); GDREGISTER_CLASS(blitz::Main); GDREGISTER_CLASS(blitz::NetworkInterface);