using System.Collections; using SWS; using UnityEngine; using UnityEngine.AI; public class Enemy : MonoBehaviour { [SerializeField] private splineMove spline; [SerializeField] private NavMeshAgent agent; [SerializeField] private Detector detector; [SerializeField] private Animator anim; [SerializeField] private float jumpAttackDistance; [SerializeField] private float speed = 5; [SerializeField] private float attackDelay = .5f; public bool IsAngry { get; private set; } private Transform _playerTransform; private NavMeshPath _navigationPath; private WaitForSeconds _delay; private static readonly int State = Animator.StringToHash("State"); private GameManager _manager; private GameManager Manager { get { if (_manager == null) _manager = GameManager.Instance; return _manager; } } private void Start() { detector.OnDetectPlayer += DetectPlayer; _navigationPath = new NavMeshPath(); _delay = new WaitForSeconds(attackDelay); IsAngry = false; } private IEnumerator StartChase() { while (IsAngry) { if (_playerTransform != null) { var playerPosition = _playerTransform.position; agent.CalculatePath(playerPosition, _navigationPath); agent.destination = playerPosition; // Extract to call only once if (anim.GetInteger(State) != 2) { anim.SetInteger(State, 2); agent.speed = speed; agent.stoppingDistance = jumpAttackDistance; } if (Vector3.Distance(transform.position, playerPosition) < agent.stoppingDistance + 0.1f) { agent.isStopped = true; transform.LookAt(_playerTransform.position); anim.SetInteger(State, 3); detector.HideDetector(); StartCoroutine(Attack()); yield break; } } if (_playerTransform == null) { IsAngry = false; anim.SetInteger(State, 3); // Wrong state // Reset detector as well. } yield return null; } } // Integrate into chase coroutine. private IEnumerator Attack() { Manager.GameOver(_playerTransform); yield return _delay; if (Vector3.Distance(transform.position, _playerTransform.position) > agent.stoppingDistance + 0.1f) { agent.isStopped = false; anim.SetInteger(State, 2); } } private void DetectPlayer(Transform inPlayerTransform) { Manager.SoundWhistle(); _playerTransform = inPlayerTransform; IsAngry = true; // TODO: Notify player controller instead _playerTransform.GetComponent().ActivateChaseState(); // (not the best implementation.) agent.enabled = true; spline.Pause(); StartCoroutine(StartChase()); } }