From e882b63b28a117005a133c3f7006a92488d85fb5 Mon Sep 17 00:00:00 2001 From: Sara Date: Sun, 21 Apr 2024 15:35:40 +0200 Subject: [PATCH] feat: CharacterActor acceleration walk_speed sprint_speed and rotation_speed are now variable --- src/character_actor.cpp | 74 ++++++++++++++++++++++++++++++++--------- src/character_actor.hpp | 24 ++++++++++--- 2 files changed, 78 insertions(+), 20 deletions(-) diff --git a/src/character_actor.cpp b/src/character_actor.cpp index 9bf0a1f..273d0fb 100644 --- a/src/character_actor.cpp +++ b/src/character_actor.cpp @@ -1,4 +1,5 @@ #include "character_actor.hpp" +#include "goal_marker.hpp" #include "planner.hpp" #include "projectile_pool.hpp" #include "state.hpp" @@ -15,8 +16,11 @@ namespace godot { void CharacterActor::_bind_methods() { #define CLASSNAME CharacterActor GDPROPERTY_HINTED(rotation_speed_curve, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Curve"); - GDFUNCTION_ARGS(set_velocity_target, "value"); GDPROPERTY_HINTED(target, Variant::OBJECT, PROPERTY_HINT_NODE_TYPE, "Node"); + GDPROPERTY(acceleration, Variant::FLOAT); + GDPROPERTY(walk_speed, Variant::FLOAT); + GDPROPERTY(sprint_speed, Variant::FLOAT); + GDPROPERTY(rotation_speed, Variant::FLOAT); GDFUNCTION(get_is_near_player); } @@ -46,7 +50,7 @@ void CharacterActor::_process(double delta_time) { GDGAMEONLY(); void CharacterActor::_physics_process(double delta_time) { GDGAMEONLY(); // accelerate towards velocity target - Vector3 const new_velocity = this->get_velocity().move_toward(this->velocity_target, delta_time * CharacterActor::ACCELERATION); + Vector3 const new_velocity = this->get_velocity().move_toward(this->velocity_target, delta_time * CharacterActor::acceleration); Vector3 const gravity{Vector3{0.f, this->get_velocity().y - 9.8f, 0.f}}; // apply either gravity or walking velocity depending on results this->set_velocity(this->is_on_floor() ? new_velocity : this->get_velocity() + gravity); @@ -55,7 +59,7 @@ void CharacterActor::_physics_process(double delta_time) { GDGAMEONLY(); } void CharacterActor::move(Vector3 world_vector) { - this->velocity_target = world_vector * CharacterActor::WALK_SPEED; + this->velocity_target = world_vector * CharacterActor::walk_speed; } void CharacterActor::aim(Vector3 at) { @@ -144,12 +148,21 @@ bool CharacterActor::get_is_near_player() const { } bool CharacterActor::get_is_near_target() const { + GoalMarker *target_marker = Object::cast_to(this->target); Node3D *target_node3d = Object::cast_to(this->target); - return target_node3d ? target_node3d->get_global_position().distance_to(this->get_global_position()) < 5.f : false; + return target_marker + ? target_marker->is_point_on(this->get_global_position()) + : (target_node3d && target_node3d->get_global_position().distance_to(this->get_global_position()) < 5.f); } -goap::Planner *CharacterActor::get_planner() const { - return this->planner; +Vector3 CharacterActor::get_move_target() const { + GoalMarker *as_marker = Object::cast_to(this->current_state.move_to); + if(as_marker) + return as_marker->nearest_point_on(this->get_global_position()); + Node3D *as_node3d = Object::cast_to(this->current_state.move_to); + if(as_node3d) + return as_node3d->get_global_position(); + return this->get_global_position(); } void CharacterActor::set_target(Node *target) { @@ -160,6 +173,10 @@ Node *CharacterActor::get_target() const { return this->target; } +goap::Planner *CharacterActor::get_planner() const { + return this->planner; +} + void CharacterActor::set_state(goap::State state) { switch(this->current_state.type) { default: @@ -173,7 +190,7 @@ void CharacterActor::set_state(goap::State state) { default: break; case goap::State::STATE_MOVE_TO: - this->move_to(state.move_to->get_global_position()); + this->move_to(this->get_move_target()); break; } } @@ -185,8 +202,8 @@ void CharacterActor::process_behaviour(double delta_time) { default: break; case goap::State::STATE_MOVE_TO: - if(this->nav_agent->get_target_position().distance_to(this->current_state.move_to->get_global_position()) > 2.f) - this->nav_agent->set_target_position(this->current_state.move_to->get_global_position()); + if(this->nav_agent->get_target_position().distance_to(this->get_move_target()) > 2.f) + this->nav_agent->set_target_position(this->get_move_target()); break; case goap::State::STATE_ACTIVATE: break; @@ -202,7 +219,7 @@ void CharacterActor::process_navigation(double delta_time) { Vector3 const target_position = this->nav_agent->get_next_path_position(); Vector3 const direction = (target_position - this->get_global_position()).normalized(); if(this->nav_agent->get_avoidance_enabled()) - this->nav_agent->set_velocity(direction * CharacterActor::WALK_SPEED); + this->nav_agent->set_velocity(direction * CharacterActor::walk_speed); else this->move(direction); } @@ -219,7 +236,7 @@ void CharacterActor::process_rotation(double delta_time) { // calculate the angle that still needs to be traveled float const angle = current_quaternion.angle_to(target_quaternion); // calculate the angle amount that can be moved this frame - float const angle_step{float(this->rotation_speed_curve->sample(angle) * CharacterActor::ROTATION_SPEED * delta_time)}; + float const angle_step{float(this->rotation_speed_curve->sample(angle) * CharacterActor::rotation_speed * delta_time)}; // update this object's global transform with the new rotation basis.set_quaternion(angle < angle_step ? target_quaternion // to avoid overshooting, check if the max step is smaller than the angle distance : current_quaternion.slerp(target_quaternion, angle_step / angle)); // convert the angle step to a lerp t value between current and target rotations @@ -238,8 +255,35 @@ void CharacterActor::try_fire_weapon() { node->set_global_transform(this->weapon_muzzle->get_global_transform()); } -float const CharacterActor::ACCELERATION{20.f}; -float const CharacterActor::WALK_SPEED{3.f}; -float const CharacterActor::SPRINT_SPEED{5.f}; -float const CharacterActor::ROTATION_SPEED{10.f}; +void CharacterActor::set_acceleration(float acceleration) { + this->acceleration = acceleration; +} + +float CharacterActor::get_acceleration() const { + return this->acceleration; +} + +void CharacterActor::set_walk_speed(float walk_speed) { + this->walk_speed = walk_speed; +} + +float CharacterActor::get_walk_speed() const { + return this->walk_speed; +} + +void CharacterActor::set_sprint_speed(float sprint_speed) { + this->sprint_speed = sprint_speed; +} + +float CharacterActor::get_sprint_speed() const { + return this->sprint_speed; +} + +void CharacterActor::set_rotation_speed(float rotation_speed) { + this->rotation_speed = rotation_speed; +} + +float CharacterActor::get_rotation_speed() const { + return this->rotation_speed; +} } diff --git a/src/character_actor.hpp b/src/character_actor.hpp index d4d72a2..213e572 100644 --- a/src/character_actor.hpp +++ b/src/character_actor.hpp @@ -53,12 +53,26 @@ public: void set_weapon_muzzle(Node3D *node); void set_velocity_target(Vector3 value); Vector3 get_velocity_target() const; + + // planner getters bool get_is_near_player() const; bool get_is_near_target() const; - goap::Planner *get_planner() const; + Vector3 get_move_target() const; + + // getter - setters void set_target(Node *target); Node *get_target() const; + goap::Planner *get_planner() const; void set_state(goap::State state); + + void set_acceleration(float acceleration); + float get_acceleration() const; + void set_walk_speed(float walk_speed); + float get_walk_speed() const; + void set_sprint_speed(float sprint_speed); + float get_sprint_speed() const; + void set_rotation_speed(float rotation_speed); + float get_rotation_speed() const; protected: void process_behaviour(double delta_time); void process_navigation(double delta_time); @@ -93,10 +107,10 @@ private: Ref data; float fire_interval{0.f}; // derived from 1 / the current weapon's rps - static float const ACCELERATION; - static float const WALK_SPEED; - static float const SPRINT_SPEED; - static float const ROTATION_SPEED; + float acceleration{20.f}; + float walk_speed{3.f}; + float sprint_speed{5.f}; + float rotation_speed{10.f}; }; }