extends CharacterBody3D
@export var player: Node3D
@export var velocidade_perseguir: float = 4.0
@export var velocidade_vagar: float = 2.0
# Distância mínima para começar a perseguir
@export var distancia_deteccao: float = 12.0
# Configurações do modo vagar
@export var raio_vagar: float = 8.0
@export var tempo_mudar_destino: float = 4.0
@onready var nav_agent: NavigationAgent3D = $NavigationAgent3D
var tempo_restante: float = 0.0
var ponto_inicial: Vector3
var gravidade: float = ProjectSettings.get_setting("physics/3d/default_gravity")
func _ready() -> void:
# Salva a posição inicial como referência para vagar na área em volta
ponto_inicial = global_position
func _physics_process(delta: float) -> void:
# Aplica a gravidade
if not is_on_floor():
velocity.y -= gravidade * delta
# Se o caminho ainda não terminou, move o inimigo
if not nav_agent.is_navigation_finished():
var proxima_posicao: Vector3 = nav_agent.get_next_path_position()
var direcao: Vector3 = (proxima_posicao - global_position)
direcao.y = 0
direcao = direcao.normalized()
if direcao != Vector3.ZERO:
look_at(global_position + direcao, Vector3.UP)
# Ajusta a velocidade conforme o estado
var vel_atual: float = velocidade_vagar
if player and global_position.distance_to(player.global_position) <= distancia_deteccao:
vel_atual = velocidade_perseguir
velocity.x = direcao.x * vel_atual
velocity.z = direcao.z * vel_atual
else:
# Para o movimento horizontal se chegou ao destino
velocity.x = move_toward(velocity.x, 0, velocidade_vagar)
velocity.z = move_toward(velocity.z, 0, velocidade_vagar)
move_and_slide()
# Lógica de atualização de destino
_atualizar_destino(delta)
func _atualizar_destino(delta: float) -> void:
if player and global_position.distance_to(player.global_position) <= distancia_deteccao:
# --- PERSEGUIR PLAYER ---
nav_agent.target_position = player.global_position
else:
# --- VAGAR ALEATORIAMENTE ---
tempo_restante -= delta
if tempo_restante <= 0.0 or nav_agent.is_navigation_finished():
tempo_restante = tempo_mudar_destino
_definir_novo_destino_aleatorio()
func _definir_novo_destino_aleatorio() -> void:
# Gera um ponto aleatório em volta da posição inicial
var offset = Vector3(
randf_range(-raio_vagar, raio_vagar),
0,
randf_range(-raio_vagar, raio_vagar)
)
var destino_aleatorio = ponto_inicial + offset
# Obtém o ponto navegável mais próximo do destino gerado
var mapa_nav = get_world_3d().navigation_map
var ponto_valido = NavigationServer3D.map_get_closest_point(mapa_nav, destino_aleatorio)
nav_agent.target_position = ponto_valido