Aprende a detener por completo el movimiento de un NPC mientras hablas con él en Unity, manteniendo una lógica simple, genérica y reutilizable en C#. Con una sola variable booleana y una verificación del estado del DialogManager, tendrás diálogos fluidos y personajes que se comportan de forma coherente.
¿Cómo pausar el movimiento del NPC al iniciar un diálogo?
Para evitar que el NPC “se escape” durante la conversación, agrega una variable booleana que indique si está hablando. Con eso, el flujo del Update se corta con un simple return cuando el diálogo está activo. Así, evitas ejecutar la lógica de caminar.
- Usa una variable booleana: isTalking.
- Coloca la comprobación al inicio de Update.
- Llama a tu método de parada:
StopWalking().
- Termina el Update con
return para no procesar caminar.
// NPCMovement.cs
using UnityEngine;
public class NPCMovement : MonoBehaviour
{
public bool isWalking;
public bool isTalking; // false por defecto.
private DialogManager manager;
void Start()
{
manager = FindObjectOfType<DialogManager>();
}
void Update()
{
// Si el diálogo ya terminó, deja de "estar hablando".
if (manager != null && !manager.dialogActive)
{
isTalking = false;
}
// Si está hablando, se detiene en seco y no ejecuta nada más.
if (isTalking)
{
StopWalking();
return;
}
// Resto de la lógica de caminar/parar aleatoriamente...
// ...
}
void StopWalking()
{
// Implementación existente para detener movimiento.
}
}
¿Qué cambios aplicar en NPC Movement y NPC Dialog?
La clave es comunicar el inicio del diálogo desde el script del diálogo hacia el de movimiento, y hacerlo de forma genérica. Usa GetComponentInParent para encontrar el componente de movimiento en el objeto padre solo si existe.
¿Qué modificar en NPC movement?
- Declara isTalking junto a isWalking.
- Añade la referencia al DialogManager con FindObjectOfType.
- Controla el flujo con
if (isTalking) { StopWalking(); return; }.
¿Cómo comunicar el diálogo con el movimiento?
- Desde el script del diálogo, al iniciar la conversación, verifica si el NPC tiene el componente de movimiento en el padre.
- Si lo tiene, marca isTalking = true.
// NPCDialog.cs (fragmento dentro del momento en que inicias el diálogo)
using UnityEngine;
public class NPCDialog : MonoBehaviour
{
void TryStartDialog()
{
// Aquí ya has detectado que el jugador está en zona y ha pulsado *Intro*.
// Se ha notificado al manager para mostrar el diálogo.
var movement = GetComponentInParent<NPCMovement>(); // Ojo: in parent.
if (movement != null)
{
movement.isTalking = true; // El NPC se detiene durante el diálogo.
}
}
}
- Esta verificación asegura un diseño genérico: cualquier NPC puede tener diálogo, y solo los que se muevan serán detenidos.
- Mantienes la lógica separada: el script de diálogo no mueve, solo informa; el de movimiento decide parar o seguir.
¿Cómo reanudar el movimiento tras finalizar el diálogo?
Cuando el DialogManager indique que el diálogo ya no está activo, simplemente desactiva isTalking. La lógica de caminar se reanudará automáticamente.
- Comprueba el estado del DialogManager en cada Update.
- Si
!manager.dialogActive, pon isTalking = false.
- Al no cumplirse el
if (isTalking), el NPC vuelve a su ciclo de caminar/parar.
// Dentro de NPCMovement.Update()
if (manager != null && !manager.dialogActive)
{
isTalking = false; // El diálogo terminó, se puede volver a caminar.
}
¿Qué habilidades y keywords te llevas?
- Uso de booleans para control de estado: isWalking, isTalking.
- Gestión de flujo en Update:
return temprano para evitar lógica innecesaria.
- Comunicación entre componentes con GetComponentInParent.
- Referencias globales con FindObjectOfType al DialogManager.
- Diseño genérico: diálogo para todos los NPCs, movimiento solo para quienes tengan el componente.
- Interacción contextual: zona de activación y botón Intro para iniciar diálogo.
¿Quieres ir un paso más allá? Implementa la misma idea para tu propio personaje jugador y evita que se mueva mientras conversa con otro NPC. Comparte tu enfoque y resultados en comentarios.