Files
real-shooter/Assets/Scripts/Character/MovementController.cs
2022-05-18 00:21:35 +07:00

116 lines
3.7 KiB
C#

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<int, NavPoint> _idNavPointDict;
private NPC _myNpc;
private Settings _settings;
private void Awake()
{
_settings = SettingsReader.Instance.GetSettings;
navMeshAgent.speed = _settings.MovementSpeed;
_idNavPointDict = MapManager.Instance.IDToNavPoint;
_myNpc = GetComponent<NPC>();
_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()
{
if (ReachedDestination())
{
_myNpc.ChangePointState(_idNavPointDict[PointStartID].navType == NavPointType.Cover
? NpcEnumState.InCover
: NpcEnumState.InDirectPoint);
}
else
{
_myNpc.ChangeBodyState(NpcBodyState.Standing);
_myNpc.ChangePointState(NpcEnumState.InRunning);
}
if (_myNpc.NpcBodyState.State == NpcBodyState.Crouching)
navMeshAgent.speed = _settings.MovementSpeed / 2;
else
navMeshAgent.speed = _settings.MovementSpeed;
}
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<NavPoint> GetPointsCandidate()
{
return MapManager.Instance.NavPoints
.Where(point =>
(transform.position - point.Position).magnitude < _settings.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 bool ReachedDestination()
{
if (navMeshAgent.remainingDistance < 0.1f)
{
PointStartID = PointEndID;
return true;
}
return false;
}
}