Unity Scripting - 3D Platformer
Mummy Madness is a Third Person Platformer, where our little mummy will have to find its way back into its tomb in the pyramid.
To do so, it must traverse the treacherous desert, by jumping over the dangerous quicksand, avoiding traps and taking all the treasures he can find with him to his burial chamber.
The game is heavily inspired by Crash Bandicoot and leans on many of the tropes of third-person platformer genre.
- Created in 6 weeks at half time - 4 hours a day
- Using Unity 2017
- Using Animations, Particles and tweaked Models from Unity Asset Store
- Challenge my scripting skills with every feature
- Make something I would love playing and love showing off.
- Capturing the feel of an old 3D platformer.
- Using only free assets
What I learned
- Handling 3D collisions through raycasts.
- Scripting non-physics based movement.
- Using Animation Curves to affect a variable.
- Scripting a Jump.
- Using Lists to handle multiple assets easily.
- Scripting an attack.
- Setting up a system to manage Collectibles.
- Respawning collectibles in between checkpoints.
- Scriptable Objects in Unity.
- Setting up a system to manage Audio.
- Doing small custom animations in Unity.
- Using Animation State Machines.
- Using Animation Blending.
- Setting up a 3D UI.
Try it here:
(Windows 64bit and gamepad required)
When I began Mummy Madness, I was a novice when it came to scripting, but during its development, I found out just how natural it felt to me and how much I liked it!
Wanting to delve deeper into scripting while making something that would be fun and lighthearted to play I chose a third person platformer.
I grew up on platformers and wanted to challenge myself and see how far I could get with me at the time newly acquired skills.
- Difficulty scoping when not knowing your own abilities -
My initial goal of the project was lofty with only four weeks of prior scripting experience, and that was scoped for two weeks. Initially, I had planned for three levels and a slide. As the project progressed, I had three half levels, no slide, no TNT and UI that were only half done. I had barely managed to pull of the attack within the two weeks but had no enemies to use it on, so It wasn't that useful to have.
After taking a critical view of my scope, I decided to use the last few days of bringing just 1 level to a polished state, scrapping the two others. This turned into a game that was playable, but far from good.
When getting back into the project after a month, I decided to set up a Trello to get a more realistic feel of what I should be aiming for.
Since we had worked with SCRUM before at school, this proved to be very effective, and when I came to week three out of four, I could focus on playtesting and bug fixing. A thing that I would have never been able to do without proper planning.
- Condensing down the gameplay -
After I had cut my three levels down to one, I decided to approach the level a little more systematically. I wrote down all my gameplay elements and tried to plan them out during the level. I had quite a lot of features, and I could have cut some, just for the simplicity for the game, but in the end, I thought it made the game more fresh to include all of them.
After the first iteration, I tweaked a couple of things, making sure the player learned how to use the attack. Afterward, I placed out a bit more crates and coins to help players complete the still pretty hard game.
The one thing I wish I had seen in time to move it around was the introduction, and the advanced appliance of the sinking pillars was actually switched in the order they appeared. Had I had more time, I'd take a second look at moving the part before the oasis at a later point in the level.
Scripting Collision and Movement
- An unessecarily complex, but giving, process -
As the title hints, creating all of the above has its drawbacks. When beginning on this project, I was still relatively new to scripting and wanted to know how all of these things play together.
My fellow student Joshua Ravn Christiansen had a lot of scripting experience an offered to tutor me in how to script a controller and collision along with the jump.
This was a big help since I wouldn't have known where to start otherwise and he was in general, a massive support during the whole project.
The process was an interesting venture but ultimately caused more headaches than were needed had I stuck with Unity's built-in controller an tweaked from there.
This resulted in problems with clipping through the floor after landing which was very unfortunate since it offset some of the precision you'd want in knowing how high you jump.
Following the tropes of a 3'rd Person Platfomer
- Making it feel right -
I think my favorite part about doing the movement was looking at how the jump works and feels in 3'rd person platformers. It was fascinating trying to analyze what made them easy to use and precise. I concluded that A lot of the feel of the jump was how the jump was curved. It needed quite a bit of airtime and air control to feel enjoyable to use.
To this purpose, I used an animation curve to define how the jump would curve into and out off the jump. The air control was made into a variable that was easy to tweak as well making the most crucial part of the game easy to tweak to a state that felt just right.
But even with a jump that felt right, platforming from a 3rd person perspective poses obstacles with navigation as the player won't always know where they are in the air in relation to the ground. This was the feedback I heard and could see when testing with people. At this point, I looked to Super Mario 64 that had the ingenious idea to use a drop shadow directly under Mario to always show where he was going to land. I found a unity package that had a blob shadow, and after implementing it, my testers found it a lot easier to navigate the game.
Jump forgiveness was something the game desperately needed cause of its brutal difficulty, and it's a sub-par character controller. But the system we had for jumping was not very open to tweaking, it felt like having painted yourself into a corner and finding out you missed a spot. Ultimately with help from Josh, I figured it out, making the game much more enjoyable.
- A challenge, a requirement for game feel and an utter pain -
For Mummy Madness to fulfill my vision for the game animations on the character was a must. But already from the beginning, I was a bit unsure of how I'd make it work with having an attack that you could use while walking. Also finding a character that worked well.
I did some research and found that mecanim characters had a lot of advantages, so I chose to go with that which made later steps way easier. For example, creating animation blending, so our mummy friend could attack and walk at the same time. The attack, however, were non-essential to the gameplay when looking at the games final state, though it was a fun challenge to script, my time would probably have been better spent elsewhere.
mecanim would also have allowed me to use any animation that had a humanoid rig, which I, in the end, didn't use since animations were included with the mummy.
The reason I prioritized animation was because of the 3rd person camera. The perspective doesn't immediately lend itself well with precise platforming, and a lot of readability comes from knowing where the character is in the jump. If you look at Crash Bandicoot, for example, he makes a front flip during the apex his jump making it very clear when you are going to descend. I wanted to apply this in Mummy Madness, and I had the right idea, but once again, the jump and collision script hindered proper implementation, making it inconsistent and unsuited to fulfill its purpose. I also didn't do my research properly this time around and made each animation transition with bools instead of triggers, which made the transitions less consistent.
Collectibles and UI
- Deceptively tricky for a new scripter -
I early on knew I wanted a 3D UI since I was curious as to how it worked. I had done 2D UI before, and it hadn't caused significant problems.
Collectibles weren't too hard to get working, but the issue of checkpoints and respawns posed itself.
Scriptable Objects and Lists:
Since I had sections of the game that required crates and TNT's to complete it was an issue when killing and respawning the player since I somehow had to keep track of what objects I had killed in between this and last checkpoint. I solved the problem by converting my crates and TNT into Unity's 'scriptable objects' adding them to a list in my checkpoint manager as they died.
Running through the list and respawning each object when the player died and finally clearing the list once the player had either died or reached a checkpoint.
A thing that I discovered through playtesting was that players were missing coins from crates and in general had a hard time colliding with the coins. It is quite common to have a kind of attraction in these games, so I made a coin magnet to relieve this issue. Going back into playtesting, people were enjoying the game a lot more, so the problem was solved successfully.
Mummy madness was for me my first adventure into the world of scripting.
And while there is a lot of things that I would have done differently now that I've learned so much.
Hindsight is always 20-20, but even with its faults, I'm really proud of how Mummy Madness turned out.
The thing I would look most closely at if I were to redo this project is the collision cause it has a negative impact on the gameplay which is unfortunate.
All in all, it was super fun to create and try to polish something from start to end.
And most of all I'm grateful that I was introduced to the world of scripting.