#include "Zombie.h" #include #include 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(get_parent()->get_parent()->find_child("FirstPersonPlayer")); DEV_ASSERT(m_Player); m_NavigationAgent = Object::cast_to(find_child("NavigationAgent3D")); DEV_ASSERT(m_NavigationAgent); m_AnimationTree = Object::cast_to(find_child("AnimationTree")); DEV_ASSERT(m_AnimationTree); m_StateMachine = Object::cast_to(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