using UnityEngine; using UnityEngine.AI; using System.Collections.Generic; public class CriaturaAutonoma : MonoBehaviour { [Header("Configuración de Movimiento")] public float velocidadMovimiento = 5f; public float velocidadRotacion = 120f; public float radioDeteccion = 10f; public float distanciaMinimaComida = 1f; [Header("Configuración de Comportamiento")] public float tiempoExploracion = 3f; public float umbralEnergia = 30f; private Transform targetComida; private Vector3 puntoExploracion; private float temporizadorExploracion; private EstadoAgente estadoActual; private List comidasDetectadas = new List(); private float energia = 100f; // Componente NavMeshAgent (nuevo) private NavMeshAgent agent; private enum EstadoAgente { Explorando, BuscandoComida, Recolectando } void Start() { // Inicializar NavMeshAgent agent = GetComponent(); if (agent == null) agent = gameObject.AddComponent(); // Configurar agente con los valores públicos agent.speed = velocidadMovimiento; agent.angularSpeed = velocidadRotacion; agent.stoppingDistance = distanciaMinimaComida * 0.8f; // un poco menos para activar recolección agent.autoBraking = true; // frena al llegar al destino estadoActual = EstadoAgente.Explorando; GenerarNuevoPuntoExploracion(); } void Update() { // Reducir energía gradualmente energia -= Time.deltaTime * 5f; // Detectar comidas cercanas DetectarComidas(); // Actualizar comportamiento según el estado switch (estadoActual) { case EstadoAgente.Explorando: ComportamientoExploracion(); break; case EstadoAgente.BuscandoComida: ComportamientoBusquedaComida(); break; case EstadoAgente.Recolectando: ComportamientoRecoleccion(); break; } // Si la energía es muy baja, priorizar búsqueda de comida if (energia < umbralEnergia && estadoActual != EstadoAgente.BuscandoComida) { estadoActual = EstadoAgente.BuscandoComida; } } void DetectarComidas() { Collider[] colliders = Physics.OverlapSphere(transform.position, radioDeteccion); comidasDetectadas.Clear(); foreach (Collider col in colliders) { if (col.CompareTag("Comida")) { comidasDetectadas.Add(col.transform); } } // Si hay comida detectada, cambiar a modo búsqueda if (comidasDetectadas.Count > 0 && estadoActual == EstadoAgente.Explorando) { estadoActual = EstadoAgente.BuscandoComida; EncontrarComidaMasCercana(); } } void EncontrarComidaMasCercana() { float distanciaMinima = Mathf.Infinity; Transform comidaMasCercana = null; foreach (Transform comida in comidasDetectadas) { float distancia = Vector3.Distance(transform.position, comida.position); if (distancia < distanciaMinima) { distanciaMinima = distancia; comidaMasCercana = comida; } } targetComida = comidaMasCercana; } void ComportamientoExploracion() { temporizadorExploracion -= Time.deltaTime; if (temporizadorExploracion <= 0) { GenerarNuevoPuntoExploracion(); } MoverHacia(puntoExploracion); // Dibujar línea para visualizar exploración Debug.DrawLine(transform.position, puntoExploracion, Color.blue); } void ComportamientoBusquedaComida() { if (comidasDetectadas.Count == 0) { estadoActual = EstadoAgente.Explorando; return; } // Actualizar la comida más cercana EncontrarComidaMasCercana(); if (targetComida != null) { MoverHacia(targetComida.position); Debug.DrawLine(transform.position, targetComida.position, Color.green); // Verificar si está lo suficientemente cerca para recolectar float distancia = Vector3.Distance(transform.position, targetComida.position); if (distancia < distanciaMinimaComida) { estadoActual = EstadoAgente.Recolectando; } } } void ComportamientoRecoleccion() { if (targetComida == null) { estadoActual = EstadoAgente.Explorando; return; } // Recolectar la comida RecolectarComida(targetComida.gameObject); estadoActual = EstadoAgente.Explorando; } void RecolectarComida(GameObject comida) { energia += 30f; energia = Mathf.Min(energia, 100f); Destroy(comida); Debug.Log("¡Comida recolectada! Energía: " + energia); } void GenerarNuevoPuntoExploracion() { // Generar un punto aleatorio y proyectarlo sobre el NavMesh Vector3 direccionAleatoria = Random.insideUnitSphere * 5f; direccionAleatoria += transform.position; NavMeshHit hit; if (NavMesh.SamplePosition(direccionAleatoria, out hit, 5f, NavMesh.AllAreas)) { puntoExploracion = hit.position; } else { // Si no se encuentra un punto válido, usar la posición actual puntoExploracion = transform.position; } temporizadorExploracion = tiempoExploracion; } void MoverHacia(Vector3 destino) { // Usar NavMeshAgent para moverse hacia el destino if (agent != null && agent.isOnNavMesh) { agent.SetDestination(destino); } } void OnDrawGizmosSelected() { Gizmos.color = Color.yellow; Gizmos.DrawWireSphere(transform.position, radioDeteccion); } }