How can I prevent a character from ignoring it's waypoint path?

I have a problem where my character is navigating via path generated from an A* map. That itself works fine, however every so often it seems like the character “trips”, and ignores the path, continuing forward.

Due to the style of the game, the character is moving by jumping forward - think in a Frogger fashion, but under control of AI most times, and using it’s own gravity system. I’ve tried multiple methods to eliminate this “trip”, but so far haven’t found anything that is actually sticking.

Additionally, what’s frustrating is that 80% of the time, it works flawlessly. Then at a seemingly random 20%, it trips and just keeps going in it’s current direction, eventually falling off the map. At this point, I can’t tell what’s wrong - I’ve re-written the script twice. The first version used a Finite State Machine. If anyone could spot the issue, I would be grateful.

public class Character : MonoBehaviour {

    public GameObject[] CharacterList;

    private float lockHeight = 0;

    [SerializeField]
    private float gravity = 9.89f;

    public float jumpForce = 2f;
    public float forwardSpeed = 2f;
    public float distanceToTarget;

    public Vector3 activeWaypoint;

    public List<Node> waypointPath;

    private Vector3 moveDirection = Vector3.zero;
    private Transform transformCache;
    private Quaternion rotationPoint;

    // Rotation Points //
    private Vector3 rotateWest = new Vector3(0, 180, 0);
    private Vector3 rotateEast = new Vector3(0, 0, 0);
    private Vector3 rotateSouth = new Vector3(0, 90, 0);
    private Vector3 rotateNorth = new Vector3(0, 270, 0);
    public Vector3 directionToTarget = Vector3.zero;

    public towardsDirection facingDirection = towardsDirection.South;

    public towardsDirection FacingDirection
    {
        get
        {
            return facingDirection;
        }
        set
        {
            facingDirection = value;
            changeFacingDirection();
        }
    }

    public bool underPlayerControl = false;
    public bool isReady = false;
    public bool characterActive = false;
    public bool isPathRandom = true;
    public bool onContact = false;
    public bool hitTarget = false;
    public bool canMove = false;
    public bool isMoving = false;
    
    public bool isThinking = false;

    [SerializeField]
    Vector3 heading = Vector3.zero;
    [SerializeField]
    float distance = 0;
    [SerializeField]
    Vector3 direction = Vector3.zero;

    [SerializeField]
    Vector3 lastDirection = Vector3.zero;
    
    // Use this for initialization
    void Start ()
    {
        rotationPoint = Quaternion.identity;
        transformCache = GetComponent<Transform>();
	}

    public void Init(bool upc = false, int rezSpecies = 0)
    {
        underPlayerControl = upc;
        changeCharacter(rezSpecies);
        isReady = true;
    }


    public void changeCharacter(int species = 0)
    {
        foreach(GameObject got in CharacterList)
        {
            if (got.activeSelf)
            {
                got.SetActive(false);
            }
        }

        CharacterList[species].SetActive(true);
    }

    public void readyCharacter()
    {
        characterActive = true;
        compareNeeds();
    }

    private void compareNeeds()
    {
        isThinking = true;
        canMove = false;
        Vector3 targetPoint = Vector3.zero;

        // Is at end of path? 

        if (waypointPath != null)
        {
            if (waypointPath.Count == 0)
            {
                if (isPathRandom)
                {
                    getRandomPath();
                }
            } else {
                moveToNextWaypoint();
            }
        }
        else
        {
            if (isPathRandom)
            {
                getRandomPath();
            } else {

            }
        }
    }

    public void getRandomPath()
    {
        Vector3 randomPosition = GridObject.Instance.returnRandomTarget();
        PathRequestManager.RequestPath(transform.position, randomPosition, onPathFound);
    }

    public void getPath(Vector3 startPosition, Vector3 endPosition)
    {
        PathRequestManager.RequestPath(startPosition, endPosition, onPathFound);
    }

    public void onPathFound(List<Node> path, bool success)
    {
        waypointPath = path;
        moveToNextWaypoint();
    }

    private void moveToNextWaypoint()
    {
        activeWaypoint = waypointPath.PopAt(0).worldPosition;
        turnToNextWaypoint();
    }
    
    private void Update()
    {
        if (isReady)
        {
            distanceToTarget = Vector3.Distance(transform.position, activeWaypoint);

            if (distanceToTarget <= 1.5f)
            {
                if (!isThinking)
                {
                    compareNeeds();
                }
            }

            if (canMove)
            {
                jumpForward();
            }

            moveEngine();
        }
    }
    
    private void moveEngine()
    {
        RaycastHit rayHit;
        Ray raycast = new Ray(transformCache.position, Vector3.down);

        if (Physics.Raycast(raycast, out rayHit, 0.2f))
        {
            if (rayHit.transform.tag == "Solid")
            {
                Vector3 hit = rayHit.point;
                lockHeight = hit.y;
            }
        }

        if (onContact)
        {
            if (!isMoving)
            {
                moveDirection = Vector3.zero;
            }
        }
        else
        {
            moveDirection.y -= gravity * Time.deltaTime;
        }

        transformCache.Translate(moveDirection * Time.deltaTime);
    }

    private void LateUpdate()
    {
        Vector3 lockPosition = transformCache.position;
        if (transformCache.position.y <= lockHeight)
        {
            lockPosition.y = lockHeight;
            onContact = true;
            isMoving = false;
        } else {
            lockHeight = -100;
            onContact = false;
        }

        transformCache.position = lockPosition;
    }

    public void turnToNextWaypoint()
    {
        heading = transform.position - activeWaypoint;
        distance = heading.magnitude;
        directionToTarget = heading / distance;

        if (directionToTarget.x > 0.4f)
        {
            FacingDirection = towardsDirection.West;
        } else if (directionToTarget.x < -0.4f)
        {
            FacingDirection = towardsDirection.East;
        }

        if (directionToTarget.z > 0.4f)
        {
            FacingDirection = towardsDirection.South;
        } else if (directionToTarget.z < -0.4f)
        {
            FacingDirection = towardsDirection.North;
        }

        canMove = true;
        isThinking = false;
    }

    public void changeFacingDirection()
    {
        if (transformCache)
        {
            switch (facingDirection)
            {
                case towardsDirection.North:
                    rotationPoint.eulerAngles = rotateNorth;
                    transformCache.rotation = rotationPoint;
                    break;
                case towardsDirection.South:
                    rotationPoint.eulerAngles = rotateSouth;
                    transformCache.rotation = rotationPoint;
                    break;
                case towardsDirection.East:
                    rotationPoint.eulerAngles = rotateEast;
                    transformCache.rotation = rotationPoint;
                    break;
                case towardsDirection.West:
                    rotationPoint.eulerAngles = rotateWest;
                    transformCache.rotation = rotationPoint;
                    break;
            }
        }
    }

    public void jumpForward()
    {
        if (onContact)
        {
            isMoving = true;
            moveDirection.y = jumpForce;
            moveDirection.x = forwardSpeed;
        }
    }
  
    private void OnDrawGizmos()
    {
        if (activeWaypoint != Vector3.zero)
        {
            Gizmos.color = Color.black;
            Gizmos.DrawWireSphere(activeWaypoint, 0.4f);
        }

        if (waypointPath != null)
        {
            foreach(Node n in waypointPath)
            {
                Gizmos.color = Color.red;
                Gizmos.DrawWireSphere(n.worldPosition, 0.4f);
            }

        }
    }
   
}

Try decreasing the direction threshold. I mean you check every direction with a threshold of 0.4f but what if the direction to the target is 0.399f? In this case the character won’t turn in the right direction.