using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class Agent : MonoBehaviour { public Transform target; 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.5f; private Path path; [SerializeField] private bool stop; [SerializeField] private Vector2 agentDestination; [SerializeField] private Vector2 moveDirection; public bool agentStop { get => stop; set => stop = value; } public Vector2 agentVelocity => moveDirection; private void Awake() { agentDestination = Vector2.zero; stop = false; } private void Start() { StartCoroutine(UpdatePath()); } public void OnPathFound(Vector2[] waypoints, bool pathSuccessfull) { if (pathSuccessfull) { Debug.Log($"WAYPOINTS: {waypoints.Length}"); path = new Path(waypoints, transform.position, turnDistance, stoppingDistance); StopCoroutine("FollowPath"); StartCoroutine("FollowPath"); } } private IEnumerator UpdatePath() { while (true) { Debug.Log("LET ME RUN!"); 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; } } } // Wait for a short time before checking the destination again yield return new WaitForSeconds(0.2f); } } private IEnumerator FollowPath() { bool followingPath = true; int pathIndex = 0; moveDirection = Vector2.zero; 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) { 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).normalized; position += moveDirection * speed * speedPercent * Time.deltaTime; transform.position = new Vector3(position.x, position.y, transform.position.z); } yield return null; } } public void SetDestination(Vector2 newDestination) => agentDestination = newDestination; private void OnDrawGizmos() { if (path != null) { path.DrawWithGizmos(); } } }