One of our game pillars was a diverse combat system (read about in the planning blog). Instead of just having a melee system, we also wanted to follow the path of sorcery and introduce a magical casting system.
Before jumping into scripting this mechanic, I wanted to research similar games that have introduced this kind of mechanics, such as Blades and Sourcery, Skyrim VR, and Waltz of The Wizard. All these games share the ability to cast a variety of different types of magic, and with this, in mind, our goal was to be able to let the player select a spell of their choosing and cast it from their hand using the trigger.
After researching other games that introduce a magical system into their game, I wanted to see if there was anything online about putting a magical system into Unreal Engine, and that's when I came across Sir_Fansi Gamedev youtube, which showed a magical system within VR. I wanted to use his videos as a base to help perfect this system.
Light & Heavy Magic Set-Up
However, since this was going to be a core feature of the game, I wanted to use data tables to make passing information across the project more simplistic, making the use of data less redundant.
To achieve this, I created a data structure that allowed me to develop critical variables such as;
Particle - the VFX particle that will be set in the casting blueprint.
Impact Particle - the particle spawned when the casting magical collides with an object.
Hand Effect - the particle spawned on the player's hand to show that the magic has been activated.
Index - the position the data will be sitting on the data table.
Name - the name of the magic.
Damage - the amount of damage dealt by the magic.
Cooldown - how long it takes for the magic to cool down.
Type - the magic type (similar to name but will be used for switch statements)
Strength Type - whether it is a light attack or a heavy attack.
Magical Class - the child blueprint that the player casts
Attack Parent - the parent of the magical classes (light parent and heavy parent) that holds variables and functions.
Mana - how much mana the magic has
Max Mana - the max mana the magic is allowed to have
In the two images below, you can see how I have turned the data struct into a data table and then manually input the desired values we decided upon as a team.
Nevertheless, I needed a way to access this data, so I created a scene component called inventory that would store a function called "Add Magic". It does pretty much what is in the name; it will get a reference to the data table by the row name that is being passed in outside of the function, then it will add one to the current index and then add that output to a spell library that is made up from an index and the magical struct I used to create the data table.
I have this function set up at the minute but not any way to access it. So that is why I added the scene component that I created called "Inventory2 to the player character, allowing us to get a reference. Then I created a new function called "Add Magic to Inventory". This allows me to reference everything in the data table and add it to that function I previously created, meaning we now have access to everything inside of it.
Now that I had all the data set up, I started working on the parent classes. I started with the light attack, which I set up to act as a projectile as I wanted to have force in the direction it was being spawned. The thing about data tables is that they store data, which cannot be changed during runtime, but I wanted to update nearly everything in our data table depending on the player's action. To do this, I had to create a function and pull the spell that's being cast from the player and then create and set variables that match the data from the data table. Doing this allows us to get the data from the data table and store it within the parent to be used when the blueprint is running.
Note: This step was repeated for the heavy parent class as well.
For this to be working in-game, I created a cast magic function on the player so that any time the right or left trigger was realised; it would get the light spell to cast that has been set when the player chooses what magic type they want to cast
First Attempt
Second Attempt
In the first attempt, you will notice how when the projectiles hit an object; they don't spawn an impact explosion. I wanted to tackle this in the second attempt as it gives the player visual feedback that they have hit something.
Light Magic Feedback
One of the critical things that were brought up during playtesting sessions was how players felt they couldn't hit any targets as they didn't know where they were aiming. I wasn't too sure how to tackle this problem as I wanted to avoid using UI elements as having things like crosshairs in VR can be sluggish for the player.
After meeting with the team, we thought that moving the magic to fire out the tips of the fingers would allow the player to use their fingertips as a guide while also trying to keep that immersive flow.
Magic & Crystal Link
After setting up the magical system, I then wanted to go forward and link it with the crystals as this was the primary source of how the player would select the magic type they would like to cast. (To read about the development of the crystals, see the "Crystal System" blog post)
Heavy Magic
After having many playtesting sessions, users felt that having a gesture for the heavy would feel more powerful and help immersive them into the game. This was when I started to look at a drawing gesture system that would allow the player to draw different symbols for different heavy attacks. This can be seen in the video below, where I started to test with simple circle gestures.
However, before taking this feature further, I soon realised we didn't have enough controls as the only input left was the 'Y' button. The only way for this to work would be if the Jump weren't bound to 'B' as we have tried to aim for symmetry across our controls as they should act like that player hands giving them easy access to the same features on both controls.
*Image designed by Luke Shingleton*
Therefore, I had to approach this from a different angle alongside Luke Shingleton. He had done a slam floor set up using a collision box on the player's hand when it overlaps with anything with the tagged floor (Read about this in Luke Shingleton's blog called Picking Up Multiple Roles...).
*Video contains work produced by Luke Shingleton*
Once Luke had handed over the base of the heavy slam attack, it was then my job to get it working with the crystal system and make it only usable when the player obtained the heaver power up. We also wanted to use this attack to allow the player to break down walls to access new areas of the map, as seen in the clip below.
Once I had set this up, I was then able to pass it over to our other game designer/ programmer Holly Boyle who did a freeze effect for the AI when they were attacked by the heavy attack, as seen in the clip below (Read about this in Holly's blog called Enemy Design & AI").
*Holly Boyle produced content in the video*
Magic Features That Didn't Make It Into The Final Game
If you look back at attempt one, you will notice how we had nine-light and heavy attacks. Still, due to the size of our scope and the amount of time, we had we reduced this down to two attacks (Fire & Ice) as this allowed us to make sure that these skills were polished and fitted the flow of the levels effectively.
As well, the heavy attack has been left out of the final game as with the redesign of the levels, it wasn't needed anymore, which was a better sacrifice for the game as losing one feature to have a more enjoyable player experience through level design was something we were confident in the making.
Out Of House Sources Used
Below is a list of all the out of house sources used to create the magic system. This is just particle effects, and all blueprints have been produced in house.
Comments