AI Surrounding Behavior - Antonio Roldan


This week I decided to spend some time improving the behaviors of my enemy AI. There was one thing that several of my teammates had brought up that I also realized when it came to the movement of my enemies, and that was the fact that their movement was way to uniform. I had given my enemies the ability to retarget, however in terms of movement, my enemies were simply moving directly to the player which lead to massive groups lining up like ants. The screenshot below exhibits this problematic behavior which is especially bad in our game where we have support abilities that are capable of large AOE attacks. 

So as you can see this is not the most dynamic of movement behaviors and it was very easy to eliminate large numbers of enemies which doesn't make for a very fun or challenging game. To address this I began working on a solution that would work to spread out the crowds and make their movements more random and unpredictable. My initial thought was to use the Crowd Manager since I am already using a Detour Crowd AI Controller for my enemies. This didn't really work out the way I was hoping however as enemies were still very easily lined up and would almost always all try to attack you from the same side, so I had to be a little more creative and come up with a solution that was bit more involved. 

I came up with an idea where rather than moving towards the player, we would create an invisible proxy actor for the enemy to target and we would just need to make that actor follow the player consistently and then get closer and closer to them until we were finally in melee range. I wanted the placement of where this proxy actor would go to be random however but I didn't want to constantly be choosing random points which I believe would have lead to very strange looking movement. To address this concern what I ended up doing was initially choosing a random point and then using the angle from that point to the player and update the actor's position proportionally using the same angle as the enemy got closer to the player. 

To get a better idea of how this works I'll explain it using the picture above as a visual representation. The orange triangles represent the enemy and the gray lines would be the path they would take. We would be setting three ranges for this being long, medium and close. When an enemy is in long range they will choose a random point in a radius of 3000cm in this example. They will move to that point and upon entering medium range we will use the angle from the player to the point, as well as the proportional distance of the point in relation to the radius of the circle, and we will assign a new point using the new radius and those two variables. The same will continue to happen as we continue crossing the ranges until we finally reach melee distance. 

In the video above you get a much better visual representation of the behavior I just described. The spheres represent the proxy actor I mentioned that the AI will now be moving to. These will obviously be hidden in the actual game but as you can see in the first example with a single enemy, the enemy first chooses one random point. Then as they close in they reach a threshold where they use the same angle and proportion of the radius to chose the new point in the smaller radius. Then finally they do the same thing but rather than having a proportional distance for the last point they just maintain the same angle and place the final point on the minimum range around the player for melee attacks to be able to hit. As you can see in the second example where I show the same effect but with ten enemies, they all follow the same logic but start with completely different random points. In large amounts this leads to them taking significantly different paths to get to the player and ultimately leads to the enemies surrounding the player which is exactly what I was intending. 

Now there were a few problems that I needed to deal with initially such as considering if they started this behavior in a range other than long range, and since I am using object pooling, what happens when they die and are then recycled? I have solved those two issues but there are a few more edge cases that I need to work out. Also since doing this essentially required me to completely remake my behavior trees, I now have to re-implement my initial retargeting behavior and make sure it fits within this new system, but we now have a much more dynamic movement behavior for the enemies in our game. 

Leave a comment

Log in with itch.io to leave a comment.