In issue #9 I mentioned that training a brain to control every aspect of an enemy was too big of a task. Let me go into a little more detail on how I ended up creating an AI to control a single enemy.
There were two aspects of the AI which I had problems with programming heuristically:
- Controlling movement to follow a set of waypoints
- Controlling movement to follow another object
I have trained two separate brains to do each of these things with a fair level of competence in a controlled training environment. A problem occurs if either of these brains encounters a situation it was not trained to handle. The biggest problem was obstacles such as a wall or another enemy.
I used Unity’s NavMesh and navigation AI to solve this issue for the waypoint brain. First I built a NavMesh for our environment and ensured that all moving objects carved out an area of the NavMesh as they move around. Whenever I would want to move an enemy, I would tell it where I wanted it to go. It would periodically use the NavMesh to generate a set of waypoints which followed a path where no obstacles would be encountered.
On rare occasion an enemy would still get stuck. For example, it could get knocked off path and get stuck behind an object.
I came up with a somewhat hacky solution for this situation.
If the enemy detects that it is stuck, it will reverse for a short period of time. With some free space in front of it, the navigation AI would be able to create a new set of waypoints to get it out of the situation.
If this failed or the enemy was unable to reverse, we turned to game design for the solution. The enemy will complain that it’s completely stuck and the player would receive a style bonus for killing the sitting duck.
The second brain allows an enemy to follow another object by observing how that object moves. This brain is no use if there are obstacles in the way so it is only used when the enemy is close to the object and there are no obstacles in the way. If there is an obstacle in the way, the waypoint brain takes over.
Aiming and shooting was much more simple. An enemy will always shoot when it has range and line of sight to the target.
Organising a group of enemies and deciding how to act was a little more complex, but let’s leave that topic for another day.