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?