Fronteras para NPCs: evita que se pierdan

Clase 43 de 60Curso Avanzado de Creación de RPGs con Unity

Resumen

Controla con precisión el movimiento aleatorio de tu NPC en Unity: evita que se pierda por el mapa, salga del escenario o entre en zonas ilógicas. Aquí verás cómo definir una frontera de movimiento y cómo hacer que el script la respete, sin romper la naturalidad del paseo.

¿Cómo evitar que un NPC se pierda por el mapa?

Cuando un NPC elige una dirección cada pocos segundos y camina de forma aleatoria, puede alejarse demasiado o incluso salir del escenario. La solución es definir una zona de movimiento con una caja que actúe como límite.

  • Crea un GameObject vacío llamado "Villager Zone".
  • Añade un BoxCollider2D y deja el tamaño base en 1x1.
  • Escálalo en horizontal y vertical para marcar la zona permitida.
  • No es obligatorio centrar la caja en el NPC: puede estar en una esquina si te conviene.
  • Activa el parámetro isTrigger para evitar colisiones no deseadas con el jugador u otros objetos.
  • Usa un nombre genérico si vas a crear un prefab, pero cada NPC puede tener su propia zona.

Idea clave: la caja define los límites exactos por donde el NPC puede moverse; así no cruzará el camino si no quieres, o no entrará en la armería por accidente.

¿Qué ventajas tiene esta frontera?

  • Mantiene al NPC en un área coherente con la escena.
  • Evita misiones imposibles por NPCs inubicables.
  • Permite personalizar el comportamiento de varios NPCs con zonas distintas.

¿Qué cambios aplicar en el script para respetar la zona?

Necesitas exponer la zona al script y detener el movimiento al alcanzar cualquier borde de la caja. Así conservas el paseo aleatorio, pero dentro de los límites.

  • Declara en tu script (por ejemplo, en npcMovement): una variable pública del tipo BoxCollider2D llamada villagerZone.
  • En el editor, arrastra la "Villager Zone" al campo villagerZone del NPC.
  • En Update, si villagerZone no es null, comprueba los cuatro bordes con villagerZone.bounds.min y villagerZone.bounds.max.
  • Si se supera izquierda, derecha, abajo o arriba, llama al método stopWalking() para frenar en seco, poner velocidad en 0 y reiniciar el contador de movimiento.
  • Atención a los ejes: x con x e y con y; no los cruces.
public BoxCollider2D villagerZone; // zona permitida

void Update()
{
    // ... lógica previa, por ejemplo: si estamos caminando

    if (villagerZone != null)
    {
        var pos = transform.position;
        var bounds = villagerZone.bounds;

        bool fueraIzquierda = pos.x < bounds.min.x;
        bool fueraDerecha  = pos.x > bounds.max.x;
        bool fueraAbajo    = pos.y < bounds.min.y;
        bool fueraArriba   = pos.y > bounds.max.y;

        if (fueraIzquierda || fueraDerecha || fueraAbajo || fueraArriba)
        {
            stopWalking();
        }
    }

    // ... resto de la lógica de movimiento
}

Idea clave: villagerZone != null te permite tener dos comportamientos: NPCs libres por el pueblo o NPCs limitados a su área.

¿Cómo vincular bien las referencias?

  • Arrastra la "Villager Zone" al campo villagerZone del NPC en el editor.
  • Asegúrate de que isTrigger esté activo en la zona para no bloquear entradas.

¿Cómo probar el sistema y gestionar empujes de enemigos?

Para verificar rápido, reduce el wait time del paseo aleatorio a un valor pequeño: así verás al NPC moverse y parar al tocar los bordes de la caja.

  • Baja el wait time para observar cambios inmediatos.
  • Verás que los enemigos pueden empujar al NPC si colisionan.
  • Si te interesa evitarlo: crea capas separadas para enemigos y NPCs y haz que no interactúen en el motor de físicas.

Idea clave: limitar el área no impide que las físicas empujen; separa capas si necesitas evitar interacciones.

¿Te gustaría que agreguemos un ejemplo con capas de físicas o ajustar el paseo aleatorio a reglas más específicas? Cuéntalo en los comentarios y seguimos construyendo juntos.

      Fronteras para NPCs: evita que se pierdan