Over the past few weeks, I have been testing my AI, adding a few things and making some changes. Here I will share some final thoughts on what I've been doing.
In previous articles I had created loops like the one in the image below, for the Behavior Tree tasks where the AI had to pick a random point, but would repeat if the point didn't fit a certain condition I had established.
It turns out this Blueprint was partially incorrect. The problem is the random point would always be the same because it's not “generated” in every go (I thought it would, from my PlayMaker background but it isn't). To fix this, rather than send the fail state back to the start, I caused the task to finish in failure so it would run again, forcing a new spot to be generated.
Another thing I did was add another sub-branch to the first branch of my tree. This branch is a “patrol” branch that will fire if the alert level of my enemy is equal to “1” regardless of any previous stimulus type. Previously, I had already configured the AI so that the alert level would gradually go down, until it reaches 1. This is the branch that will run when that happens.
You can see the branch has a Task that reads BTTask_ResetCanHunt. This is a counter that works in conjunction with my BTTask_GetRoamPoint to check if the player is far from the stalker, so the stalker should go where the player is. This is used to make the enemy go to the area where the player is, in case the player manages to get away from the stalker and do something else somewhere in the level. For example, imagine there's two rooms connected by a long hallway. You start in room 1, where the enemy is, but you manage to get out of the room and make it to room 2 where you need to solve puzzles and find items. If the enemy just stays in room 1, the game will not be engaging anymore, so the enemy has to go to room 2 to hunt for you. These two tasks take care of that.
Another thing you can do is create a routine that makes the enemy go away after a while, so the player can progress in the game. However, if you do that, you need to make sure you can “call” the enemy so it can hunt the player.
Something to keep in mind is that Tasks can be comprised of many functions, so they are not limited to a single “flow” of functions. My BTTask_GetRoamPoint chooses from 3 different functions depending on certain conditions. The stalker will simply patrol around the area, it will go away if it “thinks” the player is not around, or will go where the player is if the distance between them is too big and enough time has passed to make the player feel safe.
Lastly, I added extra sensors to my AI. There are two sensors on the face, the main one is the one I've been using all this time, and is the one that can see and hear the player, and also hear objects. However, I tweaked this one to give it a narrower view cone. The secondary sensor on the face has a wider view cone, but the visibility distance is a little bit over one third of the first one's visibility (also, this one has hearing turned off). This one is to simulate the sight when things are out of focus. I also added a third set of eyes on the lower back, to simulate the “sixth sense” when players are walking behind the enemy. This has a wide cone, but has very short visibility distance, so it will only sense the player walking right behind the enemy (this one also has hearing turned off). Below you can see all eyes attached to the enemy, and also some debug messages at the top that show which set of eyes is detecting the player.
Although this is the end of this series, I will keep sharing AI tips with Unreal Engine (and also Unity) in the future, including other types of AI or random tips.
Get Unreal Engine: https://www.unrealengine.com/