using System.Collections; using System.Collections.Generic; using System.Numerics; using Pathfinding; using Pathfinding.Drawing; using UnityEngine; using Vector2 = UnityEngine.Vector2; using Vector3 = UnityEngine.Vector3; namespace Reset.Units{ [RequireComponent(typeof(Seeker))] public class UnitPathfinding : UnitComponent, IUnitDirectionProvider{ public Vector2 Direction{ get; set; } public Seeker seeker; public float nextWaypointDistance = 3; private int currentWaypoint; public Path path; public bool reachedEndOfPath; public void Start(){ seeker = GetComponent(); Enemy thisEnemy = (Unit as Enemy); if (thisEnemy.relatedSpawner){ seeker.graphMask = GraphMask.FromGraph(thisEnemy.relatedSpawner.relatedGraph); } else { Debug.LogWarning("Creating a graph for a singular enemy is not yet implemented. Graph mask not set on this unit.", transform); } } public void AssignNewPath(Path p){ if (!p.error) { path = p; // Reset the waypoint counter so that we start to move towards the first point in the path currentWaypoint = 0; } } public void Update(){ FollowCurrentPath(); } private void FollowCurrentPath(){ if (path == null) { // We have no path to follow yet, so don't do anything return; } reachedEndOfPath = false; // The distance to the next waypoint in the path float distanceToWaypoint; while (true) { // If you want maximum performance you can check the squared distance instead to get rid of a // square root calculation. But that is outside the scope of this tutorial. distanceToWaypoint = Vector3.Distance(transform.position, path.vectorPath[currentWaypoint]); if (distanceToWaypoint < nextWaypointDistance) { // Check if there is another waypoint or if we have reached the end of the path if (currentWaypoint + 1 < path.vectorPath.Count) { currentWaypoint++; } else { // Set a status variable to indicate that the agent has reached the end of the path. // You can use this to trigger some special code if your game requires that. reachedEndOfPath = true; break; } } else { break; } } // Pass the direction to the direction handler interface if (currentWaypoint + 1 == path.vectorPath.Count) { Direction = (path.vectorPath[currentWaypoint] - transform.position).ToVector2(); Direction = Vector3.ClampMagnitude(Direction, 1f); } else { Direction = (path.vectorPath[currentWaypoint] - transform.position).normalized.ToVector2(); } // Draw an indicator for the path Draw.ingame.SolidCircle(path.vectorPath[currentWaypoint] + Vector3.up * .02f, Vector3.up, .3f); Draw.ingame.Arrow(transform.position, transform.position + Direction.ToVector3(), Vector3.up, .3f); } } }