Through this iteration we went from changing the game from rail shooter to an escort payload game, during which many changes were done to the enemy AI. We went from zombies to whiteboxes to robots, and the behavior and functionality of the code changed at every iteration. Before the semester started, we had zombies moving around, which were placeholders for our final enemies which were going to be used in the game. We then decided of whiteboxing the whole level, hence the enemy model was also made as a white box.
Following are code snippets for new enemy AI movement, with the whitebox enemy. For the white box enemy had to change the main script that controls the enemy, to make him work well suited for this iteration. The previous zombie enemy had animations, rigging and textures. This enemy had none, so I commented out the code to control the animation and rigging and added code for the enemy to patrol the area waiting for the player to come in range, and it would move on the Y axis to imitate the punching.
This wasn’t hard to do, as I could reapply most of the code I had for the previous enemy for the new one, the only changes I did after team feedback was to cue the player that the enemy was alerted of its presence (since we had different animations before to convey that), the enemy attack and death should be visibly noticeable. For the first problem, I had a red marker appear on top of the enemy which was visible to convey to the player that the enemy is coming to attack you. For the second one, I made the enemy move in 90 degrees clockwise and anticlockwise alternately to how that he is attacking, and when the player kills him I would blow his head off and turn him red, showing that he is dead.
New enemy (Robot):
When we decided to have our enemy as a robot, we then got a new model, new animations with rigging to replace our old model. This enemy was supposed to patrol, attack the player and die when killed. With this we got an additional “good guy” – the payload which the enemy also supposed to attack.
So designing how the enemy should react to two different protagonists in its vicinity was a good thought exercise. Finally, we decided to have the enemy’s preference of attack being the player. If the enemy detects the payload first, he attacks the payload even if the player then comes near him. If the player shoots him, the current preference changes to player and the enemy attacks him. We did this to incorporate the feel and need to protect the payload.
The changes done to the code were plenty. I first separated code for player and payload, as the behavior for attacking both is slightly different. When the payload is being attacked, it stops dead in its tracks. But the player can still freely move, so the animations (states) of enemy change to match the player behavior. I accomplished this using Booleans and animatior Booleans which helped us reduce code significantly. I added few more functions to provide damage to payload health too.
Some challenges Ifaced apart from attack preference was damage amount for both protagonists. After a few iterations, we decided to remove two bars of health for every 4 punches from the enemy for the payload. We kept this minimum because we found out after playtesting that players were more focused on enemies that came directly to them instead of the payload, hence the payload was getting busted easily. Another challenge we faced that by using colliders as triggers to detect player for the enemy, the player could get detected by the enemy if it touches a collider of an enemy who is on the other side of the wall. This was an important issue that came up during the many times since the development of the AI began.
I had this problem in mind and was looking for viable solutions over the summer break, and I found one out. I was working on a small side project for NPC AI for our game and decided to test this. I gave the AI ‘vision’ – meaning I attached a camera to the enemy(actually two of them) and programmed him to detect the player based on if he enters his ‘perspective area’ as shown below.
Here is the simple code for the NPC AI. As you can see in the pictures above, there are two cameras on the enemy – one for long range vision and one for close range. Both detect the player successfully depending on where he is with respect to the enemy’s location. Also, I placed the wall right in between the player and the enemy. The player is at the opposite side of the wall, and he won’t get seen until he comes out in the open, in front of the enemy. I did raycasts from the cameras and when they got hit the enemy was detected. Then the enemy does his executes his shooting code.
This would fix our problem and make our enemy a tad more ‘realistic’. Hence after talking to the team I suggested this fix to the team and started implementing this on my current enemy model.
The new enemy model has now only one camera for the far range detection and we kept one collider for the near one. We came to the conclusion that even if the player tries to sneak up from behind on the enemy, he would get detected. We did this as ours isn’t a stealth game, so it didn’t make sense. So we changed the AI code, make detection according to the camera and removed the collider, fixing the above issue.
The following changes were made to existing enemy AI code.
This is how the new robot enemy would look in the game, with a single camera and couple of colliders.