feat: added move_to and shoot_at to player character

This commit is contained in:
Sara 2024-03-22 00:16:33 +01:00
parent 7532a68b91
commit 078f0424dd
2 changed files with 32 additions and 7 deletions

View file

@ -1,5 +1,6 @@
#include "player_character.hpp" #include "player_character.hpp"
#include "projectile_pool.hpp" #include "projectile_pool.hpp"
#include "state_machine.hpp"
#include "utils/godot_macros.h" #include "utils/godot_macros.h"
#include <godot_cpp/classes/navigation_agent3d.hpp> #include <godot_cpp/classes/navigation_agent3d.hpp>
#include <godot_cpp/classes/time.hpp> #include <godot_cpp/classes/time.hpp>
@ -16,12 +17,14 @@ void PlayerCharacter::_enter_tree() { GDGAMEONLY();
this->target_rotation = this->get_global_transform().get_basis().get_quaternion(); this->target_rotation = this->get_global_transform().get_basis().get_quaternion();
this->health = this->get_node<Health>("Health"); this->health = this->get_node<Health>("Health");
this->primary_weapon_pool = this->get_node<ProjectilePool>("ProjectilePool"); this->primary_weapon_pool = this->get_node<ProjectilePool>("ProjectilePool");
this->state_machine = this->get_node<StateMachine>("StateMachine");
} }
void PlayerCharacter::_process(double delta_time) { GDGAMEONLY(); void PlayerCharacter::_process(double delta_time) { GDGAMEONLY();
this->process_rotation(delta_time); this->process_rotation(delta_time);
if(!this->mode_manual) if(!this->mode_manual) {
this->process_ai(delta_time); this->process_ai(delta_time);
}
if(this->firing) if(this->firing)
this->try_fire_weapon(); this->try_fire_weapon();
} }
@ -41,7 +44,7 @@ void PlayerCharacter::move(Vector3 world_vector) {
} }
void PlayerCharacter::aim(Vector3 at) { void PlayerCharacter::aim(Vector3 at) {
// calculate the forward vector by normalized difference between player character and the target // calculate the forward vector by normalized difference between player character and the target on the XZ plane
Vector3 const position{this->weapon_muzzle->get_global_position()}; Vector3 const position{this->weapon_muzzle->get_global_position()};
Vector3 const forward{(Vector3{at.x, 0.f, at.z} - Vector3{position.x, 0.f, position.z}).normalized()}; Vector3 const forward{(Vector3{at.x, 0.f, at.z} - Vector3{position.x, 0.f, position.z}).normalized()};
// we always want up to be the global unit up // we always want up to be the global unit up
@ -50,13 +53,27 @@ void PlayerCharacter::aim(Vector3 at) {
this->target_rotation = Basis{up.cross(forward), up, forward}; this->target_rotation = Basis{up.cross(forward), up, forward};
} }
void PlayerCharacter::move_to(Vector3 to, float target_distance) {
this->nav_agent->set_target_desired_distance(target_distance);
this->nav_agent->set_target_position(this->get_global_position().distance_squared_to(to) < target_distance * target_distance
? this->get_global_position()
: to);
}
void PlayerCharacter::shoot_at(Vector3 at) {
this->aim(at);
this->set_firing(true);
}
void PlayerCharacter::set_firing(bool firing) { void PlayerCharacter::set_firing(bool firing) {
this->firing = firing; this->firing = firing;
} }
void PlayerCharacter::set_manual_mode(bool value) { void PlayerCharacter::set_manual_mode(bool value) {
this->mode_manual = value; this->mode_manual = value;
this->nav_agent->set_process_mode(value ? ProcessMode::PROCESS_MODE_PAUSABLE : ProcessMode::PROCESS_MODE_DISABLED); ProcessMode const mode = value ? ProcessMode::PROCESS_MODE_DISABLED : ProcessMode::PROCESS_MODE_PAUSABLE;
this->nav_agent->set_process_mode(mode);
this->state_machine->set_process_mode(mode);
} }
void PlayerCharacter::set_rotation_speed_curve(Ref<Curve> curve) { void PlayerCharacter::set_rotation_speed_curve(Ref<Curve> curve) {
@ -77,9 +94,6 @@ Health const *PlayerCharacter::get_health() const {
void PlayerCharacter::set_character_data(Ref<CharacterData> data) { void PlayerCharacter::set_character_data(Ref<CharacterData> data) {
this->data = data; this->data = data;
UtilityFunctions::print("PlayerCharacter::set_character_data");
UtilityFunctions::print(" - data: ", data->get_path());
UtilityFunctions::print(" - weapon: ", data->get_weapon()->get_path());
this->fire_interval = 1.f / this->data->get_weapon()->get_rounds_per_second(); this->fire_interval = 1.f / this->data->get_weapon()->get_rounds_per_second();
this->primary_weapon_pool->set_data(this->data->get_weapon()); this->primary_weapon_pool->set_data(this->data->get_weapon());
} }
@ -89,7 +103,13 @@ void PlayerCharacter::set_weapon_muzzle(Node3D *node) {
} }
void PlayerCharacter::process_ai(double delta_time) { void PlayerCharacter::process_ai(double delta_time) {
this->velocity_target = this->nav_agent->get_velocity(); if(this->nav_agent->is_navigation_finished()) {
this->move(Vector3());
} else {
Vector3 const target_position = this->nav_agent->get_next_path_position();
Vector3 const direction = (target_position - this->get_global_position()).normalized();
this->move(direction);
}
} }
void PlayerCharacter::process_rotation(double delta_time) { void PlayerCharacter::process_rotation(double delta_time) {

View file

@ -9,6 +9,8 @@
namespace godot { namespace godot {
class NavigationAgent3D; class NavigationAgent3D;
class StateMachine;
class TunnelsPlayer;
class PlayerCharacter : public CharacterBody3D, class PlayerCharacter : public CharacterBody3D,
public IHealthEntity { public IHealthEntity {
@ -20,6 +22,8 @@ public:
virtual void _physics_process(double delta_time) override; virtual void _physics_process(double delta_time) override;
void move(Vector3 world_vector); void move(Vector3 world_vector);
void aim(Vector3 at); void aim(Vector3 at);
void move_to(Vector3 to, float target_distance = 0.5f);
void shoot_at(Vector3 at);
void set_firing(bool firing); void set_firing(bool firing);
void set_manual_mode(bool value); void set_manual_mode(bool value);
@ -38,6 +42,7 @@ protected:
void try_fire_weapon(); void try_fire_weapon();
private: private:
Vector3 velocity_target{0.f,0.f,0.f}; Vector3 velocity_target{0.f,0.f,0.f};
StateMachine *state_machine{nullptr};
Basis target_rotation{}; Basis target_rotation{};
NavigationAgent3D *nav_agent{nullptr}; NavigationAgent3D *nav_agent{nullptr};
bool mode_manual{false}; bool mode_manual{false};