- Home /
How to Make Enemy Avoid Player Field of View?
I've made an enemy that will stop moving as soon as the player can see it. However this makes them really easy to repel since they will just keep moving towards the player, and if said player is aaalmost looking at the enemy it will just walk into the field of view, stopping right outside. This way the player will be able to keep enemies away without looking at them since they just walk into the forbidden zone.
So I need to make the enemies avoid the forbidden zone. More specifically, I need a way to make them approach the player like they currently do, but also try to keep a reasonable distance between themselves and the player's field of view.
I'm using a Nav Mesh Agent to make the enemy move towards the player and avoid obstacles, so I guess a good solution would be to make it see the field of view as an obstacle. But I don't know how that's done or if it CAN be done.
Can anyone tell me how to fix this problem?
I don't work with Unity's Nav$$anonymous$$esh, but you might want to consider creating a $$anonymous$$eshCollider that is the shape of the vision cone as a trigger, and make the enemies RayCast against it, or register collisions against it, so they know to avoid it. $$anonymous$$ake it a bit larger so the enemies notice it but still won't go into the "real" vision cone.
Answer by Lahzar · Jun 26, 2015 at 09:35 PM
I am currently working a very extensive AI project, and I had the same problem earlier today. I have found 3 possible solutions, but one of them won't work in this case and the other one has already been suggested.
You can do what @Cherno said. This is the most effecient way, but it only works in open areas, as the collider will go trough walls and etc.
A* approach Probably the best solution is very difficult to implement if youre new at this. You have to ditch unitys builtin system and replace it whit an A* algorithm. (I am currently trying to figure out if you can do it with the bultin system) There are tons of complete A* algorithms out there, so it wont be very difficult.
If you don't know what A* is, just google it. All you need to know is that tt works on a grid, and cleverly uses "movement costs". Unity NavMesh uses an A* system, but you cannot access its pathpoints, which is essential to this approach.
Now that you have implemented an A* algorithm in your game, probably downloaded something like the A* project for free, you need to get a sufficient amount of pathpoints, for example every path point within 50m.
Now you need to have a script on your player that contains a coroutine constantly running in the background of your game. This coroutine must use a foreach statement to raycast its position to the players position. If there is nothing blocking the raycast, you need to change a value of that point, often reffered to as a node, to something which indicates it is unwalkable.
I know this is probably Too Much Info for you, so here is some code you can use:
//Code by Imre Angelo aka Lahzar - 2015
#region Line of Sight
IEnumerator CheckLOS() {
int i = 0;
foreach(GameObject cover in coverspots) {
Vector3 p = sight.pl.position;
Vector3 c = cover.transform.position;
float a = Vector3.Angle(c-p, sight.pl.transform.forward);
bool b = false;
if(a <= sight.pl.GetComponentInChildren<Camera>().fieldOfView*0.75f)
b = true;
if(!Physics.Raycast(p, c-p, (p-c).magnitude, coverMask)) {
//This is different in every A* algorithm.
//Lets pretend we have an interface on every node called Node
//This is code I barely changed from my own AI, thats why I have an array called coverspots.
//coverspots[i].Node.walkable = (b)false:true;
}
i++;
}
yield return null;
}
#endregion
This is taken from my own AI, and I just changed what had to be changed to make it fit your system. (My system works with scores and costs.) Simply insert this code into your AI. Activate it automatically as soon as its done with StartCoroutine_Auto or something like that. Change p to your players position. C is the position of the node which is currently being checked. B tells us wheter or not the point is within the FOV of the player. You might want to change it from 0.75f to .5f but it still works fine.
What the code does is it checks every single point on the pathfinding grid, and then send a raycast from the player to the points position. If the point is whitin the players field of view, and there are no objects (filtered by a layermask) blocking the players view to said point, the point is out in the open, and it will signal the AI that they cannot walk on this point no matter what.
I apologize for such a long awnser, but as I said I had the same problem earlier today, and I see you asked this question 9 days ago, so I wanted to give a very clear awnser. If you have any questions, something isn't working, just ask. And if anyone needs help with their AIs, PM me and I will do my very best to help you!