Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // EnemyStateMachine.cs
- public interface IEnemyState
- {
- void Enter();
- void Update();
- void Exit();
- }
- public class EnemyStateMachine
- {
- private IEnemyState currentState;
- public void ChangeState(IEnemyState newState)
- {
- currentState?.Exit();
- currentState = newState;
- currentState?.Enter();
- }
- public void Update()
- {
- currentState?.Update();
- }
- }
- --------------------------------------------------------------------------------------------------------------------------------
- // BaseEnemy.cs
- using UnityEngine;
- using UnityEngine.AI;
- [RequireComponent(typeof(NavMeshAgent))]
- public abstract class BaseEnemy : MonoBehaviour
- {
- [Header("BASE VALUES")]
- public float maxHealth;
- public float movementSpeed;
- public float attackRange;
- public float attackCooldown;
- public float damage;
- protected float currentHealth;
- protected NavMeshAgent agent;
- protected Transform player;
- protected Animator animator;
- protected EnemyStateMachine stateMachine;
- protected WaveManager waveManager;
- protected virtual void Awake()
- {
- agent = GetComponent<NavMeshAgent>();
- animator = GetComponentInChildren<Animator>();
- waveManager = GetComponentInParent<Wavemanager>();
- stateMachine = new EnemyStateMachine();
- currentHealth = maxHealth;
- }
- protected virtual void Start()
- {
- player = waveManager.player;
- agent.speed = movementSpeed;
- }
- protected virtual void Update()
- {
- stateMachine.Update();
- }
- public virtual void TakeDamage(float amount)
- {
- currentHealth -= amount;
- if (currentHealth <= 0)
- {
- Die();
- }
- }
- protected virtual void Die()
- {
- agent.isStopped = true;
- animator.SetTrigger("Die");
- Destroy(gameObject, 3f);
- }
- public bool IsPlayerInRange(float range)
- {
- if (!player) return false;
- return Vector3.Distance(transform.position, player.position) <= range;
- }
- public void FacePlayer()
- {
- if (!player) return;
- Vector3 dir = (player.position - transform.position).normalized;
- dir.y = 0;
- if (dir != Vector3.zero)
- {
- transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dir), Time.deltaTime * 10f);
- }
- }
- public Transform GetPlayerTransform() => player;
- public NavMeshAgent GetAgent() => agent;
- public Animator GetAnimator() => animator;
- public EnemyStateMachine GetStateMachine() => stateMachine;
- }
- --------------------------------------------------------------------------------------------------------------------------------
- // MeleeEnemy.cs
- public class MeleeEnemy : BaseEnemy
- {
- private IdleState idleState;
- private FollowState followState;
- private MeleeAttackState attackState;
- protected override void Start()
- {
- base.Start();
- idleState = new IdleState(this);
- followState = new FollowState(this);
- attackState = new MeleeAttackState(this);
- stateMachine.ChangeState(followState);
- }
- public IdleState GetIdleState() => idleState;
- public FollowState GetFollowState() => followState;
- public MeleeAttackState GetAttackState() => attackState;
- }
- --------------------------------------------------------------------------------------------------------------------------------
- // IdleState.cs
- public class IdleState : IEnemyState
- {
- private MeleeEnemy enemy;
- public IdleState(MeleeEnemy e) { enemy = e; }
- public void Enter()
- {
- enemy.GetAgent().isStopped = true;
- enemy.GetAnimator().SetBool("isIdle", true);
- }
- public void Update()
- {
- if (enemy.IsPlayerInRange(enemy.attackRange))
- {
- enemy.GetStateMachine().ChangeState(enemy.GetAttackState());
- }
- else
- {
- enemy.GetStateMachine().ChangeState(enemy.GetFollowState());
- }
- }
- public void Exit()
- {
- enemy.GetAnimator().SetBool("isIdle", false);
- }
- }
- --------------------------------------------------------------------------------------------------------------------------------
- // FollowState.cs
- public class FollowState : IEnemyState
- {
- private MeleeEnemy enemy;
- public FollowState(MeleeEnemy e) { enemy = e; }
- public void Enter()
- {
- enemy.GetAgent().isStopped = false;
- enemy.GetAnimator().SetBool("isRunning", true);
- }
- public void Update()
- {
- enemy.GetAgent().SetDestination(enemy.GetPlayerTransform().position);
- enemy.FacePlayer();
- if (enemy.IsPlayerInRange(enemy.attackRange))
- {
- enemy.GetStateMachine().ChangeState(enemy.GetAttackState());
- }
- }
- public void Exit()
- {
- enemy.GetAnimator().SetBool("isRunning", false);
- }
- }
- --------------------------------------------------------------------------------------------------------------------------------
- // MeleeAttackState.cs
- using UnityEngine;
- public class MeleeAttackState : IEnemyState
- {
- private MeleeEnemy enemy;
- private float attackCooldownTimer;
- public MeleeAttackState(MeleeEnemy enemy)
- {
- enemy = enemy;
- }
- public void Enter()
- {
- enemy.GetAgent().isStopped = true;
- enemy.GetAnimator().SetBool("isAttacking", true);
- attackCooldownTimer = 0f;
- }
- public void Update()
- {
- enemy.FacePlayer();
- attackCooldownTimer += Time.deltaTime;
- if (attackCooldownTimer >= enemy.attackCooldown)
- {
- enemy.GetAnimator().SetTrigger("Attack");
- attackCooldownTimer = 0f;
- }
- if (!enemy.IsPlayerInRange(enemy.attackRange))
- {
- enemy.GetStateMachine().ChangeState(enemy.GetFollowState());
- }
- }
- public void Exit()
- {
- enemy.GetAnimator().SetBool("isAttacking", false);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment