public class AstarAI : MonoBehaviour {
    public Transform targetPosition;
    private Seeker seeker;
    private CharacterController controller;
    public Path path;
    public float speed = 2;
    public float nextWaypointDistance = 3;
    private int currentWaypoint = 0;
    public float repathRate = 0.5f;
    private float lastRepath = float.NegativeInfinity;
    public bool reachedEndOfPath;
    public void Start () {
        seeker = GetComponent<Seeker>();
        
        
        controller = GetComponent<CharacterController>();
    }
    public void OnPathComplete (Path p) {
        Debug.Log("A path was calculated. Did it fail with an error? " + p.error);
        
        
        
        
        
        p.Claim(this);
        if (!p.error) {
            if (path != null) path.Release(this);
            path = p;
            
            currentWaypoint = 0;
        } else {
            p.Release(this);
        }
    }
    public void Update () {
        if (Time.time > lastRepath + repathRate && seeker.IsDone()) {
            lastRepath = Time.time;
            
            
            seeker.StartPath(transform.position, targetPosition.position, OnPathComplete);
        }
        if (path == null) {
            
            return;
        }
        
        
        
        reachedEndOfPath = false;
        
        float distanceToWaypoint;
        while (true) {
            
            
            distanceToWaypoint = Vector3.Distance(transform.position, path.vectorPath[currentWaypoint]);
            if (distanceToWaypoint < nextWaypointDistance) {
                
                if (currentWaypoint + 1 < path.vectorPath.Count) {
                    currentWaypoint++;
                } else {
                    
                    
                    reachedEndOfPath = true;
                    break;
                }
            } else {
                break;
            }
        }
        
        
        var speedFactor = reachedEndOfPath ? Mathf.Sqrt(distanceToWaypoint/nextWaypointDistance) : 1f;
        
        
        Vector3 dir = (path.vectorPath[currentWaypoint] - transform.position).normalized;
        
        Vector3 velocity = dir * speed * speedFactor;
        
        
        controller.SimpleMove(velocity);
        
        
    }
}