Saltar al contenido

🎮 Cómo Evitar que un Enemigo se Quede Atascado en Unity (Detección de Stuck)

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:

  1. Selecciona el Enemigo en la Jerarquía (Hierarchy).
  2. Revisa el NavMeshAgent en el Inspector:
    • Speed: 3.5
    • Acceleration: 8
    • Angular Speed: 120
    • Stopping Distance: 1.0
    • Auto Repath debe estar activado
  3. 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.

Etiquetas:

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Información básica sobre protección de datos Ver más

  • Responsable: Tomas Gonzalez.
  • Finalidad:  Moderar los comentarios.
  • Legitimación:  Por consentimiento del interesado.
  • Destinatarios y encargados de tratamiento:  No se ceden o comunican datos a terceros para prestar este servicio.
  • Derechos: Acceder, rectificar y suprimir los datos.
  • Información Adicional: Puede consultar la información detallada en la Política de Privacidad.

error: Content is protected !!

Descubre más desde Tomás González: Formador y Desarrollador Web

Suscríbete ahora para seguir leyendo y obtener acceso al archivo completo.

Seguir leyendo

Este sitio web utiliza cookies, si necesitas más información puedes visitar nuestra política de privacidad    Ver
Privacidad