"Mission brief: Agent F last seen in the city subway system. Strange apparitions reported, utilize Standard Issue Revolver as needed. Exercise extreme caution."
Sub Umbra is our seventh game project at TGA, and this time we had to make a third person game. We decided early to go for a horror game, and we landed on Alan Wake as inspiration since we wanted similar combat mechanics. Since I had made the created the navmesh system and all the pathfinding and path smoothing for the last game, I jumped at the opportunity to work on enemies with more complex behavior this time around. I decided to use behavior trees for this game, as I wanted to get a feel for them and what they can do.
My main focus this project was on enemies, and for this game, the enemies had to make decisions. In the last game, we used a state machine, but since we couldn't do that this time, I chose to use a small behavior tree I has made for an assignment. During the project, the behaviortree grew a lot more complex than what I had orignially envisioned, but this was a blessing in disguise. I now understand behavior trees a lot better and see the potention they have for very complex behaviors.
Since this was our first full 3D game in our own engine, player detection was more complex for this game than previous. It's also a horror game with resource management, so I wanted to make sure the player could both hide from enemies and have enemies lose the player. I deicided to use a timer, where if the monster would lose sight of the enemy for a prolonged time, they would stop and search the immideate area for the player. If they are unsuccessfull, they return back to their starting position.
This time I wanted the enemies to have actual vision cones from the monsters eyes on the model, following it while animatied. This was important for some animations, like search, where the enemy looks around trying to find the player. I also wanted it to be low cost on performance, since all enemies would be looking for the player at all times.
I decided to split up the search in 3 steps. The first, and most cheap check, is a simple distance check from the enemy to the player, to see if it's close enough for the enemy to spot. Secondly, a cheap 2D angle check, to see how many degrees to the side of the monster the player is. And if both of those succeed, then we do the more expensive raycasts to see if there is and object between the two. The raycast portion is also delayed, checking only a few times a second.