using AI.Base; using NUnit.Framework.Internal.Execution; using System; using System.Collections.Generic; using System.Xml.Linq; using UnityEngine; using UnityEngine.AI; public class GoblerStateManager { [Header("Mechanics Attributes")] [SerializeField] public float ChaseDistance = 10f; [SerializeField] public float ChaseDistanceBuffer = 1f; [SerializeField] public float AttackDistance = 1f; [SerializeField] public float AttackMaskDiameter = 1f; [Header("Enemy Attributes")] [SerializeField] public float Attack = 10f; [SerializeField] public float Speed = 10f; [SerializeField] public float Health = 10f; [SerializeField] public float Energy = 10f; private Player Player { get { return Player.Instance; } } private Transform PlayerTransform { get { return Player.transform; } } private Vector2 PlayerPos { get { return PlayerTransform.position; } } private Vector2 CrystalPos { get { return GameManager.Crystal.transform.position; } } private GameObject Owner; private Transform MyTransform { get { return Owner.transform; } } private Vector2 MyPos { get { return MyTransform.position; } set { MyTransform.position = value; } } private NavMeshAgent PathAgent; public GoblerStateManager(GameObject owner) { Owner = owner; PathAgent = Owner.GetComponent(); PathAgent.updateRotation = false; PathAgent.updateUpAxis = false; PathAgent.speed = Speed; SetState(State.GoToCrystal); EnemySpawnerManager.UpdateTick += Update; EnemySpawnerManager.GizmoTick += OnDrawGizmos; } public float DistFromPlayer { get; private set; } public float DistFromCrystal { get; private set; } public State CurrentState; public enum State { None, GoToCrystal, AttackCrystal, ChasePlayer, AttackPlayer, Damaged, Die } protected void SetPriorityState() { if (CurrentState == State.ChasePlayer) return; if (CurrentState == State.Damaged) return; if (CurrentState == State.Die) return; if (DistFromPlayer > ChaseDistance) return; SetState(State.ChasePlayer); } private bool IsUpdating; protected void Update() { if (Owner == null) return; if (IsUpdating) return; IsUpdating = true; DistFromPlayer = Vector2.Distance(MyPos, PlayerPos); DistFromCrystal = Vector2.Distance(MyPos, CrystalPos); SetPriorityState(); switch (CurrentState) { case State.None: break; case State.GoToCrystal: PathAgent.SetDestination(CrystalPos); if (DistFromCrystal < 1) SetState(State.Die); break; case State.AttackCrystal: break; case State.ChasePlayer: //MyPos += (PlayerPos - MyPos).normalized * Speed * Time.deltaTime; PathAgent.SetDestination(PlayerPos); if (DistFromPlayer > ChaseDistance + ChaseDistanceBuffer) SetState(State.GoToCrystal); else if (DistFromPlayer < 1) SetState(State.Die); break; case State.AttackPlayer: break; case State.Damaged: break; case State.Die: EnemySpawnerManager.RemoveGobler(this); SetState(State.None); break; } IsUpdating = false; } protected void SetState(State newState) { CurrentState = newState; switch (CurrentState) { case State.None: break; case State.GoToCrystal: break; case State.AttackCrystal: break; case State.ChasePlayer: break; case State.AttackPlayer: break; case State.Damaged: break; case State.Die: break; } } protected void OnDrawGizmos() { if (Owner == null) return; DrawChaseDistance(); DrawAttackDistance(); DrawAttackReach(); } private void DrawChaseDistance() { EnemyStateManager.DrawWireSphere(Color.green, MyPos, ChaseDistance); } private void DrawAttackDistance() { //Gizmos.color = CurrentState == (IState)AttackState ? Color.red : Color.green; //Vector2 center = this.transform.position; //Gizmos.DrawWireSphere(center, AttackDistance); } private void DrawAttackReach() { //if (CurrentState != (IState)AttackState) return; Gizmos.color = Color.red; Vector2 direction2D = (PlayerPos - MyPos).normalized; Vector2 point2D = MyPos + direction2D * AttackDistance; //Gizmos.DrawWireSphere(point2D, AttackMaskDiameter); EnemyStateManager.DrawWireSphere(Color.red, point2D, AttackMaskDiameter); } }