Eonirr

Untitled

Apr 15th, 2025
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.07 KB | None | 0 0
  1. // EnemyStateMachine.cs
  2. public interface IEnemyState
  3. {
  4. void Enter();
  5. void Update();
  6. void Exit();
  7. }
  8.  
  9. public class EnemyStateMachine
  10. {
  11. private IEnemyState currentState;
  12.  
  13. public void ChangeState(IEnemyState newState)
  14. {
  15. currentState?.Exit();
  16. currentState = newState;
  17. currentState?.Enter();
  18. }
  19.  
  20. public void Update()
  21. {
  22. currentState?.Update();
  23. }
  24. }
  25. --------------------------------------------------------------------------------------------------------------------------------
  26. // BaseEnemy.cs
  27. using UnityEngine;
  28. using UnityEngine.AI;
  29.  
  30. [RequireComponent(typeof(NavMeshAgent))]
  31. public abstract class BaseEnemy : MonoBehaviour
  32. {
  33. [Header("BASE VALUES")]
  34. public float maxHealth;
  35. public float movementSpeed;
  36. public float attackRange;
  37. public float attackCooldown;
  38. public float damage;
  39.  
  40. protected float currentHealth;
  41. protected NavMeshAgent agent;
  42. protected Transform player;
  43. protected Animator animator;
  44. protected EnemyStateMachine stateMachine;
  45. protected WaveManager waveManager;
  46.  
  47. protected virtual void Awake()
  48. {
  49. agent = GetComponent<NavMeshAgent>();
  50. animator = GetComponentInChildren<Animator>();
  51. waveManager = GetComponentInParent<Wavemanager>();
  52. stateMachine = new EnemyStateMachine();
  53. currentHealth = maxHealth;
  54. }
  55.  
  56. protected virtual void Start()
  57. {
  58. player = waveManager.player;
  59. agent.speed = movementSpeed;
  60. }
  61.  
  62. protected virtual void Update()
  63. {
  64. stateMachine.Update();
  65. }
  66.  
  67. public virtual void TakeDamage(float amount)
  68. {
  69. currentHealth -= amount;
  70. if (currentHealth <= 0)
  71. {
  72. Die();
  73. }
  74. }
  75.  
  76. protected virtual void Die()
  77. {
  78. agent.isStopped = true;
  79. animator.SetTrigger("Die");
  80. Destroy(gameObject, 3f);
  81. }
  82.  
  83. public bool IsPlayerInRange(float range)
  84. {
  85. if (!player) return false;
  86. return Vector3.Distance(transform.position, player.position) <= range;
  87. }
  88.  
  89. public void FacePlayer()
  90. {
  91. if (!player) return;
  92. Vector3 dir = (player.position - transform.position).normalized;
  93. dir.y = 0;
  94. if (dir != Vector3.zero)
  95. {
  96. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dir), Time.deltaTime * 10f);
  97. }
  98. }
  99.  
  100. public Transform GetPlayerTransform() => player;
  101. public NavMeshAgent GetAgent() => agent;
  102. public Animator GetAnimator() => animator;
  103. public EnemyStateMachine GetStateMachine() => stateMachine;
  104. }
  105. --------------------------------------------------------------------------------------------------------------------------------
  106. // MeleeEnemy.cs
  107. public class MeleeEnemy : BaseEnemy
  108. {
  109. private IdleState idleState;
  110. private FollowState followState;
  111. private MeleeAttackState attackState;
  112.  
  113. protected override void Start()
  114. {
  115. base.Start();
  116.  
  117. idleState = new IdleState(this);
  118. followState = new FollowState(this);
  119. attackState = new MeleeAttackState(this);
  120.  
  121. stateMachine.ChangeState(followState);
  122. }
  123.  
  124. public IdleState GetIdleState() => idleState;
  125. public FollowState GetFollowState() => followState;
  126. public MeleeAttackState GetAttackState() => attackState;
  127. }
  128. --------------------------------------------------------------------------------------------------------------------------------
  129. // IdleState.cs
  130. public class IdleState : IEnemyState
  131. {
  132. private MeleeEnemy enemy;
  133.  
  134. public IdleState(MeleeEnemy e) { enemy = e; }
  135.  
  136. public void Enter()
  137. {
  138. enemy.GetAgent().isStopped = true;
  139. enemy.GetAnimator().SetBool("isIdle", true);
  140. }
  141.  
  142. public void Update()
  143. {
  144. if (enemy.IsPlayerInRange(enemy.attackRange))
  145. {
  146. enemy.GetStateMachine().ChangeState(enemy.GetAttackState());
  147. }
  148. else
  149. {
  150. enemy.GetStateMachine().ChangeState(enemy.GetFollowState());
  151. }
  152. }
  153.  
  154. public void Exit()
  155. {
  156. enemy.GetAnimator().SetBool("isIdle", false);
  157. }
  158. }
  159. --------------------------------------------------------------------------------------------------------------------------------
  160. // FollowState.cs
  161. public class FollowState : IEnemyState
  162. {
  163. private MeleeEnemy enemy;
  164.  
  165. public FollowState(MeleeEnemy e) { enemy = e; }
  166.  
  167. public void Enter()
  168. {
  169. enemy.GetAgent().isStopped = false;
  170. enemy.GetAnimator().SetBool("isRunning", true);
  171. }
  172.  
  173. public void Update()
  174. {
  175. enemy.GetAgent().SetDestination(enemy.GetPlayerTransform().position);
  176. enemy.FacePlayer();
  177.  
  178. if (enemy.IsPlayerInRange(enemy.attackRange))
  179. {
  180. enemy.GetStateMachine().ChangeState(enemy.GetAttackState());
  181. }
  182. }
  183.  
  184. public void Exit()
  185. {
  186. enemy.GetAnimator().SetBool("isRunning", false);
  187. }
  188. }
  189. --------------------------------------------------------------------------------------------------------------------------------
  190. // MeleeAttackState.cs
  191. using UnityEngine;
  192.  
  193. public class MeleeAttackState : IEnemyState
  194. {
  195. private MeleeEnemy enemy;
  196. private float attackCooldownTimer;
  197.  
  198. public MeleeAttackState(MeleeEnemy enemy)
  199. {
  200. enemy = enemy;
  201. }
  202.  
  203. public void Enter()
  204. {
  205. enemy.GetAgent().isStopped = true;
  206. enemy.GetAnimator().SetBool("isAttacking", true);
  207. attackCooldownTimer = 0f;
  208. }
  209.  
  210. public void Update()
  211. {
  212. enemy.FacePlayer();
  213.  
  214. attackCooldownTimer += Time.deltaTime;
  215.  
  216. if (attackCooldownTimer >= enemy.attackCooldown)
  217. {
  218. enemy.GetAnimator().SetTrigger("Attack");
  219. attackCooldownTimer = 0f;
  220. }
  221.  
  222. if (!enemy.IsPlayerInRange(enemy.attackRange))
  223. {
  224. enemy.GetStateMachine().ChangeState(enemy.GetFollowState());
  225. }
  226. }
  227.  
  228. public void Exit()
  229. {
  230. enemy.GetAnimator().SetBool("isAttacking", false);
  231. }
  232. }
  233.  
Advertisement
Add Comment
Please, Sign In to add comment