120 lines
3.9 KiB
C#
120 lines
3.9 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()
|
|
{
|
|
var thisPoint = _idNavPointDict[PointStartID];
|
|
if (ReachedDestination())
|
|
{
|
|
_myNpc.ChangePointState(thisPoint.navType == NavPointType.Cover
|
|
? NpcEnumState.InCover
|
|
: NpcEnumState.InDirectPoint);
|
|
thisPoint.isOcuppied = true;
|
|
}
|
|
else
|
|
{
|
|
thisPoint.isOcuppied = false;
|
|
_idNavPointDict[PointEndID].isOcuppied = false;
|
|
_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 && point.isOcuppied == false)
|
|
.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;
|
|
}
|
|
}
|