Aprende a configurar NPCs (Non-Player Character) en Unity con un flujo sencillo y efectivo. Reutiliza sprites, configura colisiones y física, y programa un movimiento errático aleatorio con pausas para simular vida en un RPG. Sin animaciones adicionales y con pocas líneas de código, obtendrás resultados claros y escalables.
¿Cómo crear un NPC en Unity con movimiento aleatorio?
Coloca en escena un sprite existente y distínguelo del personaje con un tinte de color. La idea es reutilizar gráficos (por ejemplo, un conejo) y evitar animaciones: el NPC no rota ni anima, solo se desplaza en cuatro direcciones.
- Reutiliza el sprite del personaje y aplica un color distinto para identificar al NPC.
- Nómbralo de forma genérica (por ejemplo, “NPC”) para crear luego un prefab reutilizable.
- El movimiento será aleatorio en 4 direcciones (sin diagonales) y con pausas intercaladas.
¿Cómo definir variables clave para el movimiento?
Gestiona velocidad, estados y tiempos con contadores. Usa Vector2 para las direcciones.
- Velocidad:
public float speed = 1.5f;.
- Estado:
public bool isWalking para saber si camina o espera.
- Tiempos:
public float walkTime; public float waitTime = 3f;.
- Contadores:
private float walkCounter; private float waitCounter;.
- Física: referencia a
Rigidbody2D como npcRigidbody.
- Direcciones: arreglo de Vector2 con las cuatro direcciones cardinales.
¿Qué lógica alterna caminar y esperar?
Alterna entre caminar y esperar con contadores que decrecen con Time.deltaTime. Selecciona dirección con Random.Range(0, 4).
- Al iniciar caminar: activa
isWalking, elige currentDirection y ajusta walkCounter.
- Al parar: desactiva
isWalking, reinicia waitCounter y pone la velocity a cero.
- En Update: si camina, mueve según dirección por
speed. Si espera, queda en reposo.
using UnityEngine;
public class NPCMovement : MonoBehaviour
{
public float speed = 1.5f;
public bool isWalking;
public float walkTime; // editable en el editor.
public float waitTime = 3f; // pausa entre movimientos.
private float walkCounter;
private float waitCounter;
private Rigidbody2D npcRigidbody;
private Vector2[] walkingDirections = new Vector2[]
{
new Vector2(1, 0), // derecha
new Vector2(0, 1), // arriba
new Vector2(-1, 0), // izquierda
new Vector2(0, -1) // abajo
};
private int currentDirection; // 0..3
void Start()
{
npcRigidbody = GetComponent<Rigidbody2D>();
waitCounter = waitTime;
walkCounter = walkTime;
}
void Update()
{
if (isWalking)
{
walkCounter -= Time.deltaTime;
npcRigidbody.velocity = walkingDirections[currentDirection] * speed;
if (walkCounter < 0f)
StopWalking();
}
else
{
waitCounter -= Time.deltaTime;
npcRigidbody.velocity = Vector2.zero;
if (waitCounter < 0f)
StartWalking();
}
}
private void StartWalking()
{
isWalking = true;
currentDirection = Random.Range(0, 4);
walkCounter = walkTime;
}
private void StopWalking()
{
isWalking = false;
waitCounter = waitTime;
npcRigidbody.velocity = Vector2.zero;
}
}
¿Qué componentes y ajustes evitarán problemas de física y render?
Para que el NPC se comporte bien en escena, combina colisión, física y orden de render.
- Colisión: añade un BoxCollider2D un poco más grande de lo habitual.
- Física: añade Rigidbody2D y configura:
- gravityScale en 0 para evitar caída.
- Bloquea la rotación en eje Z para que no gire con choques.
- Render: usa la misma sorting layer y order in layer que el personaje, con z = 0.
¿Cómo evitar que el jugador empuje al NPC?
Si al chocar el jugador lo mueve, aumenta la masa del NPC para resistir empujes.
- Aumentar masa dificulta el arrastre por colisiones.
- Alternativa posible: definir capas sin colisión entre jugador y NPC.
¿Qué buenas prácticas mejoran la escalabilidad del sistema?
Pequeñas decisiones aceleran el trabajo y reducen errores al crecer el proyecto.
- Crea un prefab del NPC para replicarlo con la misma lógica y parámetros.
- Mantén nombres claros: npcRigidbody, walkCounter, waitCounter, walkingDirections.
- Controla errores al autocompletar variables con nombres similares (por ejemplo,
waitTime vs walkTime).
- Ajusta
walkTime y waitTime desde el inspector para tunear el ritmo del mundo.
- Recuerda: el motor de físicas mueve al NPC al asignar velocity; no multipliques por Time.deltaTime en ese caso.
¿Te animas a ampliar el comportamiento, añadir diálogos o más gráficos para tus habitantes? Cuéntame qué misiones te gustaría que entregaran tus NPCs.