Creating enemies - Ideation & Selection
The first step I went into was to simply come up with dozens of enemies rough ideas and behaviors, may it be projectile patterns, movement or attacks, trying to take inspiration from various games and movies. Trying to come up with as much ideas as possible instead of focusing on the first idea which seems appealing allowed me to broaden my vision and to have a pool of ideas and behaviors to pick from.
After that I had to select which one should be prototyped. I did this selection by choosing the enemies which directly answer to the player's abilities, are easy to understand, to prototype and which would have good synergies when put together in a battle.
At this moment, I thought that having a basic melee enemy and a turret would enable us to have a simple but entertaining combat so I went on prototyping these 2 before going on more interesting designs.
My intention on the AI Design is the same as the 3Cs : design them in a holistic way : including Design, Programming, Animation.
This video displays an arena of our Vertical Slice, featuring our 5 enemies.
Fast Prototyping - Mistakes and iterations
After 9 hours of work, I had my first melee enemy working, I worked on WIP animations, used the built-in NavMesh from Unity and went for a simple state machine with Enter/Exit conditions and events. With that, a few attack and bump coroutines, the melee enemy was ready and allowed us to have our first punching bags.
After that I prototyped the turrets (fig1) and quickly came to the realization that they actually played the very same role as the melee enemies : invite players to flee in a single direction. To change that, I decided that the turret would anticipate player's movement which ended being the perfect result : as a player you flee the melee enemies while having to take some backsteps to not get hurt by the turrets' projectiles. The synergy of these two put players in a constant positioning dilemma, which directly answers the main challenge of our game : positioning, needed to shoot the ball at the wanted location and dodge enemies attacks.
After a few adjustements on their readability and firerate, it turned out as on the fig2.
The different turret's iterations took me approximately 6 hours to make it right (animation, code and feedback included).
Smooth & Adaptable Blends
By choosing when to trigger animations at certain percentages of actions, I've been able to make the animations match the wanted feel.
Here the variable "When To Trigger Falling Anim" (fig1) enable the falling animation (fig2) at 90% of the bump duration.
Here it's a combo of 2 animations : the "bumpBegin" which stays at the last frame until the animation "bumpFall" is triggered. This way we can change all the distance and duration variable while keeping the animation's feel.
Another advantage from making WIP animations is that I've been able to test quickly and come up with frame datas that we already iterated on.
This way, the support animators and myself were able to create the animations faster.
Providing the key poses moments and the animation layers also helped a lot to know what your animations must look like.
And since every WIP animations were integrated, replacing them with the new ones were quick and easy.
The Shield Enemy - Case Study
The shield enemy is certainly our most interesting enemy. If the player's ball hit the shield, it instantly rebounds on it and deals no damage to the shield enemy.
The way it directly interacts with the player's main mechanic seemed like a really cool idea but it came with many interesting design problems that I had to solve during the development.
On the right is a One-Pager with a template from GDKeys.com which I modified a bit to suit my needs.
SHMAR stands for Strength, Health, Movement, AttackSpeed, Reach.
The Shield Enemy - Iteration 1
The first iteration included the shield in front of the enemy which made the ball rebound as on a wall (according to the ball trajectory and shield's normal direction), and a charge attack in a straight line.
The first thing I saw was that losing the ball when you hit its shield was very punitive and that its attack was either easy to dodge if we set a long anticipation time or too frustrating with a short one, no tweaking felt right.
Our next step would be to make its attack more interesting to dodge and to make the rebound more forgiving.
The Shield Enemy - Iteration 2
For the second iteration, we modified the attack so that he can turn during its charge, which made it more dangerous and increased the need of a dash to be safe. We also made the recovery time longer so that a good player gets the time to hit him once in the back after its charge.
And for the rebound we made it so that if the angle difference between the "classic trajectory" and the Vector "enemy to player" is less than X, then the ball directly comes back to the player. That way players immediately had a second chance to pass around him.
After this iteration the attack felt a lot better and the rebounds were more forgiving. But it still felt like a mini-boss to most players, which spend sometimes one minute to take him down due to its shield. So I had to find new solutions to make him easier to fight while keeping the shield mechanic as it is.
The Shield Enemy - Iteration 3
On the 3rd iteration I decided that the enemy would lose its shield for a few seconds once he gets hit in the back. This way, once players get his shield down, they can chain him with normal passes and finish him.
This way it rewards players for understanding the enemy behavior and to take him down but took less time to take him down.
The final problem that I had was that the shield enemy would unexpectedly change focus from one player to another, which often happened when one player tries to get in its back.
I took some time to spot this problem but once I found it I just tweaked the variable (which handle how much distance difference there must be between both players to change focus) to an absurd number which made sure that the shield enemy would always keep the same focus, making him more predictable.
It took multiple iterations to get its behavior right but it allowed us to have an interesting enemy which interacts directly with the player's core mechanic and is readable.
I also had the chance to do all the shield enemy final animations, including the GIF on the left.