Rev'nShoot page button below.
Section 1: AI
I First created a base AI character where some generic blueprints and behaviours will be added which may or may not be used in multiple types of enemies. I also added the AI controller and a base behaviour tree and blackboard. I also added the Nav Mesh Bounds Volume which allows the AI to navigate within the volume.
AI Controller AIC Enemy Base:
Here are all the variables used in the AIC. The names are for blackboard keys for when I set their value. The attack target generally just refers to as the player. Known seen actors Is an array of actors which the AI has seen using its sight sense perception.
On possession of the character It gets the Behaviour tree which is a validated variable so different AI types can use the same variable for different behaviour trees. Then if it is valid it runs the behaviour tree, of not prints a string, then a function called set state as passive is called (explained later), another function called get ideal range is called (also explained later), then it sets the attack range to the ideal attack range from the function as a black board key, along with the defend range. Then it sets a timer by event for checking whether it has forgotten seen actors.
On un possession it clears the previous timer.
Here is the senses config for the three senses I implemented, sight, hearing and damage detection. I have the sight at 5000 (they don't see the player well if not at a high number) the lose sight radius is at 7000, a peripheral vision of 90 degrees in order to be able to see the player better and not get stuck in a passive state. The hearing range is 7000 also so when you shoot they get alerted to you're position.
Here I set up the handles for perception, for each of the perception updated actors (if its seen, unseen etc.) then it will first run the Handle sense function for sight, then if that succeeds then It will run the handle sight function, if not it will run handle lost sight function. Then it will handle sense again this time for hearing, if it succeeds it will handle hearing wit the location input as the stimulus location (where the heard noise is first located). Finally it will handle sense again this time for damage and if succeeding it will run handle sense damage with the player character as input for the actor.
Functions explained later.
This is the check if forgotten seen actors event If the number of known seen actors is not equal to the AI perception known perceived actors (I.e. its updated and its lost a sight of an actor). Then for all known seen actors loop, check if the from the known perceived actors there is one less than the known seen actors, if so then clearly it has lost an actor and so it runs the handle forgot actor function.
 This is the seek attack target event, which called the set state as seeking function and clears the timer for a timer to seek after losing sight (shown in the function).
AIC Enemy Base Functions:
Here are all the functions for the AIC, they either fall under the Set state category or the handle category.
Set States:
Here it sets the enumerator for AI states (passive) as the value for the blackboard key for AI state.
The set state as attacking function uses an input for attack target which is an actor and Use last known attack target which is a Boolean. Then if the input Boolean is true and the Attack target is valid it will set the New attack target variable as the Old attack target, otherwise it will use the input value for the attack target. If the new attack target is valid It checks runs the Is Dead function for the New attack target, if it isn't valid then it sets state as passive. Then if it is dead it sets the AI state as passive, if not it sets the Attack target blackboard key as the New Attack Target, and then sets the AI state blackboard key as attacking and finally it sets the Attack target as the New Attack Target (so the function can run properly again with the New Attack Target).
This is a function for getting the current state, where it gets the AI state blackboard key and sets the output value to it.
This is the set state as investigating function which sets the AI state BB key (I'll be using "BB" as blackboard replacement now) as the Enum AI state investigating. Then it sets the input vector (Location) as the point of interest BB key. Investigating state just means, when it loses sight of the attack target It goes to its last known location and then searches randomly around the area.
Here it sets the AI state BB key as Dead, If the state is dead, it will stop the AI from continuing.
Here it sets the AI state BB key as Frozen, Frozen just means the AI cant do anything for a certain time.
Here it sets the AI state BB key as seeking, and then like the investigating function, sets the input vector (Location) as the point of interest BB key. Seeking is like investigating except its actively going to predict where the player may have gone.
Here it sets the Boolean BB key Stop Spawning as the Boolean input Stop Spawning? This is for the boss's spawning ability.
Handles:
Handle sense function takes two inputs, the sense (Enumerator) and the Actor, it then gets the actors perception (in built function), then for all the last sensed stimulus gets its sense class and checks if it is equal to None, sight, hearing or damage, form the input Sense. If it is then it will return the successfully sensed Boolean (from the array element (single) of the last sensed stimulus) and also the Array element itself as the stimulus.
Handle sensed sight, for each of the last known seen actors it adds unique, this append an element at the end of the array if it is not already present. Then it gets the current state and switches, for passive attacking investigating and seeking (so if it is equal to one of these states it will continue) if the input actor is equal to the player character It will set state as attacking with the attack target as the actor (player) (this can also be used to make the AI fight each other but I put the player character in for the game). Then if the state is attacking and the attack target is equal to actor it will clear the timer to seek after losing sight.
Handle sensed hearing, It gets the current state and I it is passive, investigating or seeking, it sets the state as investigating with the input location.
Handle sensed damage, gets the current state if it is passive, investigating or seeking and the input actor is the player it will set state as attacking with the actor as the attack target.
Handle Forgot actor, it first removes known seen actors and if the forgotten actor is equal to the attack target it sets the state as passive.
Handle Lost sight, gets the current state, if it is not attacking and the input actor is the attack target, it gets the current state again and if it is attacking, investigating or frozen, it clears the timer to seek after losing sight, then sets a timer by event, seek attack target.
Enemy Base:
Here are all the variables used in the AI enemy base (which all other enemies can use as they inherit from). Has Equipped Weapon is set true after the equip weapon event, weapon actor is what weapon has been equipped, behaviour tree is what behaviour tree the enemy is using. Hit reaction montage to play is what hit reaction to play (when the AI is hit). Reserved attack tokens is a map for the actors which are being attacked and so the number of attack tokens available to use, tokens used in current attack (self explanatory), Is Dying is true just after the dead event is called so animations etc, can cancel.
There are also three event dispatches, On Attack End, On Equip Weapon, and On Unequip Weapon.
On event begin play It promotes the AIC to a variable and also creates the enemy healthbar widget.
Dead event, sets the is Dying variable to true, sets simulate physics to true sets the mesh collision to to query and physics, and the capsule collision to none (so the player can still run over the enemy). Then it stops all logic of the AIC for that enemy, and sets state as dead. Then for each to the reserved attack tokens it finds the keys and sets the amount to return attack token as the output of the find node. Then after a three second delay it destroys the actor and the weapon actor.
This is the damage response event, it stops all movement immediately and sets state to frozen, then it plays the hit reaction montage and after completing or being interrupted, it sets state as attacking again.
AI Jump event, suggests a projectile velocity using the enemy starting position and the destination (input) with Z adding 250, otherwise it wouldn't jump high, then calls the inbuilt launch character function.
Attack tokens allow the enemy to attack the player when they are available, here are the events which correalate to the attack tokens in some way. Return attack token, calls the return attack token function from the damage system (explained later), Store attack tokens adds the input amount and adds the number of reserved attack tokens, and If it finds reserved tokens successfully, it will pick that new integer, if not it will pick the input amount and then add it to the reserved attack tokens. Attack end, takes attack target, returns the tokens used in current attack, then uses the negative value of the tokens used in attack as the input for the store attack tokens function/event, then setts attacking to false and calls on attack end. Lastly, Event Attack sets attacking to true.
Destroy enemy function, this function checks if the levels which have enemies (not spawn level) are loaded (I'm aware I could have done Not Spawn instead Idk I didn't), then it destroys the AI (target) and the Weapon (Weapon target).
BPI Enemy AI:
Here are all the functions in the Interface.
Set movement speed sets the character movement, to the Movement states given value.
Get Ideal Range, away to set and get the Attack and defend range.
Attack start, first reserves attack tokens with the tokens needed, if that succeeds then it will store the tokens needed, and then set tokens used in current attack as the tokens needed.
BPC Damage System:
Here are the functions, variables, macro and event dispatches for the BPC Damage System. Health is the actors current health, max health is maximum health. There are also Booleans for Is invincible, Dead, Interruptible and Blocking.
Hit response:
Damage Type:
These are the enumerators used in the BPC Damage System, the Hit response and Damage type. Hit response refers to what then enemy or player should do in response to being hit by a trace. The damage type refers to what damage type it is, so A gun trace will choose projectile damage (currently doesn't nothing but could add other functionality for different damage types.
This is a structure for Damage Info, Damage amount, Damage Type (Enum from before) Damage Response (Other Enum from before), Should Damage Invincible, Can be blocked, Can be parried, Should Force Interrupt.
Here I created a simple widget for the Enemy health bar. The percentage binding, divides the current health, by the maximum health, where the target is a damageable actor, so any actor which runs the BPI damage system is considered damageable.
Take damage function, takes Input of Damage Info structure and damage causer. I then runs a Macro (shown just below) with corresponding outputs of the structure running in to the inputs for the Macro. Then from the macro, when blocked, it calls the event dispatcher On Blocked and returns was damaged as false. For No Damage, it just returns was damaged as false. Finally, Do Damage, it sets the Health as the Health subtract the damage amount. If that New Health value is less than or equal to 0, it sets Is Dead as true and calls On Death Event Dispatcher and finally returns Was Damaged as true. If health is not less than or equal to 0, it runs another branch, where the condition is either Is Interruptible or Should Force Interrupt, then if true, It calls On Damage Response and Returns Was Damaged as true, otherwise it just returns was damaged as true.
 Above is the Macro from the take damage function, which takes inputs should damage invincible and can be blocked. Then if Is Not Dead, and Is Not Invincible or Should Damage Invincible then it will output true. If true then it checks If can be blocked and Is Blocking, if this is all true, it will output Block Damage, If Is Blocking is False or can Be Blocked is False, Or both, then it will output Do Damage. If the actor Is Dead It will output the first condition as false, If true and Is Invincible is true and Should damage Invincible is false then it will output false. If the first condition is false then it will output No Damage.
 Here we have the reserve attack token function, it checks if Attack Token Count is greater than or equal to the input amount, If true it set the Attack token count to the attack token count subract the input amount and returns success. If the condition is false it returns false.
This is the return attack token function, it sets the attack tokens count, to the attack tokens count add the input amount.
Heal function, if the actor is not dead, it sets the health (current), to the health plus amount (clamp limits this to between 0 and maximum health).
BPI Damage System:
 Here are all the functions for the BPI Damage system. These functions can then be called if an actor has the BPI Damage System on it.
Reload, checks if total ammo magazines is greater than 0 and current rifle ammo is equal to 0, If true set current rifle ammo to Max rifle ammo, and set total ammo magazines to its self subtract 1.
Get current heath, outputs the Health from BPC Damage system.
Get maximum health, same as current health but for max health.
Heal health, calls the heal function from BPC Damage System and outputs New Health.
Take Damage, calls take damage function with inputs matching to the take damage inputs and same with outputs.
Is dead outputs Is Dead Boolean from BPC Damage System.
Is Attacking Outputs variable Attacking.
Reserve Attack token calls the reserve attack token function.
Has Ammo, checks if the input ammo amount is greater than 0 and if true outputs has ammo.
Get current ammo gets current Rifle ammo and outputs as float (could be generic ammo variable).
Get Max Ammo, same as current ammo.
Take ammo, sets current rifle ammo as its self subtract input amount.
Set Default health sets the BPC Damage System health variables.
Has magazines checks if the input magazine count is greater than 0.
Finished attacking (doesn't do anything but could be used to stop attacking).
BPC Attack System:
Variable Object type query is of type array and has two values, World Static and Pawn.
Player Fire Bullet, takes trace start, end and also damage info structure as input. It then traces a line for objects (Array Variable), If it returns true, it calls take damage function, which uses the damage info input, the hit actor as the target and the damage causer as the owner. It then reports a damage event (for the AI sense damage). So it traces a line, checks to see if it has hit a world static object, if so it will run the rest of the code (static object doesn't have health and isn't AI so it does nothing). If it doesn't hit a static object but hits a pawn, it will run the code again, this time it will call take damage.
Enemy fire bullet is the same as player fire bullet, except I set it up currently so that if the hit actor is not equal to the player character it will do nothing (the AI when grouped together would shoot each other).
Enemy Base Behaviour tree and Blackboard:
Here Are the Black board keys, which essentially allow us to run different behaviours depending on the key selected, such as move to the Attack target etc.
Here is the AI State enumerator, this involves each of the states the AI can be in, passive (patrolling or standing still), attacking (firing gun or swinging sword) etc.
The Enemy Base behaviors are used as a base which have some generic functions other AI might use. Behaviour trees work from left to right in terms of priority, however in this case I used a selector. The selector will select the highest priority first, but if there are conditions to be met, I will select the following behaviour based on those conditions. So for the frozen state (I forgot to rename the node to frozen state) It used a black board based condition so that if the state (BB key) is equal to frozen it will run, if this changes It will abort both itself and all other branches within the selector. For combat state it checks if the state is equal to attacking it runs if it, changes it aborts itself and runs either the next highest priority or if another condition is met chooses that instead. The investigating is for the investigating state and aborts self, and the same with the passive/patrol state, for if the state is equal to passive.
Sub tree Seeking:
Here is a sub tree (behavior tree to be used in main behaviour trees) for seeking.
It first goes to the last known location (set by the AIC earlier), this clears the focus and sets movement speed and then moves to the point of interest set by the AIC.
Then for 5 loops, it runs the EQS Seeking and moves to the point of interest, ( The EQS is shaped like a cone, with the highest valued points being out of sight, a certain distance away, and also close to the AI, to mimic as though the AI is searching around each corner looking for the player.
Finally, once done seeking it sets state as passive, so the AI can either patrol or set state as passive.
Sub tree Frozen:
When the AI state is equal to Frozen it runs the Frozen sub tree.
It has a simple purpose of clearing focus setting the movement to idle(stopping) and then waiting 5 seconds.
Sub tree Investigate:
This sub tree is for moving to the last known location of the attack target (set by the AIC), this is supposed to make it seem like the AI is investigating that area.
Sub tree Patrol(Randomly):
This is a subtree to make the AI move to a random point within the radius (I made a patrol system along a spline point however it bugged and stopped working, see my product programming page to see that).
AI Types:
I made a total of 7 different enemy types including the enemy base, boss, jump, melee, ranged, rapid fire and tutorial enemy. Base enemy explained earlier.
Enemy Melee:
The melee enemy has the ability to block damage, so when it starts blocking it sets is blocking (used in the BPC damage system as shown earlier) and sets the blocking state enumerator to blocking. It then plays a blocking animation and then on interrupted checks if the blocking state is equal to blocked successfully, if true it then calls end block function if the animation is completed then it just calls end block. The on blocked function is from the BPC damage system and when called it sets blocking state to successful and plays a hit reaction animation and the calls end block. The end block function sets is blocking to false and sets the blocking state to none and finally calls on end blocked.
Once the melee enemy code starts it first runs the parents(enemy base code) and sets health to 250.
Event attack is the melee enemy's base and only attack. it first checks if it is dying (as there is a delay between the death and literal destruction of the enemy it can still attack after losing all its health without this). Then if it isn't dying it plays a sword swing animation, It then sets is interruptible to false (so it doesn't get stunned when swinging) and on completed or interrupted it calls attack end and sets is interruptible to true. I set a notification up on the montage so when it starts swinging it calls the notify. On notification does a sphere trace for objects (generates a capsule/sphere for tracing) it then takes the enemy location as the start and the enemy location plus the enemy forward vector multiplied by 200 as the end point and the target object types are pawns. Then it checks if the return value is true (so if it has in fact hit a valid target) and then calls take damage function where the target is the hit actor and deals 15 damage.
Event equip weapon, plays an drawing sword animation, I set up a notification for this animation when the hand reaches the waist (where the sword is), on the notification it spawns the sword actor and sets the value of weapon actor, it then attaches the sword to the grip point and sets has equipped weapon to true.
Event unequip weapon, plays a montage for sheathing the sword and this time on notify it destroys the sword actor and sets has equipped weapon to false.
This is the melee enemy death event which first checks if health is at 0 and then calls the death function, it then calls destroy enemy.
Melee Enemy Behaviour Tree:
Passive State:
The passive state has two options, if the enemy is wielding a sword it performs unequip weapon task, and if not then it calls the patrol/passive state subtree.
The unequip weapon task, casts to the enemy base and calls unequip weapon function, it the binds event to on unequip weapon and finish execute.
Condition check to see if has equipped weapon is true.
Patrol/passive state shown earlier.
Combat State:
Condition check to see if the enemy is attacking, and a service to stop attacking if the target/player is dead.
This is the service, it checks is dead for the attack target as actor, and if true it sets state as passive.
This is the wield sword sequence, which checks if the AI is already wielding a sword and if not, it focuses the target and equips the sword.
Condition check to see if has equipped weapon is false.
Focus task, checks if the AI controller is valid, if it is it sets focus and finishes, if it isn't, it checks if the focus target is a valid AI Location and if it is sets it as the focal point and finishes.
Equip weapon (same as the unequip weapon task but for equip weapon).
Condition check to see if the enemy is attacked and a cooldown. If it is being attacked and is not on cooldown it sets movement speed to idle, focuses the attack target and performs a melee block.
Condition check just calls Is Attacking function from the bpi damage system.
Melee block task, calls start blocking and then finishes on end blocked.
 Attack sequence just calls melee attack task and waits for one second along with a 2 second cooldown.
 Attack task, calls attack start (BPI enemy), then if that fails it finish executes but if it succeeds, it sets movement speed to run and clears focus. After clearing focus it moves to the attack target, with an accepted radius of the Ideal range. Then on failure it calls attack end and finishes, and on success it focuses, calls the attack function and the binds on attack end to finish execute.
Strafe section, if the enemy is NOT within ideal range (decorator) it clears focus sets movement speed to run and moves to the ideal range. If it is within ideal range it calls the strafe sequence, which calls focus task, sets movement speed to walk and runs the strafe EQS, it then moves to the point of interest and waits half a second.
The condition check gets the distance from the attack target to the controlled pawn(AI) and subtracts a margin of error of 50. Then if that is less than or equal to the ideal range it returns true if not false.
This is the move to ideal range task which moves to the attack target within the accepted radius of the ideal range, then if the character is falling it will finish execute (so it doesn't keep moving in the when it lands (as it takes impact) and if it isn't falling it also finish executes.
 This is the EQS for strafe, it generated 5 points on a circle around the attack target at a distance between 100 and 500, preferably towards 500, and has a radius of 350, which means the points should generate in a circle around the player.
This is the EQS context for the attack target, it essentially just uses the variable from the AIC and selects it as the resulting actor. The testing purposes only section is for when I want to use the player start to test the EQS, outside of run time.
Enemy Jump:
The jumping enemy was designed to be a more dangerous but easy to defeat enemy with its massive damage amount nearly killing the player in one shot, however is vulnerable to attack as it only has 20 health the player can one shot kill them. The enemy runs and jumps at the player to deal massive damage, but the impact from jumping also deals damage.
Event attack, it first checks if the enemy is dying, this way it doesn't attack if it is already dead. It then plays a jump attack montage. It first sets is interruptible to false, then on completed or interrupted it calls attack end and kills the enemy. On the notification (a certain point just before landing) it calls jump to attack target (shown down below), it then binds event to on landed delegate (when it lands), where it calls the trace sword function shown below, it then unbind the event and stops movement immediately (to make sure it doesn't move whilst the animation is still playing.
Jump to attack target, uses and custom made function called calculate future actor location (shown below) where the actor is the attack target. I initially set the time to 3 but that caused issues where the AI would jump way to high and start attacking mid air, so I set it to 1 and it solved this. It then takes the x and y location and inputs it as the suggested projectile velocity and the z as 100 (so it doesn't try to clip into the ground or other objects). The suggest projectile velocity custom arc is another built in function which takes the starting position (AI location) and suggests an arcing path for the AI to follow, it then calls launch character with this suggested launch velocity.
 Trace sword, this event does a sphere trace for pawns, with the start being the actor location and the end being the actor location plus the actor forward vector multiplied by 200. Then if this succeeds it calls take damage with the damage info as an input to the event. This is pretty much the same as the one used in the melee enemy only this is a separate event.
Calculate future actor location function, this function takes the actor velocity multiplies the x and y by 1 and z by 0, then multiplies again this time by the time and finally adds this value to the actor location. Essentially it is getting the players current velocity, multiplying the z by 0 to cancel it out and the multiplying the player x and y velocity by the time which is also 1, it then adds the actor location, this means it it is calculating based on the velocity where the player will be in 1 second time.
On begin play it sets health to 20, again a design choice to make it really easy to defeat, but really dangerous if it sneaks up on you without you noticing.
Jump enemy behaviour tree:
The jump melee uses the melee behaviour tree as its base with the only changes to the combat state. First I removed the blocking ability and also the strafe, and changed the attack so it first runs towards the ideal range then performs the melee attack (jumping attack) and then waits for 1 second.
Tutorial Enemy:
The tutorial enemy is just the melee enemy but on death it calls the open door event which sets the Should open variable to true (used in the tutorial door later). The health is also changed from 250 to 100.
Ranged Enemy:
The ranged enemy is a simple concept, like the player it has a rifle and can shoot from long distances.
The equip weapon works the same as the melee enemy except the socket is changed to rifle socket and weapon actor to the rifle actor.
Event attack, this plays a shoot montage, where on completed or interupted it calls attack end. When the notification begins (rifle is fired) it calls the enemy fire bullet (BPC Attack system) where the trace start is the actor location and end is the attack target location, I set the damage to 20 as it technically has aim bot and and can shoot from long ranged so is very powerful.
Ideal range set to 600 so it shoots from far distance.
Health is set to 100 so it is fairly quick to kill.
Ranged Enemy Behaviour tree:
This is a sequence for finding cover, so when the AI is below a certain health thresh hold it first runs the find cover subtree, sets focus and performs the heal task, finally it waits 1 second.
Condition check to see if the current health over the maximum health (percentage) is less than the health thresh hold.
Heal task, gets the maximum health multiplies it by the heal percentage, and calls the heal health function.
This is the find cover sub tree, which first clears focus, sets movement speed to run and then runs the take cover EQS, moving to the point of interest.
This is the EQS take cover, it traces a line from the attack target to the enemy, so if the enemy is seen by the player then the point is nullified, and it also checks the distance to the attack target scoring higher the closer the point is to the player. This way the AI is looking for a point not visible by the player, but also close enough to the player that it can quickly run back out after healing.
The attack is similar to the melee enemies attack except it first checks if it can see the attack target. It then attacks on cooldown of 6 seconds, then it strafes.
The ranged attack task is simpler than the melee's, it first calls attack start, then if that succeeds it sets focus, calls the attack function and on end of the attack it finishes. If the attack fails it just finishes.
This is the EQS for finding ranged position, its a simple grid with radius 600 and a space of 200 between each point (600 is also the attack and defend range). As usual it first checks if the point is reachable (not clipped under objects etc.) and it then traces a line to the Attack Target. Then it checks the distance to the attack target and scores higher the further away it is. Finally, it checks the distance to the querier with a minimum distance of 300 so the AI must be within a range of 300 to 600 preferably greater.
Here is the move to line of sight, it first clears focus, sets movement speed to running then runs the find ideal ranged position EQS shown above, and moves to the point of interest.
Enemy Ranged Rapid Fire:
The idea for the ranged rapid fire was just to increase the speed of the animation so that the attack is quicker and decrease the damage.
The attack and defend range are also smaller at 200 and 400.
The health is also smaller at 45.
The cooldown is also smaller at 2 seconds.
Boss Enemy:
The idea behind the boss enemy is he's much bigger than all the other enemies and he carries a gatling gun.
It has a few new variables, final phase complete, second phase complete and damage multiplier, along with a new function called final phase.
 The health is set to 1000 as he's a boss and the ideal range is also set to 1000, it also calls destroy enemy.
One begin play it first sets is interruptible to false and is invincible to true (as its playing a start up animation), then it plays the chest bump animation and then immediately after it plays the rage animation, it then calls equip weapon, sets health and creates the boss health bar widget.
The even equip weapon is slightly different from other enemy types, it first plays the equip weapon montage where on completion it sets is interruptible to true and is invincible to false but part way through the animation the boss reaches behind to grab the gatling gun, where it then deletes the static mesh component and spawns the gatling gun actor as normal.
The attack is also slightly different, as the animation has many notifies so the shoot function is rapid, however the damage is also lower at 3.
Enemy Boss behaviour tree:
The combat state is also changed as I've added different phases.Â
I then updated the attack functions later to fix bugs, when it lost sight of the player it would simply reset the final phase and when you came in sight again it would spawn more enemies.
I set up decorators to check if certain phases are completed so it could stop them.
Here I made a service to check if the time run is greater than 0 and if true it will set completion for the phases (this way it only spawns once).
This is the first phase, it calls do once (so it only spawns one time) then it sets is interruptible to false and spawns the AI spawners within a random reachable radius, and finally destroys the ai spawners and sets is interuptable to false.
The second phase and final phase are the same as the first phase only the radius increases and the number of enemy spawners also increase.
Weapons:
All the weapons below are NOT my models and were downloaded from free 3D models and also turbos quid.
AI Spawner:
I made AI spawners for each enemy type, where it first delays so it can run as soon as the game is played. Then it spawns the enemy type at the actor location, and on respawn it resets by spawning the actor again.
Ai Jump To:
The jump to function uses a nav link which essentially creates a path between, two points.
Animations (Enemy):
Each enemy type has its own animation blueprint.
ABP Manny:
 This selects a float between 0 and 1, it selects 0 if the value of the Disable Leg IK curve is greater than 0. The Disable Leg IK curve is a curve used in all montages to disable the leg movement so movement vertically isn't working, this way the animation plays properly.
Here it sets the direction which the character is facing, so it takes the actors rotation, then calls calculate direction (built in function) and takes the velocity (pre made variable).
ABP Melee:
The melee animation blueprint, blends between regular idle and sword idle with the condition that has equipped weapon is true, in other words it will use the sword idle if it has a sword equipped.
It also does this for the walk/run animations, except this time the sword blend space uses both speed and direction.
Here it checks if the pawn owner is player controlled if it isn't and the other factors are correct it sets should move to either false of true.
Checks if has equipped weapon (used when switching between regular and sword animations).
ABP Jump Melee:
Here it takes the main states as the base pose and uses layered blend per pose with the main states (upper body slot), it then uses the out put as the true pose inf the blend poses by bool. The false pose is the main states (upper body slot) and the condition is the velocity is not equal 0.
ABP Ranged:
 The ranged enemy animation blueprint functions the same as the melee animation blueprint except the animations are obviously the rifle animations.
The boss works differently as I got rid of the original Manny animations and replaced it with only the gatling gun animations as, the boss is always holding the gatling gun apart from during its equipping animation.
Enemy Materials:
The materials used for each enemy is just the mannequin material but I changed the tint colour in the material settings to give the coloured sections their own colours.
Section 2: Player
I also made a few things for the player such as a spawn point actor, which like the enemies is used to spawn the player (this is needed due to the level system shown further on).
The player implements the same damage and attack actor components for ease of use (this was initially done just so the player had a basic attack and could be damaged, however later on due to time limits the rifle shoot became the only weapon in the prototype.
Here are all the variables and event dispatchers used for the player.
The main ones being the ammo/gun variables, the player stance, walk speeds, and various other variables, some weren't implemented like player gold.
Ammo functions:
Take ammo sets the current rifle to the current rifle subtract the input taken amount and sets it as the output new amount (this output is incase it is required for quick access).
Has Magazines checks if the magazine count is greater than 0.
Reload function (this is the most important one), it first checks if the total ammo magazines is greater than 0 and current rifle ammo is equal to 0. Then if both are true, it sets current ammo to max ammo, then sets magazines to subtract one of itself.
Get current and max rifle ammo are self explanatory.
Level Select:
We needed a way to change levels and loading entire new levels cause many problems for the AI and other things like the health widgets and such. So instead I used level streaming, which means that when one "level" is loaded it unloads all the other levels actors and loads the new ones, compared to just changing the map which loads an entire new map.
Simple GUI to select one of the three levels available, Tutorial, Town level and Boss.
Event tick, first runs the first sequence, which checks if should interact is true (this is only true when in the vicinity of the level selection object), it then gets the interact reference seen in the code below, it then traces a line by channel starting from the first person camera world position, to the camera world position plus the camera forward vector times 500, in other words where the camera looks it traces a line 500 in that direction. It first promotes the out hit to a variable (used later on in the interact function) checks if something has been hit if it has it then checks if it implements the interactable interface (which anything that should be interacted with should have on) and if it does it sets is interactable to true and checks if the interact widget is within viewport, if false it adds it to viewport. And if the objects doesn't implement the interact interface or nothing was hit, it checks if the interact widget is in viewport and if it is, removes it and sets is interactable to false.
The create interact event creates and sets the interact widget used above. By pressing E it sets should destroy to false (so it doesn't destroy the player on leaving the level) and if is interactable is true, call interact select function.
Calls create interact widget on begin play.
Here is the interact select function which can do all the code needed after interacting with something. For the prototype there's only one purpose, to get the hit actor (from the line trace before) and check what it is equal to, if it is equal to the level select actor, then it creates the level select widget adds it to viewport and pauses the game.Â
This is the level select widget blueprint, on construction it sets game paused (this was used before as well so is redundant but I forgot to edit it), it then sets show mouse cursor to true (so you can select buttons), then sets the input mode to UI only. After it sets the player blueprint as a variable for later, gets the actor of class actor and then promotes the spawn point actor to a variable.
On clicking each of the level select buttons it will open the corresponding stream level and unload the spawn stream level, remove the widget from parent, set show mouse cursor to false, set input mode to game only and unpause the game.
These are the stream levels, the persistent level is the official map level, which is just a blank space with the sky box and lighting etc. as well as a player start as this is where the Main menu is used.
Pause Menu:
When pressing escape it loads the pause menu widget shown above, the play button just removes the widget, the settings button, opens another widget and removes the current widget, main menu button opens main menu widget, and quit exits the actual playing instance.
Player block:
The player block system was a last minute addition from me, as the player was being stun locked a lot by enemies, I wanted a difficult way to completely block all damage dealt, this doesn't work so well with bullets as you have to predict exactly when they're going to fire, but for melee enemies it can work if you have really good timing.
When you press F it checks if delay for block is true, if false it plays the blocking montage, and sets the delay for block to true and checks it again, it then delays for 0.05 seconds, sets is invincible to true, and after a 0.2 second delay sets it back to false (very short blocking timeframe) then it tells you that it is on cooldown, delays for 5 seconds and then sets delay for block to false and tells you that you can block again.
Hit Reaction:
Damage response, it first checks if is invincible is true, if false it disables input and plays a hit reaction (this staggers the player which is why I added the block) then on complete or interrupt it enables input again and sets stance to default.
Display Hud:
Here if the player Hud reference is valid it sets visibility to visible, if not it creates the widget and sets the player Hud reference and adds it to viewport.
Return attack token:
Calls the return attack token function (shown at the beginning with the BPC damage system).
Dead state:
If the player dies, it disables input, calls the death function and plays a death animation where on completion calls on respawn.
Death function removes all widgets and creates the death widget (I wanted it to be like in Souls games).
Respawn:
The respawn function is on event tick, it binds the event to on respawn (called after death), and it loads the spawn stream level and unloads all of the other levels, then calls respawning function.
Respawning function sets health, enables input and sets is dead to false.
Gun:
Gun stance:
When pressing the right mouse button it checks if the player has a weapon equipped (currently only gun) and changes to gun stance, then on release goes back to default stance (works as a sort of aiming system).
The gun and default stance functions used before, set the enumerator to their correct values and the walks speeds to their correct values, on gun stance it calls show cross hair and on default stance it calls hide cross hair.
Sets visibility of the cross hair.
Equip:
After pressing 3 it checks if should equip weapon and has not equipped weapon are true, if so it calls equip weapon, if false it calls unequip weapon.
Equip weapon, spawns the rifle actor, promotes it to a variable, then attaches it to the rifle socket and sets has equipped weapon to true, finally it calls on equip weapon.
Unequip weapon, checks if has equipped weapon, if true it detaches from actor, destroys the weapon rifle and sets has equipped weapon to false.
Shoot:
Shoot bullet, checks if has equipped weapon and is in gun stance, if true it checks if has ammo, if true it calls do once and sets can move to false.
It then plays an animation, where on completion or interruption it sets can move to true and attacking to false as well as the function reset bullet which was used so the player cant spam the shoot button. On notification it reports a noise event (for AI) sets attacking to true, then traces a line by channel (this has been shown earlier but it basically traces a line from the camera forward a long distance).
Finally, it breaks the hit result, selects the vector base on if something was hit, if something was hit it selects the location if not it selects the trace end and uses that as the player fire bullet trace end. The trace start for the bullet it the weapon rifle location, it then calls take ammo. The reason the damage amount was set so high is for testing purposes with the boss.
Level things:
I also made some general level things like a way back to spawn (not really implemented, a back to spawn from death for if the player falls into the void, and a tutorial door.
Tutorial door:
The tutorial door is used to destroy iteself when the tutorial enemy is defeated.
Back to spawn from death:
Here is checks on component begin overlap (box collision) it checks if the actor is the player, then it loads a level, if it is equal to something (not equal to nothing) it checks if the level is loaded and if it isn't it loads the level, (the level being spawn), then it also checks for each of the levels to unload, which are the town and tutorial (I didn't set up for boss as the boss is the end), it checks if it is equal to the town or tutorial, if so it checks if the level is loaded, and if this is true it unloads those levels.
Back to spawn door:
This works the same as the back to level from death except it unloads the level anyway as long as a level is loaded.
Boundaries and spawn point:
Boundaries are just a collision box (can be scaled and rotated etc.) And the spawn point is the player spawn point.
Widgets:
I created a widget for the boss and the player death (forgot to add the name so its just left as name).
Interact widget:
Fades the cross hair and E on construction.
Remove crosshair, checks if animation current time is 0 if so it plays the fade in animation in reverse and delays for 0.25 seconds before removing the widget, if the time equal to 0 was false it delays for 0.25 seconds before continuing.
Main menu:
On clicking the play button it loads the spawn level removes the widget etc. and at the end calls display Hud.
On construction it does the same as shown in previous widgets.
Clicking settings opens the settings widget.
Pressing quit just calls the function quit game (engine game).
Player Hud:
Here it gets the player current health over the max health and returns that as the health percentage.
Same as the health for the ammo.
Settings menu (not implemented):
The final thing I added was a settings menu, but due to limited time I never implemented these settings.