I have a problem with my simple AI script. My AI NPC’s sometimes get stuck between objects and i’m looking for a way to know when they get stuck, back them up a little and then randomly choose a direction (other than the way it was moving) and move on.
my code so far:
private var direction : int; //Sets direction of NPC
private var speed = 10; //Sets speed of NPC
function Awake()
{
direction = Random.Range(0, 3);
}
function Update () {
switch(direction)
{
case 0: gameObject.transform.position += gameObject.transform.forward * Time.deltaTime * speed;
stuck();
break;
case 1: gameObject.transform.position -= gameObject.transform.forward * Time.deltaTime * speed;
stuck();
break;
case 2: gameObject.transform.position += gameObject.transform.right * Time.deltaTime * speed;
stuck();
break;
case 3: gameObject.transform.position -= gameObject.transform.right * Time.deltaTime * speed;
stuck();
break;
}
}
function OnCollisionEnter(col : Collision)
{
if(col.gameObject.tag == "Building")
{
setDirection();
}
}
function setDirection()
{
var way = Random.Range(0 ,3);
Debug.Log(way);
if(direction != way)
{
direction = way;
}
else
{
setDirection();
}
}
function stuck()
{
}
As you noticed the stuck function checks if the NPC gets stuck. But i currently have no idea how to do this.
Idea: put some traces in front, and both sides, and if they ALL are touching anything, have the NPC rotate 180. If that works, you can get more complicated checking you surroundings.
you remember the last position (every 1-2 seconds) and if your npc is considered to move and the distance to the last position is smaller than a treshold its probably stuck.
You can use a bigger collider for the NPC, so when the collider triggers a collision, you change the NPC’s movement to 90 degrees or something like that.
I think you can also use a sphere raycasting, with pretty much the same effect. You’d have to use layers for the ground and other NPC’s though.
Ways to get unstuck:
Check to see if we have traveled the distance we should have traveled in the direction we were headed in the last 1 or 2 seconds. If not, then a 90 to a 270 degree turn would work best, imo.
You could implement this by caching the position every 2 seconds, for example, and then comparing if the distance traveled in the last 2 seconds was smaller that what it should have been.