This sprint, I worked on improvements to the enemy AI, solving the issue of players having to search for the last few stragglers at the end of a wave to move on, and making the Weapon HUD functional!
Enemy Auto-Chase
Throughout the project’s development thus far, all enemies’ AI were initialized to the Wandering state upon spawn, meaning that they would navigate to random nearby points, waiting until the player entered their sight radius before chasing and attacking. This sprint, we decided that we want enemies to instead start in the Combat state. Thankfully, due to the way that I set up the enemy AI in previous sprints, this was easily accomplished by initializing the AI state to Combat upon spawn, and plugging in the player character as the attack target.
Super Easy!
This worked great for the light enemies, who would now immediately book it toward the player. However, this implementation had some undesired effects on the behavior of ranged enemies.
With ranged enemies, their Combat behavior consists only of “Shoot at the player if you can see them” and “Melee the player if they are too close”. There is no behavior for repositioning if the player is out of sight. Before the change to the enemy AI, this worked fine, because the enemies would only enter the Combat state once they had line of sight. However, now that they are entering the Combat state before they have line of sight, they’re simply standing in place until they can see the player. Next sprint, I plan on reworking the ranged enemy behavior trees to move towards the player (with the same logic as the light enemies) if they do not have line of sight. Otherwise, shoot the player. If I want to get a little fancier, I could use the Environment Query System to check points around the ranged enemies for line of sight of the player, so that they could take different angles instead of just beelining towards the player. However, we have a lot of enemies active at once, and so EQS can get quite expensive if I’m not careful.
Wave End Enemy Culling
One problem that we consistently observed throughout playtests was that as players would near the end of the wave, sometimes a couple stragglers would be hanging out in areas that the player already cleared out. This would cause them to have to spend a lot of time searching the map trying to find the last one or two enemies that might have gotten stuck somewhere.
In order to combat this, I developed a system that would wait until the enemy count reached a certain threshold, and then every time an enemy was killed, check to see if all the other enemies were offscreen. If they were, they would be culled and the wave would immediately end.
The on-screen check consists of two parts: a screen-space check, and a line of sight check.
This set of nodes is essentially grabbing the player’s viewport, then the world location of the enemy, and using the handy World Location To Screen Location node to check if the enemy is within the rectangle projected by the player camera.
The second check is much simpler, here I check to see if the player has line of sight of the current enemy. This is to prevent an enemy from being culled if the player is nearby but simply just turned around.
Finally, the last check I make before culling the remaining enemies is seeing if all of them were marked as off screen and not in LOS. This ensures that the enemy culling only ever happens when absolutely necessary. If there is still an enemy within reasonable range of the player, the game will wait until that enemy dies before performing this check again.
Weapon HUD
Last sprint, I implemented a HUD element that was meant to show the player’s currently equipped weapon. However, I only got to the implementation of the actual art, not the switching of the icons to reflect the current weapon, so it always showed the handgun to be equipped no matter what weapon was actually held. This sprint, I got around to making it properly reflect the held weapon and its ammo.
The logic here is pretty simple. I mapped all the possible held weapons to a unique texture, and then when the weapon is switched, I grab its texture and apply it to the UI. Super easy! I do the same thing with the ammo icon as well.
Updating the ammo count is also very easy, there’s an event dispatcher in the ActorComponent that handles shooting which fires every time the ammo count needs to update (which is when ammo is consumed, added, or the weapon is switched and a different ammo count needs to show). This made updating the UI very easy!
Comments
Post a Comment