Pesquisar este blog

godot inimigo seguindo playr usando o navegacao3d

 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