Post 15: Christmas Update; AI; Part 2
This post is going to be a bit of a long one as I have done a fair bit in the way of the of AI without updating my logs. Call it a crazy time of year. The challenges with the timing has left me with many short burst of productivity, which in itself is actually kind of cool to go through as I feel it will help promoting a more scrum style development process, relieving pressure towards the end of the project.
Never the less, I will start with the breakdown of what I have done since my last update.
Creating a Fighting Blendspace
A smaller detail, but one that will come into play later down the track. Basically I segregated the current animations that I had setup into a different tree that could be controlled by a bool. This will allow me to instigate animations for single handed weapons as well as what I currently have. I will need to look at using a switch instead of a bool if I want to add any other weapon animation styles; Archery, Superpowered, melee etc…
This is all, of course, setup to be blended into the top half of the body as to allow for running. I will tweak this as some of the animations aren’t blending well, but for now it shall do.
This was all an amendment to the existing blend space and can be easily replicated / modified for a potential female character / humanoid NPC’s.
Pretty simple stuff really.
Creating a Locking System
This one, was a little more complex and started off by creating 2 children from the existing code and converting the existing character controller into a somewhat of a Master copy. This will allow me to make changed that apply to all of the child characters, as well as allow me to make changes to the children without affecting each other. From here it was a case of implementing and including Unreal hearing and seeing AI to the enemy NPC’s and then linking into the existing “Lock On” code that was created for the player character in my last coding session.
From there the existing code helps determine who to lock onto and the distance of lock.
The existing following mechanics helped with testing as the NPC would run to the player character, stop and then constantly rotate where the player went.
Finally I implemented a call to this every time the player attacked as I wanted the fighting sequences to be fluid and felt that aiming the character was almost secondary to the point and focus of the game.
Bish, bash, bosh – locking on was working.
Getting the NPC character to Attack
Like the moving, getting the NPC to attack the player basically tied into the existing code with fairly minimal modification. The spherical ray-cast could be used by the NPC to detect other characters (this includes the potential for enemy NPCs). The locking system created before let the NPC focus on a target and the existing attack-combo function was modified to start in a loop once the NPC was within an attacking range. Finally, the auto-lock on attack that I implemented before would keep the NPC attacking in the correct direction.
With our player and NPC being able to hit each other, the natural rate of progression would dictate that I should implement a reaction to being hit. This was to be done in the Master Player Blueprint and presented a large problem for me. How was I going to implement hit detection? I thought of a couple of options:
- Direct hitbox collision
- Hit notifiers in the attack montage.
- Time raycast hits.
I went with option number two as it seemed like it would be the quickest to implement and I can always double back around at a later time to fixed it properly.
First, I started off by putting in hit-checks into the sword animation montages. I then added a notifier event into the notifier graph I had made previously for the footsteps and what not.
At this point the designated hit point on the sword, in this case a mid-mesh socket, would be scanned to see if it were touching a mesh. This mesh would then be determined to be an enemy or not and in the event of it being so, an animation and sound would be played.
Blood spatters and trails
The objective of this was to have blood spurts and trails come out of the character being hit and following the sword that was doing the hitting. This was done by using two seperate particle effects; one for the blood spurt and one for the trail and making two seperate calls.
The blood spurt was called at the point of contact as a one shot kind of deal.
The trail followed the point of contact and looped for just under a second, being disabled after that.
Both particles were attached and called from the weapon slot that I had put on the sword earlier.
Not much more to it really…
Like most of the assets that I have put in, these will go on the list for replacement after the rest of the code is working the way that I want it to.
Blocking reactions and nulling
Building off the existing blocking function, I added in a bool to establish whether a character was in a blocking state. I then added a check in the hit detection so that the attacking character would search for the blocking bool.
If the attacked character is blocking, the appropriate blocking animation, sound and a spark particle effect is triggered.
If not blood splatters, hit animations and ‘slice’ sounds are played.
This one was a barrel of fun. Originally I had intended on allowing for directional dodging in the form of a roll away that would be decided by what direction the player was travelling in. E.g. strafing left + dodge = dodging left.
I couldn’t figure this one out in the time allocation that I had for it, so I moved on and will double back when I find a solution that won’t take a ridiculous amount of time to implement.
For now, my setup consists of:
- Detecting dodging ability based on the proximity of enemies (Is one close, then able to dodge)
- Using the space (Jump) key so that the player would dodge instead of jump in attack sequence
- Implementing an animation, freeze controls and impulses backwards by re-using the attack impulse forward function and inputting negative parameters.
- Putting impulse notifiers into the roll backward animation montage (same as my attacking montages)
- Implementing all the above desired functionality into the existing notifier graph, alongside all the rest of the notifier functions.
This was the player will always be facing the enemy when the dodge and can’t do anything to mess with the impulsing.
Bug: Animation Interuption
Due to the way that I setup my attacking montages, sometimes the player would get hit in the middle of an attack sequence and would then be unable to move due to the ‘enable move’ notifier never being called. This will need fixing in the future.
NPC Strafing and Blocking
I implemented NPC strafing in the same sequence as as the attacking as I wanted the NPC to either attack or strafe – not at the same time.
Essentially there’s a split in the attack / strafe path which is separated by an integer based sequencer, attached to a random number generator.
The strafing uses a Vector Right call instead of the Vector Forward and the random int range is between -1.0 and 1.0. This allows for left and right hand movement.
At the end of both paths is a delay, which determines how long the strafing/attacking will happen for and then both link back to the reset node in the “Do once” function right at the start.
The blocking was another split off this again with a shorter delay so that the sequence doesn’t run for as along as the strafing and attacking sequences.
These can all be fine tuned later by adjusting the delays on them.
Character Health, Weapon damage and Death
There were three parts that I needed to instigate, as mentioned above,
- Creating a character health system
- Creating a weapon damage system
- Creating a death sequence
The first was fairly simple and basically involved creating a variable in the master Character blueprint so that every child of that BP would have their own assigned health. I then set the variable to 100, as once this number gets to zero we are talking death.
The second problem was basically the same as the first, except I set the variable as the damage amount that I wanted to inflict, in this case 10. This variable will change according to what weapon mesh is active in the actor, hence doing it in the master Character blueprint.
The final task was creating a damage and death protocol, incorporating it in the existing function.
I began by putting the damage to health function in the OnHit function that already existed. This is good as the team query was already there, so friendly fire / self inflicted damage is already circumvented.
I then put a bool and branch in to determine if the characters health was equal to or below zero, with a link to the death sequence.
The death sequence comprised of:
- A dying animation
- A command to strip the dead character of it’s team status (this will stop NPC’s from continually attacking and stop blood spatters
- A command to change the capsule collider to ignore all collisions, but those with the environment.
- A delay so that the animation could finish and would be able to lead into…..
- Ragdoll effect, so that the character body would lie naturally on non-flat ground and not half in the air.
- The weapon to be detached from the character and dropped on the ground.
I know I’ve just glossed over what the death sequence comprised of, so I’ll go into more detail.
The dying animation is the same as usual. Mixamo anim with a montage call. Nothing out of the ordinary here.
The stripping of the team number was literally just a modification to the existing team number that would null it out, causing the character to no longer be recognised as being on any team. This prevents any character attack registering.
The delay was a simple delay function. It just allows the animation to play out fully before changing the controller to a physics simulation (ragdolling).
As mentioned above, the control of the character is changed to a physics simulation, also known as ragdolling. This will allow the dead character to wrap over the angled terrain.
There currently exists a bug where the wrists stretch out too much, but I’ll double back and fix it later.
Finally, the weapon being dropped on the ground. Basically the attachment to the hand socket is released and physics simulation is applied to the sword. Interestingly, the sword is still a child of the parent, which will have to change if I implement the ablility to pick up weapons. Jury is out as to whether or not I will…. but this is not important at this moment.
An essential part to any RPG combat system, we had already laid the foundation for a healthbar, in the previous session when I created the health and death system.
I started by creating a UI widget in the form of a ‘progress bar’. From there I created a function that I would plugin to the existing health update function. This then converts the health integer into a percentage (by dividing by 10) and then plugs it into the widget’s built in progress percentage.
I after changing a couple of the aesthetics around, we were good to go.
The video below shows where I’m at with the project, plus a little more functionality (stealth killing) that isn’t quite ready yet.