Today I have been working hard on re-writing the core of the enemy AI pathfinding. The approach I am using now is working really well along with the stealth mechanics.
Basically, the player has the ability to hide within shadows in the game, giving you 3 levels of stealth: Hidden, Partial and Exposed. This has a number of effects on the enemy AI and automated security systems.
Firstly, being hidden dramatically reduces the detection range of all enemies and security systems, and will allow you more chances to hide behind objects at a closer range to enemies. Being partially hidden, has no effect on the enemy detection range, but does allow you to lose enemy line of site by darting behind objects that would place you in shadow. Bieng fully exposed increases the enemy detection range and prevents you from hiding behind anything, except walls.
Now light sources are the primary method of controlling stealth, but just to add an extra layer to it, if you turn on your flashlight, you become fully exposed (its bloody bright after all) or firing your weapon will also do the same. Thus, making it more of a tactical challenge to move in stealth. Melee does not affect your stealth level currently.
Now for the AI of the enemy pathfding, I designed the following approach based on giving the enemies specific “states” that they can be in at any one time. Here is the workflow I designed for the AI:
This means that the enemies dont just use basic pathfinding, they use their “senses” as well, ie. if you are in their range, they still have to be able to either see or here you, based on occluding objects and light levels.
In practise, this means that I can succesfully sneak around my enemies, or watch them chase me and I can lose them and see them try to find me at my last position, patrol around and then go back to what they were doing. It feels great, and i’m damn happy with todays coding, that was 11 hours well spent 😀
Mind you, I did have a minor melt down earlier when I made a load of changes to one of the levels and the enemy prefabs, and then forgot to put a yield statement in a coroutine, crashed unity and lost about an hours work, I was not impressed!