using System.Linq; using Unity.VisualScripting; using UnityEngine; using UnityEngine.AI; public enum TargetType { Gate, Wall, Tower, Any } public class EnemyController : MonoBehaviour { public float moveSpeed; public float targetRange; public float attackRange; public float attackSpeed; public float attackDamage; public TargetType targetType; public Transform target; private NavMeshAgent navMeshAgent; private Animator animator; private SphereCollider targetCollider; private float attackCooldown; void Awake() { navMeshAgent = GetComponent(); animator = GetComponentInChildren(); targetCollider = GetComponentInChildren(); navMeshAgent.speed = moveSpeed; targetCollider.radius = targetRange; } void Start() { GetTarget(targetType); } void Update() { if (target != null && !target.gameObject.activeInHierarchy) { target = null; GetTarget(targetType); } if (target != null) Attack(); animator.SetFloat("Speed", navMeshAgent.velocity.magnitude); } private void OnTriggerEnter(Collider other) { if (target != null) return; if (!other.CompareTag("Gate")) return; AttackPoint attackPoint = other.GetComponentInChildren(); if (attackPoint != null && targetType == TargetType.Any) { target = attackPoint.transform; navMeshAgent.stoppingDistance = attackRange; navMeshAgent.destination = attackPoint.transform.position; } } private void GetTarget(TargetType targetType) { GameObject[] potentialTargets; GameObject closest = null; float minDistance = Mathf.Infinity; switch (targetType) { case TargetType.Gate: potentialTargets = GameObject.FindGameObjectsWithTag("Gate"); foreach (GameObject go in potentialTargets) { float distance = Vector3.Distance(go.transform.position, transform.position); if (distance < minDistance) { minDistance = distance; closest = go; } } break; case TargetType.Wall: potentialTargets = GameObject.FindGameObjectsWithTag("Wall"); foreach (GameObject go in potentialTargets) { float distance = Vector3.Distance(go.transform.position, transform.position); if (distance < minDistance) { minDistance = distance; closest = go; } } break; case TargetType.Tower: potentialTargets = GameObject.FindGameObjectsWithTag("Tower"); foreach (GameObject go in potentialTargets) { float distance = Vector3.Distance(go.transform.position, transform.position); if (distance < minDistance) { minDistance = distance; closest = go; } } break; case TargetType.Any: potentialTargets = GameObject.FindGameObjectsWithTag("Gate") .Concat(GameObject.FindGameObjectsWithTag("Wall")) .Concat(GameObject.FindGameObjectsWithTag("Tower")).ToArray(); foreach (GameObject go in potentialTargets) { float distance = Vector3.Distance(go.transform.position, transform.position); if (distance < minDistance) { minDistance = distance; closest = go; } } break; } if (closest != null) { AttackPoint attackPoint = closest.GetComponentInChildren(); if (attackPoint != null) { target = attackPoint.transform; navMeshAgent.stoppingDistance = attackRange; navMeshAgent.destination = target.position; } } } private void Attack() { attackCooldown -= Time.deltaTime; if (Vector3.Distance(target.position, transform.position) < attackRange && attackCooldown <= 0f) { transform.LookAt(target.position); animator.SetTrigger("Attack"); attackCooldown = 1f / attackSpeed; target.GetComponent().AddAttacker(); target.GetComponentInParent().TakeDamage(attackDamage); } } /*private void OnDrawGizmosSelected() { // Target range — green if priority target is assigned, red if not Gizmos.color = target != null ? Color.green : Color.red; Gizmos.DrawWireSphere(transform.position, targetRange); // Attack range — green if target is within attack range, red if not bool inAttackRange = target != null && Vector3.Distance(target.position, transform.position) < attackRange; Gizmos.color = inAttackRange ? Color.green : Color.red; Gizmos.DrawWireSphere(transform.position, attackRange); }*/ }