feat: CharacterActor acceleration walk_speed sprint_speed and rotation_speed are now variable

This commit is contained in:
Sara 2024-04-21 15:35:40 +02:00
parent febfa76bb3
commit e882b63b28
2 changed files with 78 additions and 20 deletions

View file

@ -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<GoalMarker>(this->target);
Node3D *target_node3d = Object::cast_to<Node3D>(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<GoalMarker>(this->current_state.move_to);
if(as_marker)
return as_marker->nearest_point_on(this->get_global_position());
Node3D *as_node3d = Object::cast_to<Node3D>(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;
}
}

View file

@ -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<CharacterData> 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};
};
}