using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.AI; using Random = UnityEngine.Random; [RequireComponent(typeof(NavMeshAgent))] [RequireComponent(typeof(NPC))] public class MovementController : MonoBehaviour { private Transform _firePointTransform; public int PointStartID { get; set; } public int PointEndID { get; private set; } public float FlagDistance { get; private set; } private const float UpdateFlagPositionDelay = 5; private const float UpdateReachedDestinationDelay = 5; [SerializeField] private NavMeshAgent navMeshAgent; [SerializeField] private GameObject flag; public float DistanceToGo { get; private set; } public float RemainingDistance => navMeshAgent.remainingDistance; public Vector3 Velocity => navMeshAgent.velocity; private Dictionary _idNavPointDict; private NPC _myNpc; private void Awake() { navMeshAgent.speed = SettingsReader.Instance.GetSettings.MovementSpeed; _idNavPointDict = MapManager.Instance.IDToNavPoint; _myNpc = GetComponent(); _firePointTransform = transform.GetChild(0); InvokeRepeating(nameof(UpdateFlagPosition), 0, UpdateFlagPositionDelay); InvokeRepeating(nameof(ReachedDestination), 0, UpdateReachedDestinationDelay); } private void OnDestroy() { CancelInvoke(nameof(UpdateFlagPosition)); CancelInvoke(nameof(ReachedDestination)); } private void Update() { print($"{_myNpc.NpcState.ToString()}, {_myNpc.GetCharacter.Team}"); if (Velocity.magnitude > 0) _myNpc.ChangeBaseState(NpcEnumState.InRunning); else { _myNpc.ChangeBaseState(_idNavPointDict[PointStartID].navType == NavPointType.Cover ? NpcEnumState.InCover : NpcEnumState.InDirectPoint); } } private void UpdateFlagPosition() { FlagDistance = (flag.transform.position - gameObject.transform.position).magnitude; } [Obsolete] public void MoveToRandomPoint() { GoToNextNavPoint(MapManager.Instance.NavPoints[Random.Range(0, MapManager.Instance.NavPoints.Count)]); } public List GetPointsCandidate() { return MapManager.Instance.NavPoints .Where(point => (transform.position - point.Position).magnitude < SettingsReader.Instance.GetSettings.MovementDistance) .ToList(); } public void GoToNextNavPoint(NavPoint destination) { if (navMeshAgent.isStopped == true) navMeshAgent.isStopped = false; PointStartID = PointEndID; PointEndID = destination.PointId; navMeshAgent.SetDestination(destination.Position); DistanceToGo = navMeshAgent.remainingDistance; } public void ReturnToStartPoint() { if (navMeshAgent.isStopped == true) navMeshAgent.isStopped = false; navMeshAgent.SetDestination(_idNavPointDict[PointStartID].Position); (PointEndID, PointStartID) = (PointStartID, PointEndID); } public void StopOnPath() { navMeshAgent.isStopped = true; } public void ReachedDestination() { if (navMeshAgent.remainingDistance < float.Epsilon) { PointStartID = PointEndID; } } }