In February 2019, I began to learn how to use Unity to create games. I began with simple clones of classic games such as Pong (which turned out to be WAY more complex than I first anticipated), and eventually after following many, many tutorials, I was able to experiment and try creating different projects with vastly different gameplay mechanics. Although each project never got very far, I learned a lot through trial-and-error, and each time I began a new project I had a few less hurdles to jump over.
Something that I wanted to do from the very beginning was to take screenshots & recordings of my projects. I wanted to keep a record of how my skills and projects were progressing over time, mainly for my own benefit – being able to look back and visibly see your own progress is a great motivator when you’re feeling demotivated or discouraged, and it’s been a great reminder that persistence & practice are key to learning any skill.
Here’s a look at some of the projects I’ve worked on so far.
I followed a tutorial series by popular YouTuber Brackeys, which demonstrated how to create a simplistic RPG-style game. I had my own ideas of game mechanics I wanted to try implementing, and so ended up combining both into my first ‘real’ project.
One of the ideas in my mind was to create a health pickup system where the player could collect glowing orbs, restoring their health. If the orb was within a certain radius from the player, it would become ‘magnetized’ and move towards the player automatically. After several hours of prototyping, here was my initial result:
Bonus points if you can recognise what game my placeholder sounds are from.
After a little more refinement (and hunting for free assets online), I was able to produce a more complex prototype, this time with a working health bar above the player’s (newly added) head.
After another few hours of work, I added a basic enemy cube that would inflict damage on the player when it was within attacking range, and would take damage when clicked on by the player. Upon death, the enemy would drop several health orbs that the player could pick up.
While the entire project up to this point is still incredibly simplistic, it took me dozens of hours to reach this point. Despite the ugly graphics, the placeholder textures and the horrible grunting sound effects, I was proud of what I had made, and even prouder of myself for learning how to make it.
Despite grand plans to take this project further, I abandoned it shortly afterwards and moved on to a new project.
My next project was intended to be a Halo-inspired first-person shooter, including various game types such as Slayer, Capture the Flag and King of the Hill. I also wanted to learn how to implement networking & multiplayer into the project.
It turns out, I was getting way ahead of myself by even thinking about game types – I spent over 20 hours alone on the character controller code, and even then it had its fair share of bugs, and wasn’t extensible at all.
My first working prototype features a simple rigid-body character controller capable of walking, crouching, jumping and ‘sprinting’ (holding a button increases the movement speed by 1.25 or so):
The first-person model is purely for show – at this point, the player can’t actually shoot.
After another few days, I was able to implement a few more features:
- A simple shooting mechanic (shooting physics objects will result in them moving, and an impact particle effect will appear)
- Ability for the player to throw grenades, which will explode and add force to any nearby objects (including the player)
It turns out, since the grenades added force to nearby rigid body objects, even the player was affected – this inadvertently resulted in the ability to grenade jump up onto higher platforms.
Despite making some great progress on this project, I had no clear direction nor any real goals while developing it. I eventually embraced it as a learning project, rather than hoping to turn it into anything specific. I began trying to recreate some of the gameplay mechanics from Half Life 2 for further practice. I started with the ability to pick up and throw physics items, and then added a basic flashlight just for the heck of it.
At this point, I wanted to move onto a different project – one with a clearly defined scope that I would hopefully be able to finish.
After learning the basics of working with Unity, I wanted to start a new project that I could actually finish. I began with a rough design document of gameplay elements I wanted to create, so that I had a clearly defined scope for the project & clear goals to work towards. These gameplay mechanics were:
- A simple movement system
- Ability to climb onto ledges and taller obstacles (nothing crazy like Uncharted climbing mechanics, but just a basic one-button climb onto the top of an obstacle/over an obstacle)
- Ability for player to pick up objects and place the object down / throw the object to break it
- Ability for player to drag / push larger objects (i.e. large crates that are too heavy to pick up)
Overall, I felt that this limited sandbox of mechanics would still provide a good base experience for a player and would allow for a variety of gameplay scenarios & puzzles.
After a few hours of initial prototyping, I had a few of my mechanics in a working state:
However, a few issues with my implementation became immediately apparent. I was using Unity’s in-built CharacterController component, which while very easy to prototype with, was limited and restrictive in other ways – namely, it doesn’t play nicely with physics objects as the CharacterController does not use a RigidBody for its physics, instead resolving collisions internally. This meant that the player couldn’t push a box out of the way simply by walking into it – however, if the box was in motion (aka the RigidBody was awake) and the player walked into it, it would move, albeit in a jerky, obviously buggy way. I knew that at some point I would need to rebuild the character controller utilising RigidBody physics to get the results I needed.
However, before I did that, I wanted to prototype a vaulting system, where players could climb on top of any objects that had a surface within a defined height (i.e. so the player couldn’t climb to the top of a 20 metre tall cliff). I experimented with various complex methods of determining where the player could stand on a surface, detecting the edge of a surface, however these all produced inconsistent results and weren’t scalable (i.e. each climbable object needed to have a script, which I quickly realised would become a chore to apply to EVERY climbable object in the game world.
After pursuing various over-complicated solutions, I opted to use a simpler method in my climbing system. There is a trigger volume in front of the character (initially used for the object picking up & throwing system) which I re-purposed to detect when a player was facing an object. Out of all objects within this trigger volume, I would then detect if these objects were tagged as ‘unclimbable’, then I would find the tallest object out of the remaining objects. I would then cast a ray from a certain distance above the player (and in front of the player, of course) and see if we hit the same object (sometimes, the tallest object would extent above the ray’s origin point, so the ray would begin within another object – this was obviously not desirable as that means a player could then climb into a static object).
The result worked quite well, was dynamic (meaning I didn’t need to set up anything apart from ‘unclimbable’ objects), and was easily extendable (the player movement is performed within a co-routine, which could be easily overridden when implementing animations).
At this point, I became slightly side-tracked and began investigating how I could build a simple water physics system to further extend my physics-based gameplay.
Water & Water Physics
As it turns out, a simple water physics system is a bit of an oxymoron – there is a lot of complexity in even a simplistic water physics system. Here is my initial attempt, before doing any research into the topic:
The water clearly behaves more like jelly, as the objects immediately pop straight out of the water and then sits on the surface. After doing a lot of research into the fundamentals of water buoyancy and simulating ‘realistic’ physics within Unity (including a great talk by Ziba Scott at Unite 2015), I was able to get something I was pretty happy with. This system works on any rigid bodies within the trigger volume, and there is very little setup to be done (only tweaking the RigidBody mass of any objects that may interact with the water, to determine whether it will sink or float).
If anyone would like to see the entire C# code, you can see it below:
Aside from some slight jittering as the objects settle in the water, I was very happy with these results.
I was particularly proud of the water splash particle effects, which took my a few hours to create, but I’m proud to say I made entirely on my own.
At this point, I figured I should probably try and integrate these new scripts & effects into my main project (stupidly, I had begun this endeavour on a new Unity project using the 2018 version of Unity, while my main project had been updated to 2019 – in hindsight, a bad decision).
I had some trouble with integration my water physics into my main project – in fact, because I created my water shader using Amplify Shader Editor in Unity 2018 (standard renderer), this meant that the shader was incompatible with the Lightweight Render Pipeline in Unity 2019. I’ve still been unable to port the shader over, but luckily, my water physics script was easily usable without any further issues.
Seeing it all together like this really made me feel proud of my progress.
Current Status of Project
At the current stage, I’ve purchased a third-person RigidBody character controller (Easy Character Movement) & removed my own vaulting system for now – I’m reconsidering the mechanics of my game slightly, and trying to determine whether I want it to be a more linear experience or whether I’d like to introduce more randomness / physics-based gameplay.
I’ve also introduced the ability to break objects – if an object has a BreakableObject script attached, whenever a player throws it, it will trigger the Break() method, spawning particles & a random breaking sound (if these are assigned on the object). The BreakableObject can also spawn a GameObject when broken, the idea being that it will contain a pickup for the player, or a quest item, etc.
Here’s a snippet of this code for anyone interested:
Looking back on my progress over the last few months, I’m really proud of myself for the amount I’ve learned in a relatively short time span, and I’m really excited to see what I will be able to do in the future. For now, I’m aiming to continue building on my project and hopefully build a few levels into it – my hope is that I will have a single cohesive project that I can show as a portfolio piece, before moving onto the next.
This was also my first experience using HacknPlan, a project management tool aimed towards game development projects specifically.
Here’s a screenshot of my primary sprint board – it shows tasks that are to be started, in-progress, undergoing testing, and fully completed tasks, along with their estimated time costs & how much time has been spent on any single task.
I’ve found this to be an extremely useful tool as it’s completely free (aside from a few features aimed at larger teams with more complex projects), and it’s really helped me break my project into sub-tasks and focus my attention on high-priority tasks.
It’s a really great tool that I’d recommend to anyone working in game development to try out.