generated from Persson-dev/Godot-Xmake
85 lines
2.8 KiB
C++
85 lines
2.8 KiB
C++
#include "Zombie.h"
|
|
|
|
#include <godot_cpp/classes/engine.hpp>
|
|
#include <godot_cpp/core/math.hpp>
|
|
|
|
using namespace godot;
|
|
|
|
namespace blitz {
|
|
|
|
static constexpr float SPEED = 2.0f;
|
|
static constexpr float ATTACK_RANGE = 2.0f;
|
|
|
|
void Zombie::_bind_methods() {
|
|
ClassDB::bind_method(D_METHOD("set_m_PlayerPath", "m_PlayerPath"), &Zombie::set_m_PlayerPath);
|
|
ClassDB::bind_method(D_METHOD("get_m_PlayerPath"), &Zombie::get_m_PlayerPath);
|
|
ClassDB::bind_method(D_METHOD("hit_finished"), &Zombie::hit_finished);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "m_PlayerPath"), "set_m_PlayerPath", "get_m_PlayerPath");
|
|
}
|
|
|
|
Zombie::Zombie() {}
|
|
|
|
Zombie::~Zombie() {}
|
|
|
|
void Zombie::_ready() {
|
|
#if DEBUG_ENABLED
|
|
if (Engine::get_singleton()->is_editor_hint()) {
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
m_Player = Object::cast_to<FirstPersonPlayer>(get_parent()->get_parent()->find_child("FirstPersonPlayer"));
|
|
DEV_ASSERT(m_Player);
|
|
m_NavigationAgent = Object::cast_to<NavigationAgent3D>(find_child("NavigationAgent3D"));
|
|
DEV_ASSERT(m_NavigationAgent);
|
|
m_AnimationTree = Object::cast_to<AnimationTree>(find_child("AnimationTree"));
|
|
DEV_ASSERT(m_AnimationTree);
|
|
m_StateMachine = Object::cast_to<AnimationNodeStateMachinePlayback>(m_AnimationTree->get("parameters/playback"));
|
|
DEV_ASSERT(m_StateMachine);
|
|
this->set_velocity(Vector3(0, 0, 0));
|
|
}
|
|
|
|
void Zombie::_process(float a_Delta) {
|
|
#if DEBUG_ENABLED
|
|
if (Engine::get_singleton()->is_editor_hint()) {
|
|
return;
|
|
}
|
|
#endif
|
|
if (m_StateMachine->get_current_node().match("Run")) {
|
|
m_NavigationAgent->set_target_position(m_Player->get_global_position());
|
|
m_Velocity = (m_NavigationAgent->get_next_path_position() - this->get_global_position()).normalized() * SPEED;
|
|
this->set_velocity(m_Velocity);
|
|
look_at(Vector3(this->get_global_position().x + this->get_velocity().x, this->get_global_position().y,
|
|
this->get_global_position().z + this->get_velocity().z));
|
|
|
|
} else if (m_StateMachine->get_current_node().match("Attack")) {
|
|
this->set_velocity(Vector3(0, 0, 0));
|
|
look_at(Vector3(m_Player->get_global_position().x + this->get_velocity().x, this->get_global_position().y,
|
|
m_Player->get_global_position().z + this->get_velocity().z));
|
|
}
|
|
m_AnimationTree->set("parameters/conditions/run", !_target_in_range());
|
|
m_AnimationTree->set("parameters/conditions/attack", _target_in_range());
|
|
|
|
move_and_slide();
|
|
}
|
|
|
|
bool Zombie::_target_in_range() {
|
|
return this->get_global_position().distance_to(m_Player->get_global_position()) < ATTACK_RANGE;
|
|
}
|
|
|
|
void Zombie::set_m_PlayerPath(const NodePath& path) {
|
|
m_PlayerPath = path;
|
|
}
|
|
|
|
NodePath Zombie::get_m_PlayerPath() const {
|
|
return m_PlayerPath;
|
|
}
|
|
|
|
void Zombie::hit_finished() {
|
|
if (this->get_global_position().distance_to(m_Player->get_global_position()) < (ATTACK_RANGE + 1.0)) {
|
|
Vector3 dir = this->get_global_position().direction_to(m_Player->get_global_position());
|
|
m_Player->hit(dir);
|
|
}
|
|
}
|
|
} // namespace blitz
|