Advertisement
DugganSC

EnemyNavMeshAgent.cs

Apr 18th, 2025
312
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.95 KB | None | 0 0
  1. using AmazingAssets.AdvancedDissolve.Examples;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using Unity.VisualScripting;
  5. using UnityEngine;
  6. using UnityEngine.AI;
  7. using UnityEngine.Assertions;
  8.  
  9. public enum EnemyState
  10. {
  11.     Moving,
  12.     Attacking
  13. }
  14.  
  15. [RequireComponent(typeof(NavMeshAgent))]
  16. [RequireComponent(typeof(Animator))]
  17. public abstract class EnemyNavMeshAgent : MonoBehaviour, IDamageable
  18. {
  19.     [SerializeField] EnemyState _state = EnemyState.Moving;
  20.     [SerializeField] Transform _start;
  21.     [SerializeField] Transform _end;
  22.  
  23.     [SerializeField] PlayerAttackable _nearestTarget;
  24.  
  25.     protected Animator _animator;
  26.  
  27.     [SerializeField] float _health = 50f;
  28.  
  29.     NavMeshAgent _agent;
  30.  
  31.     bool _isDead = false;
  32.  
  33.     [SerializeField] float _deathDelay = 0.5f;
  34.  
  35.     public void Damage(float damage)
  36.     {
  37.         _health -= damage;
  38.  
  39.         if (_health <= 0 && !_isDead)
  40.         {
  41.             HandleDeath();
  42.         }
  43.     }
  44.  
  45.     private void HandleDeath()
  46.     {
  47.         _animator.SetTrigger("Die");
  48.         _isDead = true;
  49.  
  50.         gameObject.layer = LayerMask.NameToLayer("Default");
  51.  
  52.         // Disable the colliders
  53.         foreach (Collider collider in GetComponentsInChildren<Collider>())
  54.         {
  55.             collider.enabled = false;
  56.         }
  57.  
  58.         _agent.isStopped = true;
  59.         foreach (Renderer renderer in gameObject.GetComponentsInChildren<Renderer>())
  60.         {
  61.             AnimateCutoutAndDestroy script = gameObject.AddComponent<AnimateCutoutAndDestroy>();
  62.  
  63.             //Instantiate material and assign it to the script
  64.             script.material = renderer.material;
  65.         }
  66.     }
  67.  
  68.     public bool IsDead()
  69.     {
  70.         return _isDead;
  71.     }
  72.  
  73.     // Start is called before the first frame update
  74.     void Start()
  75.     {
  76.         _agent = GetComponent<NavMeshAgent>();
  77.         Assert.IsNotNull(_agent, "NavMeshAgent not set up!");
  78.  
  79.         transform.position = _start.position;
  80.        
  81.         _animator = GetComponent<Animator>();
  82.     }
  83.  
  84.     // Update is called once per frame
  85.     void Update()
  86.     {
  87.         if (IsDead())
  88.         {
  89.             return;
  90.         }
  91.  
  92.         Debug.Log($"Agent: {_agent != null}", this);
  93.  
  94.         if (_nearestTarget == null)
  95.         {
  96.             // Try fetching one
  97.             PlayerAttackable[] targets = GetTargets();
  98.             float closestDistance = Mathf.Infinity;
  99.             foreach (PlayerAttackable target in targets)
  100.             {
  101.                 float distanceToTarget = Vector3.Distance(transform.position, target.gameObject.transform.position);
  102.                 if (distanceToTarget < closestDistance)
  103.                 {
  104.                     NavMeshPath path = new NavMeshPath();
  105.                     if (_agent.CalculatePath(target.transform.position, path) && path.status == NavMeshPathStatus.PathComplete)
  106.                     {
  107.                         // Do we allow partial paths? Might make sense for ranged attacks.
  108.                         _nearestTarget = target;
  109.                         closestDistance = distanceToTarget;
  110.                     }
  111.                 }
  112.             }
  113.         }
  114.  
  115.         _state = _nearestTarget == null ? EnemyState.Moving : EnemyState.Attacking;
  116.  
  117.         switch (_state) {
  118.             case EnemyState.Moving:
  119.                 if (_agent && _end)
  120.                 {
  121.                     Debug.Log("Setting Destination as " + _end.position, this);
  122.                    
  123.                     _agent.SetDestination(_end.position);
  124.                 }
  125.                 break;
  126.             case EnemyState.Attacking:
  127.                 _agent.SetDestination(_nearestTarget.gameObject.transform.position);
  128.                 PerformAttack(_nearestTarget);
  129.                 break;
  130.         }
  131.                
  132.         _animator.SetFloat("Speed", _agent.velocity.magnitude);
  133.     }
  134.  
  135.     protected abstract void PerformAttack(PlayerAttackable nearestTarget);
  136.  
  137.     protected abstract PlayerAttackable[] GetTargets();
  138. }
  139.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement