AI states switching before functions in state finishes

Hi, I wrote the following code, and for some reason or the other, it will just keep switching between the follow and find state. The find state has a pathfinding function in it that should be executed to find a path, and then move the enemy along that path.
For some reason it won’t do this, and instead switches between the two states every frame or so.

#pragma strict

import System.Collections.Generic;

var startNode: node;
var targetNode: node;
var curNode: node;

var player: Transform;

var map: AstarGrid;
	map = Terrain.activeTerrain.GetComponent(AstarGrid);
	
var openList = new List.<node>();
var closedList = new List.<node>();
var pathList = new List.<node>();
var neighbors: node[];
	neighbors = new node[4];
	
var mapScale: float;
var speed: float = 5;

enum AIState
{
	idle = 0,
	attack = 1,
	follow = 2,
	find = 3,
	death =4
}
var state: AIState = AIState.follow;

function Awake()
{
	player = GameObject.FindWithTag("Player").transform;
	
}

function Start()
{
	mapScale = Terrain.activeTerrain.GetComponent(AstarGrid).nodeSize;
	InitStartFinish(transform,player);
}

function Update()
{
	switch(state)
	{		
		case AIState.follow:
		
			var layerMask = 1 << 17;
			layerMask = ~layerMask;
			if (!Physics.Linecast(transform.position, player.position, layerMask))
			{
				transform.LookAt(Vector3(player.position.x,transform.position.y,player.position.z));
				if(Vector3.Distance(transform.position,player.position)>3)
				{
					transform.Translate(Vector3.forward*speed*Time.deltaTime);
				}
				Debug.DrawLine (transform.position, player.position, Color.green);	
				print("following");
			}
			
			else
			{
				state = AIState.find;
			}
			
		break;
		
		case AIState.find:
		
			if (Physics.Linecast(transform.position, player.position, layerMask))
			{
		
				FindPath(curNode);
				print("pathfinding");
			}
			
			else
			{
				state = AIState.follow;
			}
			
		break;
		
		case AIState.idle:
		print("Idling");
		break;
		
		case AIState.attack:
		print("attacking");
		break;

		case AIState.death:
		print("dieing");
		break;
		
	}
}

//Set pixel based positions for start & end nodes. 
function InitStartFinish(cur: Transform, target: Transform)
{
	var tempNode: node;
		tempNode = new node();
	
	tempNode.pos.x = Mathf.Round(cur.position.x/mapScale);
	tempNode.pos.y = Mathf.Round(cur.position.z/mapScale);
	
	for(var i:int=0;i<map.nodes.Length;i++)
	{
		if(map.nodes*.pos == tempNode.pos)*
  •  {*
    

_ startNode = map.nodes*; _
_
}_
_
}*_

* tempNode.pos.x = Mathf.Round(target.position.x/mapScale);*
* tempNode.pos.y = Mathf.Round(target.position.z/mapScale);*

* for(i=0;i<map.nodes.Length;i++)*
* {*
_ if(map.nodes*.pos == tempNode.pos)
{
targetNode = map.nodes;
}
}
curNode = startNode;
openList.Add(curNode);
CalcF(curNode);
}
//Cleans pathfinding arrays and such for the start of a new search.
function clearPath()
{
map.InitGrid();
openList = new List.();
closedList = new List.();
pathList = new List.();
}*_

function FindPath(cur: node)
{
* InitStartFinish(transform,player);*
* while(curNode != targetNode)*
* {*
* //remove current node from open and add to closed*
* openList.Remove(cur);*
* closedList.Add(cur);*

* //find neighbor nodes*
* neighbors[0] = map.nodes[cur.ID-map.gridSize];*
* neighbors[1] = map.nodes[cur.ID+1];*
* neighbors[2] = map.nodes[cur.ID+map.gridSize];*
* neighbors[3] = map.nodes[cur.ID-1];*

* //for each neighboring node, check if it is walkable, not on either open or closed list, if so add to openlist, set parent to current node, and calculate F scores*
* for(var i:int=0;i<neighbors.Length;i++)*
* {*
_ if(neighbors*.walkable == true)
{
if(!closedList.Contains(neighbors))
{
if(!openList.Contains(neighbors))
{
openList.Add(neighbors);
neighbors.parent = cur;
CalcF(neighbors);
}
//if neighbor is in openlist, check G scores to see if current path is shorter or not. If so change parent to current node and recalculate F scores*

if(openList.Contains(neighbors*))
{
if(cur.G+1< neighbors.G)
{
neighbors.parent = cur;
CalcF(neighbors);
}
}
}
}
}
//Find lowest F in openList*

* curNode = openList[0];
for(i=0;i<openList.Count;i++)
{
if(openList.F < openList[0].F)
{
curNode = openList;
}
}
}
if(curNode == targetNode)
{
TracePath();
}
}
//calculates F score for a node*

function CalcF(node: node)
{
* //CalcG
if(node.parent==null)
{
node.G = 0;
}
else*

* {
node.G=1+node.parent.G;
}*_

* //CalcH*
* node.H = Mathf.Abs(node.pos.x-targetNode.pos.x) + Mathf.Abs(node.pos.y-targetNode.pos.y);*

* //CalcF*
* node.F = node.G + node.H;*
}
//traces path when pathfinding is complete, follows it and draws it on the map.
function TracePath()
{
* var temp: node;*
* temp = targetNode;*
* for(var i:int=0;i<closedList.Count;i++)*
* {*
Terrain.activeTerrain.GetComponent(AstarGrid).map.SetPixel(closedList_.pos.x, closedList*.pos.y, Color.yellow);
Terrain.activeTerrain.GetComponent(AstarGrid).map.Apply();
}*_

* while(temp != startNode)*
* {*
* pathList.Add(temp);*
* Terrain.activeTerrain.GetComponent(AstarGrid).map.SetPixel(temp.pos.x, temp.pos.y, Color.red);*
* Terrain.activeTerrain.GetComponent(AstarGrid).map.Apply();*
* temp = temp.parent;*
* }*
* pathList.Reverse();*

_ for(i=0;i<pathList.Count && Vector3.Distance(pathList*.RLPos, transform.position)<1;i++)
{
transform.LookAt(Vector3(pathList.RLPos.x,transform.position.y,pathList.RLPos.z));
}
transform.position = Vector3.MoveTowards(transform.position, pathList.RLPos, Time.deltaTimespeed);

}_

public class node
{
* var ID: int;*
* var parent: node;*
* var pos: Vector2 = Vector2(0,0);*
* var RLPos: Vector3;*
* var walkable: boolean = true;*
* var F: int = 0;*
* var G: int = 0;*
* var H: int = 0; *
}
So I’m wondering, is my pathfinding function not completing, or is it getting cut off by something, or what? Any tips to fix/improve this?

The code says to quickly flip between find/follow when the linecast hits/misses. So maybe the linecast is occasionally hitting something?

The line goes from trans.position to player.position – is that from your feet to the player’s feet? If so, a tiny rise would block it. Could toss in a RayCastHit and print the name of what you’re hitting (ex: “in follow: hit tree1”)

I’d probably not have Follow flip to Find by being blocked for a single frame – what if a tree got in the way? Might only switch to Find if I haven’t seen the player for 0.5 second or more.

In Find, you’re running a pathfind every frame. The path isn’t going to change that much as the player moves (unless doors are closing, but you could have those signal you. Or does the player teleport?) Could only do a find if that last one was >5 seconds ago, or you reach the end.