- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.EventSystems;
- using MyCollections.AI.Pathfinding;
- using Grid = MyCollections.AI.Pathfinding.Grid;
- public class Agent : MonoBehaviour
- {
- public float speed = 20f;
- public float turnSpeed = 3f;
- public float turnDistance = 2f;
- public float stoppingDistance = 10f;
- public const float pathRequestUpdateTime = 0.2f;
- public const float pathUpdateMoveThreshold = 0.2f;
- private Path path;
- private Vector2 targetDestination;
- [SerializeField] private bool stop;
- [SerializeField] private Vector2 agentDestination;
- [SerializeField] private Vector2 moveDirection;
- [SerializeField] private Vector2 velocity;
- [SerializeField] private float rDist;
- [SerializeField] private Grid grid;
- [SerializeField] private PathRequestManager pathRequestManager;
- public Vector2 TargetDestination => targetDestination;
- public Path Path => path;
- public Grid Grid => grid;
- public bool agentStop { get => stop; set => stop = value; }
- public Vector2 agentVelocity => velocity;
- public float remainingDistance => CalculateRemainingDistance();
- public Vector2 destination
- {
- get => agentDestination; set => agentDestination = value;
- }
- private void Awake()
- {
- agentDestination = Vector2.zero;
- velocity = Vector2.zero;
- stop = agentVelocity.normalized.magnitude == 0 ? true : false;
- }
- private void Start()
- {
- StartCoroutine(UpdatePath());
- }
- private void OnEnable()
- {
- agentDestination = Vector2.zero;
- velocity = Vector2.zero;
- moveDirection = Vector2.zero;
- path = null;
- stop = agentVelocity.normalized.magnitude == 0 ? true : false;
- StartCoroutine(UpdatePath());
- }
- private void Update()
- {
- rDist = CalculateRemainingDistance();
- }
- public void OnPathFound(Vector2[] waypoints, bool pathSuccessful)
- {
- if (pathSuccessful)
- {
-
- path = new Path(waypoints, transform.position, turnDistance, stoppingDistance);
- StopCoroutine("FollowPath");
- StartCoroutine("FollowPath");
- }
- else
- {
- Debug.Log("Path is not successfull!");
- }
- }
- private IEnumerator UpdatePath()
- {
- while (true)
- {
- if (agentDestination != Vector2.zero)
- {
- if (Time.timeSinceLevelLoad < 0.3f)
- {
- yield return new WaitForSeconds(.3f);
- }
- pathRequestManager.RequestPath(new PathRequest(transform.position, agentDestination, OnPathFound));
- float sqrMoveThreshold = pathUpdateMoveThreshold * pathUpdateMoveThreshold;
- Vector2 destinationOldPos = agentDestination;
- while (agentDestination != Vector2.zero)
- {
- yield return new WaitForSeconds(pathRequestUpdateTime);
- if ((agentDestination - destinationOldPos).sqrMagnitude > sqrMoveThreshold)
- {
- pathRequestManager.RequestPath(new PathRequest(transform.position, agentDestination, OnPathFound));
- destinationOldPos = agentDestination;
- }
- }
- }
-
- yield return new WaitForSeconds(0.2f);
- }
- }
- private float CalculateRemainingDistance()
- {
- if (path == null || path.lookPoints == null || path.lookPoints.Length == 0)
- {
- return 0f;
- }
- float distance = 0f;
- Vector2 currentPosition = transform.position;
-
- if (path.turnBoundaries.Length > 0)
- {
- distance = Vector2.Distance(currentPosition, path.lookPoints[path.turnBoundaries.Length - 1]);
- }
-
- for (int i = path.turnBoundaries.Length - 1; i < path.lookPoints.Length - 1; i++)
- {
- distance += Vector2.Distance(path.lookPoints[i], path.lookPoints[i + 1]);
- }
- return distance;
- }
- private IEnumerator FollowPath()
- {
- bool followingPath = true;
- int pathIndex = 0;
- Vector2 previousPosition = transform.position;
- float speedPercent = 1f;
- while (followingPath)
- {
- if (stop)
- {
- yield return null;
- continue;
- }
- Vector2 position = new Vector2(transform.position.x, transform.position.y);
- while (path.turnBoundaries[pathIndex].HasCrossedLine(position))
- {
- if (pathIndex == path.finishLineIndex)
- {
- followingPath = false;
- break;
- }
- else
- {
- pathIndex++;
- }
- }
- if (followingPath)
- {
- CalculateRemainingDistance();
- if (pathIndex >= path.slowDownIndex && stoppingDistance > 0)
- {
- speedPercent = Mathf.Clamp01(path.turnBoundaries[path.finishLineIndex].DistanceFromPoint(position) / stoppingDistance);
- if (speedPercent < 0.01f)
- {
- followingPath = false;
- }
- }
- Vector2 targetDirection = (path.lookPoints[pathIndex] - position).normalized;
- moveDirection = Vector2.Lerp(moveDirection, targetDirection, Time.deltaTime * turnSpeed);
-
- position += moveDirection * speed * speedPercent * Time.deltaTime;
- transform.position = new Vector3(position.x, position.y, transform.position.z);
-
- velocity = (position - previousPosition) / Time.deltaTime;
- previousPosition = position;
- }
- yield return null;
- }
-
- velocity = Vector2.zero;
- }
- public void SetDestination(Vector2 newDestination) => agentDestination = newDestination;
- private void OnDrawGizmos()
- {
- if (path != null)
- {
- path.DrawWithGizmos();
- }
-
- Gizmos.color = Color.red;
- Vector3 direction = transform.right;
- Gizmos.DrawLine(transform.position, transform.position + direction * 2);
- }
- }