Battle of the Summit
Visual Scripting - TPS Boss
Battle of the Summit has been my favorite portfolio piece to work on, incorporating both visual scripting and gameplay. Something that I had been itching to do for a while.
Having previously delved into scripting with Mummy Madness and Unreal Engine with Afterlife I felt ready to take on this challenge. I had learned so much from the last two projects so this one I really wanted to have fun and push what I could do within the Unreal Engines Blueprint scripting system!
Created in 3 weeks - half time.
Using Unreal Engine 4
Using animations from Mixamo
Using free assets (models, particles, sounds) from Infinity Blade Challenge packs, the Paragon packs and the Unreal 'Learn section'.
- 3 Different Boss Attacks
- 2 Different Boss States
- Projectile and Damage system
- Weakpoint and Armor system
- Aim down sights
What I learned
- Boss animation montage
- Player blendspace
- Player aim offset
- Creating boss AI
- Creating an Animation Blueprint
- Advanced use of destructible meshes
- Using arrays to spawn multiple actors
When I set out to begin Battle of the Summit I was very excited. I had been craving to do gameplay and wanted to something fun to play that would feel epic. But most importantly, I wanted to challenge myself in visual scripting, since I had just scratched the surface previously and I had enjoyed C# so much, so I was very excited going into this project. Since doing my walking simulator, I had wanted to do something with the destructible meshes. All of this aligned very well with my pet peeve about third-person shooters where it's either only aim down sight or only shoot from the hip. I wanted both in this piece, and I could visualize really well how I was going to do it.
- Boss attacks, behavior and states -
Having clear visual feedback and communication was essential to me as the player needed to know what was going on. I had been inspired by finding the destructible meshes during 'Afterlife' and wanted to use their shattering as a way to reveal weak points on the boss. As for the weak points themselves, I wanted to make them distinct, so I gave them a sharp red with a scrolling texture on top as a placeholder. I had intentions of exchanging the material later, but it worked for its purpose, and at the end of the project I deprioritized lifting their visual standard since they were fully functional for their purpose.
I knew a couple of things when I started.
A) - I didn't want any melee interactions since they are heavy on the animation and collision department, and I wanted to get as much bang for the buck as I could.
B) - It was important for me to have attacks that made the player act differently, not just looked different.
C) - Two attacks were the minimum but if at all possible I wanted the third attack to keep the boss fight fresh.
Knowing this I tried to state the basic functions of each attack.
- Attack 1 - Get the player to move in a basic manner, it shouldn't be safe to aim all the time.
The primary 'fire projectile' at player ability was a pretty straightforward to make, and it fulfilled the requirements I had for it. It also had the added benefit of being able to use much of what made the players attack work in the first place.
- Attack 2 - Test players attention, prevent the player from camping behind an object, give the player more things to handle a the same time.
Looking at these traits, I came up with the 'Summon Ice Staff' ability, it checked all the boxes, and I thought it would be less resource heavy than the other alternative that I had in mind; suicide minions (small minions that would run towards you and explode).
The minions would also have worked, but at this point, I was tired of dealing with animations, so I chose the more particle heavy option. This proved to be a challenge in itself since good particle effects are hard to come by for free.
- Attack 3 - Make the player sprint, a risk-reward scenario for the player, a window of opportunity and easily implementable.
The last attack I decided to have a slam attack that would send out a shock wave in a 360 degree from the boss. It was fairly easy to implement since I chose to use projectiles as the shock wave. This way I could also easily re-purpose my already existing boss projectile. The window of opportunity came from the idea to have a weak point spawn on the back of the boss. Having a weak point there would be hard for the player to get to during the other attacks since the boss would rotate towards the player in those.
The solution was to make him do several slams in a row and not having him rotate in between them, giving the player the incentive to sprint between covers making their way behind the boss to finally get some well-earned damage on the boss.
To me, having the three attacks would have been a wasted opportunity if I didn't change them up a bit sometime during the fight. Since all the scripting were already done, it was a matter of turning on a bool and changing the metrics to get some different gameplay that would feel fresh and exciting to the player.
The second state triggers just after the weak points are destroyed and the boss gains his slam attack. Now both his attacks are faster executed, and his cooldown on his shoot ability was also lowered. Had I had a bit more time I would have liked to switch the pattern of attack more than just adding the slam attack.
As I, unfortunately, ran out of time the second state is only visually communicated to the player via a one-off particle effect, but what I really would have wanted was to make a material instance of his skin to tweak the different colors on his body to visually accent the change in behavior.
- Everything is connected -
Rewriting the on hit system:
At the beginning of the project, I had set up a system that would check with a 'cast to' what I had hit in the projectile. This was fine, to begin with, but as the project went on, I wanted to check more and more things. I ended up having 8+ branches with 'cast to' checks to every individual item I could hit. I knew it wasn't a sustainable solution, so I decided to find another way to do it. I had previously seen someone use an 'Event Hit' function and it hit me;
instead of using the projectile to check what it was hitting, I could migrate the checks to the objects themselves, not needing to be cast to, but instead registering that they had been hit and from there, checking what had hit them.
This saved me from the headache of having all the casts in different branches in the same object which made my workflow a lot smoother.
Creating a shock wave:
II had used lists before in C#, so I was convinced that the way to go was with the equivalent in blueprints called an array.
Since I didn't know beforehand how many projectiles I would need to spawn to make it feel like a proper shock wave without killing the frame rate I decided to try and make it as tweakable as possible.
The only thing I knew was that I wanted it to cover 360 degrees around the boss, so the simple solution was to divide 360 between however many projectiles I'd have and then time it by the index number. This way I would always get an equal distribution of projectiles while only having to change one number to test different variations.
Integrating functionality with animations:
A lot of the boss behavior was dependent on the animations since I chose to use animation montage notifies to call the events I wanted the boss to execute.
This meant that there was a lot of communication going on between the animation blueprint and the boss blueprint.
One of the hardest parts was to integrate the flinch animation since it would cancel the other animations and take priority to give feedback to the player. But that could leave an AoE indicator of the ice staff attack on the floor if the boss flinched mid-animation. But here notifies at the end and beginning of animation were, again, useful to know when they would 'allow' the boss behavior to proceed, furthermore the way I set up the default behavior of the boss helped with always defaulting back to shooting if there were any 'doubts'.
I knew I had to set up a simple decision tree to get the boss to function. I decided to prioritize the attacks in a branch, so the boss would never get to his shooting behavior if he were supposed to do a summon or a slam.
So the lowest priority (shoot at the player) is the one behavior that the boss will default to if other conditions are met.
Attack priority visualized
- An integral part of telegraphing boss attacks -
Doing a 3D boss fight, I knew I had to focus a lot on telegraphing the attacks of the boss. This can be done in many different ways, but the most natural and fluid is, in my opinion, using animations to set expectations. Everything besides that, like markers or lines, are supporting features to exaggerate the already telegraphed attack.
Using Mixamo for my animations were useful since I could pick and choose from a wide variety of animations that didn't necessarily belong to the same pack. For coherency, I only used one pack made for a spellcaster.
I did quite a bit of research on how to properly use the animations with other gameplay elements. Since I wanted the attacks to be tied to the animations, I decided on using an animation montage, allowing me to use notifies to call events on specific frames. This, for example, let me time the shot to be fired at the exact frame of the extended arm of the boss.
It wasn't a miracle solution on all fronts, but for a boss fight, I would definitely say it was the right choice.
Setting up a proper blend space and aim offset to blend between the basic animations was a pain, and took me a long time to get properly working.
But as it was central to the experience, I had no other choice than to sink a good deal of time into it. Looking back at the project I would have preferred to buy a template and focus more on the scripting.
Battle of the Summit has been my favorite portfolio piece to work on by far. It has been a joy to be able to script something solidly from the bottom up and knowing what you did before you blindly fumbled your way forward. Almost all decisions in this piece were well thought out and planned for.
It wasn't by any means easy, but it was fun and challenging in a way I could have only hoped for.
It taught to be a lot about animation, boss design and most of all visual scripting.
Most notably I think going from the 'cast-to chain' to 'event-hit' and scripting the shock wave were some of the experiences where I really felt I developed as a scripter.