Si estás usando NavMeshAgent para la IA de tu enemigo, es posible que se atasque en obstáculos o en lugares donde no puede moverse correctamente. Para solucionar esto, podemos implementar detección de stuck y forzar que el enemigo busque una nueva ruta.
✅ El enemigo detectará si está atascado.
✅ Se recalculará la ruta automáticamente.
✅ Funciona con NavMeshAgent
para evitar bloqueos en obstáculos.
🔹 1. Detectar si el Enemigo está Atascado
Para saber si el enemigo se quedó atascado, podemos comparar su posición actual con su posición anterior. Si después de un tiempo su posición no ha cambiado, significa que está atascado.
📌 Código Mejorado para Detección de Stuck
Modifica tu script de movimiento del enemigo (EnemigoPersecucion.cs
) para incluir detección de stuck:
using UnityEngine;
using UnityEngine.AI;
public class EnemigoPersecucion : MonoBehaviour
{
public Transform objetivo; // Referencia al jugador
private NavMeshAgent agente;
private Vector3 posicionAnterior;
private float tiempoAtascado = 0f;
private float tiempoMaxAtascado = 2.0f; // Tiempo antes de considerar que está atascado
private float distanciaMinimaMovimiento = 0.1f; // Distancia mínima para considerar que se movió
void Start()
{
agente = GetComponent<NavMeshAgent>();
if (objetivo == null)
{
Debug.LogError("⚠️ No se ha asignado el jugador como objetivo en el Inspector.");
}
// Guardar la posición inicial
posicionAnterior = transform.position;
}
void Update()
{
if (objetivo != null)
{
// Perseguir al jugador
agente.SetDestination(objetivo.position);
}
// Comprobar si el enemigo se ha movido
if (Vector3.Distance(transform.position, posicionAnterior) < distanciaMinimaMovimiento)
{
tiempoAtascado += Time.deltaTime;
}
else
{
tiempoAtascado = 0f; // Reiniciar contador si el enemigo se movió
}
posicionAnterior = transform.position;
// Si el enemigo ha estado atascado por demasiado tiempo, recalcular la ruta
if (tiempoAtascado >= tiempoMaxAtascado)
{
Debug.Log("⚠️ Enemigo atascado. Recalculando ruta...");
agente.SetDestination(RandomNavmeshLocation(10.0f));
tiempoAtascado = 0f; // Reiniciar contador
}
}
// Método para encontrar una nueva posición aleatoria en el NavMesh
Vector3 RandomNavmeshLocation(float radius)
{
Vector3 randomDirection = Random.insideUnitSphere * radius;
randomDirection += transform.position;
NavMeshHit hit;
Vector3 finalPosition = Vector3.zero;
if (NavMesh.SamplePosition(randomDirection, out hit, radius, 1))
{
finalPosition = hit.position;
}
return finalPosition;
}
}
🔹 2. Explicación del Código
✔ Comprueba si el enemigo se ha movido en los últimos 2
segundos.
✔ Si no se movió lo suficiente (distanciaMinimaMovimiento = 0.1f
), aumenta tiempoAtascado
.
✔ Si tiempoAtascado
es mayor que tiempoMaxAtascado
, busca una nueva posición aleatoria en el NavMesh.
🔹 3. Configurar Parámetros Correctamente
Para asegurarte de que el sistema de detección funcione correctamente:
- Selecciona el
Enemigo
en la Jerarquía (Hierarchy
). - Revisa el
NavMeshAgent
en elInspector
:Speed
:3.5
Acceleration
:8
Angular Speed
:120
Stopping Distance
:1.0
Auto Repath
debe estar activado ✅
- Asegura que el
NavMesh
está bien generado (Window > AI > Navigation > Bake
).
🎯 Resultado Final
✅ El enemigo perseguirá al jugador con NavMesh.
✅ Si se queda atascado, intentará moverse a otra zona.
✅ Nunca se quedará atrapado indefinidamente en obstáculos.
