Enemy Balancing - Antonio Roldan
I've been spending the better part of a week working with more issues regarding replication as I talked about in my last few posts. The last of these being the particle effects for things such as the bile that emits from my enemy spewer, and the blood splatter that displays when bullets hit any of my enemies. Replicating these proved to be just as challenging as getting my animations to replicate, but the process of solving the issue was nearly the same. One major thing I began to notice as I was working on replicating my spewer specifically was just how insanely easy he was for the player to deal with. This enemy is a ranged enemy that shoots acid spray at you and has a good chunk of health. The state he was in however was such that the player only needed to slowly walk to the side or backwards and this enemy was no threat at all, so I knew that I needed to spend some time this week balancing him.
The way that I created this enemy's behavior was by using an attack task node to trigger an attack animation. That animation had notifies that would not only start and stop a particle effect that I had positioned to a socket in front of the spewer's mouth, but also trigger notifies that would start and then later invalidate a timer. That timer would call a function where projectiles would be shot from that same mouth socket directly forward, which always lined up with the player because we set our controller's focus to be set on the player. I then just made sure to line up the velocity of the projectiles with the velocity of the particles and it worked pretty well as a start.
The blatant problem as I mentioned was that this was far too easy to dodge. The player merely had to step in in any direction other than forward and they would be completely safe from this attack. This was because spewer would stop rotating when they attacked and they weren't actually shooting towards the player, just forward in general. The solution to this problem was to have my spewer use the player's position and velocity to predict where they would be heading next, and lead on the shots. This is a relatively straight forward process but the problem this brings is that the AI would potentially be too hard for the player to deal with, so we need a way to scale this back.
What better way to do that than with a scalar? I'll briefly walk through the math I used to accomplish this task which lead to the balanced behavior I was desiring, being that the player is able to dodge the attack if they run to the side at full speed, but unable to dodge it if they are walking or just beginning to run. So really all we need from the player are two things, their current position and their velocity. Then we can use our position and subtract it from theirs to get the distance between them. We also want to make sure we know what the speed of our projectile is so that we can divide our distance by that speed, which gives us the time in which it will take for our projectiles to reach their target. This is important for our main formula which is as follows. We want to take the velocity of the player and scale it by the time it takes for the projectile (and later our other scalar for balancing which will act as our enemy's rotation speed). We then simply add the vector we get from that to the position of the player and what we are left with is a prediction of where the player will be by the time the projectile reaches them.
Once we have that predicted location we can create a rotation matrix, making sure to create it from the vector we get by subtracting the location of our spewer's mouth socket with our newly predicted location. This gives us the exact rotation to face towards our predicted location and that is where we send our projectiles during the attack. Now as I mentioned if you add in a second scalar to that equation for the predicted location and ensure that it is normalized between zero and one, this can act as how responsive this prediction is. You can also think of it as a rotation speed where 1 is full rotation and 0 is no rotation. I played around with that number for a while and found that 0.64 gave me exactly the speed I needed for our player to be able to outrun the projectiles by running to the side, but be impossible for them to evade by walking.
This formula worked great and the spewer was now a force to be reckoned with, however I still had one issue to solve. My particle effect was not lined up to this new logic at all and so the visuals didn't match anymore. This was easily solved by first simply setting the rotation of my particle system to be the same as the rotation matrix we received from the predicted target. This wasn't enough though because even though the particle system now rotated correctly, it didn't match up entirely with the projectiles. I needed to add an additional offset, but this could not be a hard coded value since it was possible for it to need to be negative or positive. My solution was to take the yaw we got from our calculated rotator and multiply it by 0.25, then add that to our original rotator. By taking the original yaw and creating a proportion out of it we now no longer have to worry whether it's negative or positive, either direction will be exaggerated by a quarter. This seemed to line things up visually and now my spewer is really starting to look and feel great.
Plague Wardens
Obliterate for your country.
Status | Prototype |
Author | Board Gamers |
Genre | Shooter, Action |
Tags | Action RPG, Bullet Hell, Co-op, horor, pve, Third-Person Shooter |
More posts
- Spawning Logic Rework - Antonio Roldan4 days ago
- Surrounding Behavior Improvements - Antonio Roldan15 days ago
- AI Surrounding Behavior - Antonio Roldan21 days ago
- Functional Lobby and More Visual Feedback - Ryan Brown31 days ago
- Network Smoothing - Antonio Roldan36 days ago
- Stratagem Improvements and Menu Additions - Ryan Brown36 days ago
- C++ Conversion - Antonio Roldan38 days ago
- Interactable Visuals and Other Changes - Ryan Brown38 days ago
- AI Optimization - Antonio Roldan49 days ago
Leave a comment
Log in with itch.io to leave a comment.