feat: units hold formation while patrolling

This commit is contained in:
Sara 2025-07-21 16:50:58 +02:00
parent c05d3aa28f
commit ec6fc76335
7 changed files with 31 additions and 11 deletions

View file

@ -46,6 +46,10 @@ NavigationAgent3D *WretchedState::get_nav() const {
return this->nav;
}
void WretchedPatrolState::set_patrol_target(Vector3 path_point) {
get_nav()->set_target_position(path_point + get_target()->get_unit_offset_3d());
}
void WretchedPatrolState::enter_state() {
this->path = get_target()->get_unit()->get_patrol_path();
@ -53,13 +57,13 @@ void WretchedPatrolState::enter_state() {
get_target()->set_movement_speed(max_speed);
get_nav()->set_max_speed(max_speed);
Vector3 const nav_target{ this->path->get_closest_point(get_target()->get_global_position(), &this->path_point) };
get_nav()->set_target_position(nav_target);
set_patrol_target(nav_target);
}
void WretchedPatrolState::process(double delta) {
if (get_nav()->is_navigation_finished()) {
this->path_point += 1;
get_nav()->set_target_position(this->path->point_at(this->path_point));
set_patrol_target(this->path->point_at(this->path_point));
}
Vector3 const direction{ get_target()->get_global_position().direction_to(get_nav()->get_next_path_position()) };
get_target()->set_movement_direction(Vector2{ direction.x, direction.z }.normalized());

View file

@ -36,6 +36,7 @@ private:
class WretchedPatrolState : public WretchedState {
GDCLASS(WretchedPatrolState, WretchedState);
static void _bind_methods() {}
void set_patrol_target(Vector3 path_point);
public:
virtual void enter_state() override;

View file

@ -59,3 +59,15 @@ void EnemyBody::set_movement_speed(float value) {
float EnemyBody::get_movement_speed() const {
return this->movement_speed;
}
void EnemyBody::set_unit_offset(Vector2 offset) {
this->unit_offset = offset;
}
Vector2 EnemyBody::get_unit_offset() const {
return this->unit_offset;
}
Vector3 EnemyBody::get_unit_offset_3d() const {
return { this->unit_offset.x, 0, this->unit_offset.y };
}

View file

@ -23,6 +23,9 @@ public:
NavigationAgent3D *get_nav() const;
void set_movement_speed(float value);
float get_movement_speed() const;
void set_unit_offset(Vector2 offset);
Vector2 get_unit_offset() const;
Vector3 get_unit_offset_3d() const;
private:
float movement_speed{ 1.f };
@ -31,6 +34,7 @@ private:
StateMachine *fsm{ nullptr };
NpcUnit *unit{ nullptr };
NavigationAgent3D *nav{ nullptr };
Vector2 unit_offset{ 0, 0 };
};
#endif // !ENEMY_BODY_H

View file

@ -18,10 +18,13 @@ void NpcUnit::child_added(Node *node) {
if (EnemyBody * npc{ cast_to<EnemyBody>(node) }) {
this->npcs.push_back(npc);
npc->set_unit(this);
PlayerDetector *detector{ cast_to<PlayerDetector>(npc->get_node(NodePath("%PlayerDetector"))) };
Vector3 const offset{ npc->get_global_position() - get_global_position() };
npc->set_unit_offset({ offset.x, offset.z });
if (PlayerDetector * detector{ cast_to<PlayerDetector>(npc->get_node(NodePath("%PlayerDetector"))) }) {
detector->connect(PlayerDetector::sig_awareness_changed, callable_mp(this, &self_type::on_npc_awareness_changed));
}
}
}
void NpcUnit::enter_tree() {
this->connect("child_entered_tree", callable_mp(this, &self_type::child_added));

View file

@ -1,13 +1,13 @@
#ifndef NPC_UNIT_H
#define NPC_UNIT_H
#include "scene/main/node.h"
#include "scene/3d/node_3d.h"
class StateMachine;
class EnemyBody;
class PatrolPath;
class NpcUnit : public Node {
GDCLASS(NpcUnit, Node);
class NpcUnit : public Node3D {
GDCLASS(NpcUnit, Node3D);
static void _bind_methods();
void on_npc_awareness_changed(bool seen);
void child_added(Node *node);

View file

@ -56,8 +56,4 @@ void StateMachine::add_state(State *state) {
if (this->current_state == nullptr) {
this->switch_to_state(state);
}
print_line("states:");
for (KeyValue<StringName, State *> kv : this->states) {
print_line(vformat("\t\t| %s %s", kv.key, kv.value));
}
}