The final battle between the character and the monster relies on a collision box for the range the player can hit the monster at, as well as a sphere collision. Inside this sphere collision there is a flipbook of a flare that I made for this exact part of the game. When the monster comes into range, the player can press F and kill it by launching the flare.
This is the code inside a blueprint actor that detects when the player overlaps and will sett of the monster walking. I describe how this works in the "Other Code" section of this site and so will not be doing it here as it is a waste of time.
When the custom event "Start Walking" is activated by the cast from the collision box, a timeline is started. Every tick in the time that the timeline is active will cause the update execution line to progress.
every time the update line is activated, a vector lerp will be needed. The code on the left will get the alpha of the timeline and place the player at the proper location based on A and B, in this case being the world location of the flipbook (monster) and the ER (Location to walk to).
The update line leads onto a "set world location" node which is hooked up to the paper flipbook. This moves the paper flipbook to a location determined by the LERP (VECTOR). This ensures the monster mooths smoothly along the screen like it's walking which I think is a very cool effect and something that increases the graphics rating of the game as a whole. The movement is practically a complete match to the player walking and stands out in no way.
When the player overlaps the monster blueprint, such as the monster walking into them and vice versa, the capsule component will detect that an overlap has happened and will rule out that is is a normal interaction by checking the tags in the first half of the sequence. The second output in the sequence will check if the actor that is overlapped has the tag "MonsterHittable". This leads to the player death event being activated.
The final part of this execution line includes casting to the overlapped monster blueprint and setting off the "Killing Player" event. This is seen plugged into the stop branch of the monster blueprint in a previous screenshot, and ensures that the monster stops at the player as if they are mauling them to death rather than hitting them and walking straight by them. This just makes more logical sense and makes the game more realistic.
The player death event is really simple, it just sets the max walk speed of the player to 0 so that they can't run away from the monster anymore, it then leads onto a camera fade with the target set as the camera manager. This just means that the player camera will start to fade to black, with the fade happening over 2 seconds and going from full visibility to total darkness. The darkness is kept the same by a delay node which lasts 4 seconds before the level is opened again. This level is set by name as you can only every die in the last level, meaning there's no reason to make this dependent on anything. The player always starts with a fade from black too, making the transition seamless.
When the player presses F, the game will check for all of the overlapping actors of "Gun Range. This is the long collision box infront of the player in the player blueprint. The for each loop will just check all of the actors in order to determine if the monster is within range.
The loop body consists of a simple branch checking whether the hit actor has the tag "MonsterHittable", if so, the branch will enter a sequence to break the loop and stop it repeating.
The sequence goes into a set node, this node gets the location of the sphere collision at the end of the range box in the player blueprint. This sets a variable called "WhereFlareShouldGo" so that the flare can actually move to a set location. TThe next thing is making the flare visible so that you can tell that it has been fired at the enemy, this is done through a very simple "set visibility" node with the flare flipbook as the target and the new visibility being true.
You can see above how the character is stopped from moving by setting the max walk speed to 0. This is so that the player has to experience the ending of the game without wandering off, adding to the gravitas of the ending and game as a whole. It also shows the player that they don't need to do anything, allowing them to watch the monster death and see the end screen without worrying about missing something.
The code shown in the image below is what makesw the flare move. A timeline is used to monitor the speed at which the flare travels, updating the location of the flare though a "set world location" node. The new location is determined through getting the current location of the flare and then the intended final location of the flare, using a float in the timeline to manage the movement. This then plugs from the LERP to the "set world location", allowing the movement of the sprite.
The flare comes with it's own collision, when the flipbook moves, so does the collision surrounding it. As you can see on the right, this is because the sphere is underneath the flare flipbook in the component selecter and so will have to copy anything that happens to it's parent. In this case, it's movement. When the sphere detects an overlap, a branch is used to check the tag of the overlapped actor to determine whether it is the monster or not. If it is actually the monster, the visibility of the flare is set to false in order to create the impression the monster has been hit.
The code then ensures that the flare is gone by deleted it completely through the "destroy component" node. This leads to a cast to the monster blueprint which is used to activate "MonsterWasShot".
The "MonsterWasShot" event will spawn an actor named "MonsterIsDead" at the same location as the paper flipbook component within the monster blueprint. The spawn location is brought from the paper flipbook location being converted from a vector into a transform variable, the actor spawn node is also set to always spawn the new actor no matter the collision issues involved. To finalise the code, the moster actor is fully destroyed, saving processing power and clearing the living room.
The new actor being spawned is literally just the death animation of the monster. This is so that the death of the monster leaves some fleshy mush on the floor for dramatic effect and realism, adding to the user experience.
When the new actor is spawned, there is a 1.999 second delay before setting the visibility of a paper sprite which is alongside the flipbook in the blueprint actor. The reason behind this is that the death animation will be on the final frame around 1.999 seconds after starting, meaning that by setting the visibility of the animation to false and the sprite visibility to true, I can act like the monster has stopped moving like it's dead on the floor rather than the animation just repeating itself. From here, a cast to the main player with a 1 second delay to allow the player to see the monster dead allows me to activate a custom event within the player called "You Won".
This is the view of the entire actor for the player dying, I turned on visibility for the single sprite and moved it to the side so you can see what is is.
The ending code of the game is quite anticlimactic. The only thing "You Won!" actually does is create a widget called "W_You_Survived" which is then added to the player viewport before the game is paused. This means that the win screen will pop up without any issues and the pause will stop the player overlapping any actors in the level which could affect the survival widget such as distorting or obstructing it as well as making the game less likely to crash due to things like unhandled exceptions.
Below is the win screen for the game. It was made on Asesprite last minute in order to give the player a sense of achievement and accomplishment. I also like the idea that the player thinks there's different endings and so tried to get them despite there only being one real ending. This increases the fun players have as well as giving the game more playtime than just a single playthrough.
(Skip to 5:40)
Conclusion
In conclusion, the final battle goes smoothly enough that I consider it to be perfectly adequate for the game. It doesn't have any glaring issues in terms of bugs or glitches to note, but there is definitely one thing I wish I could add but unfortunately don't have the time to anymore. If I had the time, I would add a popup saying f to shoot. This would have made it more obvious to the player that they can kill the monster using the flaregun they picked up from the basement earlier in the game. Since the popup isn't there, players don't know they can do anything against the monster and would probably end up getting frustrated alongside their immersion broken due to not being able to complete the game. To counteract this I'll put an explanation in the itch.io page, but it's unlikely to help too many people avoid the issue completely.