This is the code in the enemy AI script that tests whether the enemy can see the player or not.

<pre>function findPlayer(){

var hit : RaycastHit;

var distanceToPlayer : float;

directionToTarget = theTarget.transform.position – transform.position;

directionToPlayer = thePlayer.transform.position – transform.position;

distanceToPlayer = Vector3.Distance(transform.position, thePlayer.transform.position);

var targetAngle = Vector3.Angle(directionToTarget, transform.forward); //for vision

var playerAngle = Vector3.Angle(directionToPlayer, transform.forward);

Debug.Log(playerAngle);

Debug.Log(distanceToPlayer);

if(Mathf.Abs(targetAngle) < visionAngle && distanceToPlayer < visionRange){

Physics.Linecast(transform.position, thePlayer.transform.position, hit);

//Debug.Log(hit.collider.name);

if(hit.collider.name == thePlayer.collider.name){

canSeePlayer = true;

theTarget = thePlayer;

}else{

canSeePlayer = false;

}

}else{

canSeePlayer = false;

}

if(distanceToPlayer < hearRadius){

canHearPlayer = true;

theTarget = thePlayer;

}else{

canHearPlayer = false;

}

if(canSeePlayer == false && canHearPlayer == false){ //This has to ultimately be the final else

canSeePlayer = false;

canHearPlayer = false;

FindNextWaypoint();

}

}</pre>

There’s a fair amount of Unity mumbo jumbo in there. In the beginning, I define the variables I’ll need. Some of them, such as distance to player, are somewhat self explanatory.

After the variables (and two debug prints to the console) comes the actual code. The idea is that the enemy checks for the strictest test, then the second strictest, and so on. Currently there are only two tests however. The first, and the one we’re interested in here, is whether the enemy can see the player or not. To see the player, the AI requires three things. First, the player must be within a certain angle of the front of the enemy (in it’s cone of vision). Secondly, the player must not be too far away from the enemy. And thirdly, there must be no solid object blocking the player from the enemy.

It was this third element that caused a lot of trouble. I tried many ways of doing this. While eventually I used a linecast, I spent a lot of time trying to get a raycast to work. Linecasts and raycasts are built into Unity; a linecast is between two points, and a raycast is emit from a single point. Both provide information on the first game object they hit which has a collider component on it. Raycasts provide more information and control than a linecast; but ultimately the easiest method turned out to be checking whether the linecast hits the player or something else first.

Over time, playing around with the raycast/linecast systems more, I began to realize that my conditional structures were causing a lot of the weirdness I was seeing.

Level design is going well; it’s a much slower process than I anticipated though!

One tricky thing has been scaling things correctly. I ended up creating a little player nub object, designed to serve as a consistent reference for the size of the character, but some of the earlier stuff is somewhat strangely proportioned. The purple object in the image there is a standardized door-size object.