I'm having problems checking if my A.I. can see me? (C#)

I’m making the A.I. for my game, and right now, I’m trying to make it so that if they can’t see the player, they won’t go after him.

I was told the best way to do this is by using Linecast, however, that doesn’t seem to work for me.

They never move, even when I stand right in front of him, I even try to do everything to make sure nothing can possibly be in the way, no good.

It turns out that the value is always false, regardless of whether or not they can see me or if anything’s in the way.

Here’s the code:

public int layerMask = 1 << 8;
float angle = 90f;
public float squareRange = 100;

void Start()
{	
	layerMask = ~layerMask;
}
void Update () 
{
		Debug.DrawLine(target.transform.position, transform.position  + (Vector3.up * 5), Color.red);
	
		if((myTransform.position - target.position).sqrMagnitude < squareRange && 
			(Vector3.Angle(target.transform.position - myTransform.position, transform.forward) <= angle))
		{
			if (!Physics.Linecast(myTransform.position + (Vector3.up * 5), target.position, layerMask))
			{
				targetInSight = true;
			}
		}
		else
		{
			targetInSight = false;
		}
}

The reason the line starts above the object position, is because the root of that model is on the floor, so it’s to avoid any floor collisions.

What am I doing wrong?

In your code you are presuming the target is in sight if linecasting between the enemies current position and the players position fails - this is unlikely because you are likely to have a collider on the player (and you need to avoid any collider on the enemy too).

Normally you would

  • mask off enemy AIs from the Linecast by putting them on a separate layer and ignoring it in the Layermask of the line cast
  • provide a hit parameter for the linecast and check whether the thing it hit was the player → if it was then you can see him, if it wasn’t then you can’t, if you hit nothing then you also can’t see the player

I think I get what is wrong below is pretty much the same as yours and it works for me.
You say you assign the layer to the NPC but did you assign it to the player? Probably not (the article covered that :)). So add a layer at 8 (I guess you did), assign it to the NPC prefab so that the prefab collider is ignored and assign it to the player prefab so that his own collider is also ignored.

See the linecast goes from NPC position (somewhere in the middle of it) to the player position (somewhere in the middle of it) but the collider of the player is in between and stops the linecast.

public int layerMask = 1 << 8;
float angle = 90f;
public float squareRange = 100;
Transform target;
Transform myTransform;
public bool targetInSight;

void Start(){
    target = GameObject.Find("Player").GetComponent<Transform>();
    myTransform = GetComponent<Transform>();
    layerMask = ~layerMask;
    targetInSight = false;
}
void Update(){
    if ((myTransform.position - target.position).sqrMagnitude < squareRange &&
      (Vector3.Angle(target.position - myTransform.position, transform.forward) <= angle)){
       if (!Physics.Linecast(myTransform.position, target.position, layerMask)){
            targetInSight = true;
       }else{
            targetInSight = false;
       }
}