3D Platformer GameDev Series – Weekly Blog #8: Health System and Player Knockback

Hey everyone! Whoa… It’s been about two months since I started this weekly blog series and the 3D Platformer Udemy Course. I feel that I am now heading into the bulk of the course material where the coding and logic is starting to get a bit more complicated to grasp – you may realize this too (if you have been following this blog series all along) when I attempt to explain how to implement player knockback today.

Before I dive right into the main content of my post, there is a key concept that I would like to mention again as it is becoming more evident when making a game in Unity and programming in C#:

“Individual scripts should only handle their individual elements.” – James Doyle

This concept was introduced earlier when the ‘GameManager’ script was created. You may recall that this script deals with everything that happens at the broader game level. However, that’s not to say that we cannot create – as we have done – instances of individual scripts and functions within them to call or be called by other scripts. We saw how important this was for the first time when player respawn was implemented and then again when checkpoints were added. This keeps the script and coding logic much more easy to read and follow! So as I progress further in the course, I will point this out less; by now, you should be able to see clearly how scripts, in a sense, interact with one another.

Now, onto the main topics of this post. The first thing is to create a health system. While it may be tempting to create it in the GameManager script, as I had just reminded everyone, we would want a separate or individual script for handling and managing the health system instead:

HealthManager script

The health system is really simple to set up as you can see from above. And because the script is set up as an instance, the ResetHealth function can then be called in the ‘GameManager’ script whenever the player respawns:

GameManager script updated

Now, something is needed to reduce the player’s health and to call the ‘Hurt’ function in the HealthManager script. For this, let’s add a spike trap to the game!

Spikes (add to game scene)

Just as we did with the Killzone created earlier and the checkpoints added before, for an interactable object such as these spikes, a box collider is added and the “Is Trigger” enabled to allow the following “HurtPlayer” script attached to the spikes object to work:

HurtPlayer script

Excellent! The only thing left to do now is to set up the player knockback when the player gets hurt. For this, we turn back to the ‘PlayerController’ script. Yes, you read right… I didn’t think we would have to turn back to the PlayerController script either…

PlayerControllerKnockBackPart1
PlayerControllerKnockBackPart2

Oh my… Did you understand all of that? It took some time for me afterwards, but if I were to try to come up with this logic myself, I honestly don’t think I would have been able to. And as an aside, this is one thing that especially bothers me sometimes. That is, for someone like myself who is not naturally good at programming and logic, it bothers me when I understand some aspect of coding only afterwards in hindsight. Although, I do believe that there are always more than one ways of doing or solving something. That being said, can anyone think of another way to implement player knockback? 🤔

PlayerKnockback

Anyway, that’s it for this week’s blog! I hope you enjoyed the read. Stay tuned for next week when I make our robot player temporarily invincible and flash after getting hurt!

– Taklon

3D Platformer GameDev Series – Weekly Blog #7: Adding Checkpoints

Hey everyone, I am now past a quarter of my way into the 3D platformer course! This past week, I learned how to add and set up checkpoints (which makes sense after setting up and completing the player respawn last week).

In 3D (and especially 2D) platformers, players often encounter locations or spots called checkpoints. Upon entering/visiting a checkpoint, the player will respawn there the next time rather than at the beginning of the level or stage.

Similar to how a killzone was created earlier for the player being ‘out-of-bounds’, an empty game object for the checkpoint is added to the scene and an appropriate collider attached to it with the “On Trigger” enabled (to allow the “Checkpoint” script to work; see further below). The game asset for the checkpoint (resembling a circular button/switch) is added and made a child of the empty checkpoint object and is then further duplicated; one of these assets represents the checkpoint’s ON state (which would appear yellow) and the other/duplicate represents the OFF state (which would appear greyish-blue):

AddingCheckpointToGameScene

The “Checkpoint” script attached to the checkpoint object introduces two new coding concepts. The first concept is the ability to pass a variable into a function being called in another script (the “GameManager” script in this case; see further down below). The second concept is the use of a “for loopto generate a list/array and to assign a number/element to each of the items in that list (in this case, all the checkpoint objects in the scene).

CheckpointScript

To see how the first concept works, the following is set up in the “GameManager” script:

GameManagerScript(checkpointNewSpawnPoint)

To see how the second concept would work, multiple checkpoints are added to the scene (which had already been done) and the final result looks like this when the game is run:

CheckpointsPlayerRespawn

You may have noticed when the checkpoint is active, there are some particle effects happening. This was also introduced in the course this past week using Unity’s built-in particle system. I must say, it had piqued my curiosity quite a bit! No doubt, I think it’ll be a lot of fun to play around in it sometime to create some very interesting effects. 🙂

But for now, stay tuned for next week when we will look at how to create a health system!

– Taklon

3D Platformer GameDev Series – Weekly Blog #6: Completing the Player Respawn

Hey everyone! It was a rather busy work week for me so today’s blog post will be relatively shorter than my previous posts for this series. Still, I did get a chance to go through and reproduce all the material covered so far in the 3D Platformer course on my own (as I said I would do each week before moving onto the next section of the course). Today, I will introduce Unity’s UI tools to finish setting up the player respawn by adding a fade in and fade out transition. Let’s hop right to it!

As you may know (whether consciously or not), User Interface (UI) is essential to all software applications and programs. In video games, the UI is comprised of all the screen displays that the user can see and/or access (i.e.- maps, inventory system, dialogue boxes, menus, etc..). The UI is also involved in generating screen transitions and effects.

In order to create a fade in and fade out transition for the player respawn, the first step is to create and add a UI object called a Canvas to the game scene. The canvas is set to scale with the screen size such that it can fit across any monitor’s resolution. The next step is to add a UI image (“BlackScreen”) under the canvas object. The UI image is resized to match the size of the canvas and to overlay it completely. Of course, an appropriate black colour is also assigned to it (the colour it will transition to and from):

Canvas (UI object)

After setting up the game scene, a new C# script called “UIManager” is attached to the canvas. In order to access Unity’s UI scripting elements and classes, the “UnityEngine.UI” namespace must be declared at the start of the script. This allows us to add and display a 2D Image or sprite to the canvas (a black screen in this case). Lastly, two boolean variables are used to generate the transitions (note: the coding is inversely written for the ‘fadeFromBlack’ transition which is not shown below but included in the script):

UIManager script (fadetoblack)

In order to call the transitions to occur, this is done in the GameManager script. Last week, we had set up the player respawn in the GameManager script by making the player disappear when it enters a killzone and then reappearing at the player’s starting position after 2 seconds. Now, we will trigger the two transition effects when the player disappears and when the player reappears (note: the camera is also disabled and re-enabled in order to fix an issue whereby the Cinemachine camera swivels around trying to follow the player which had just respawned at a distance from the killzone):

GameManager script (camerafix+fadetransition respawn)

By setting and enabling the fade from black transition as the default game state, the game begins with a fade transition – the final result of the complete player respawn looks like this when the game starts:

PlayerRespawnComplete

I must say, I am quite satisfied with my progress and pacing so far – and I think committing to a weekly blog is especially helping me stay on track. I’m already looking forward to this coming week, when I will learn how to create and add checkpoints/savepoints to the game. Stay tuned!

– Taklon

3D Platformer GameDev Series – Weekly Blog #5: Creating a Killzone and Setting Up Player Respawn

Wowzas! It seems like the past few weeks have just been rolling by! Alas, after spending a little over a month on learning how to setup the player and controls, I can now shift my focus to the game environment and its effect on the player. This week, I will demonstrate how to create a “killzone” – and with it, the player respawn.

So first of all, what is a “killzone“? Well, actually, this term is something that the course instructor, James Doyle, uses to define an area which kills the player upon entering it. In most 3D platformers, the main killzone is the one which defines the area that is ‘out of bounds’ – the player is usually killed if they fall or manage to jump into it. Below (click image to enlarge), you can see how such a killzone is created, re-sized, and positioned in the Unity game scene:

KillzoneObjectInGameScene

In the image above, you may have noticed that we also created and attached a new C# script (called ‘KillPlayer’) onto the ‘KillZone’ empty object. Also, enabling ‘Is Trigger‘ on the box collider added component allows us to then use a function in the script called “OnTriggerEnter“. In this case, the function will be used to respawn the player (Note: The player respawn function is being called from the GameManager script):

KillPlayerScript

So you might be asking, “Why is the Respawn function being called from the GameManager script and not coded and executed locally in the KillPlayer script?” “Individual scripts should only handle their individual elements“, James Doyle answers in response. For this reason, the Respawn function is set up in the GameManager script since the GameManager script controls things at a broader/global level. Not only does it make the code/logic easier to perform and follow, this also makes sense since player respawn can be triggered by more than just the player entering a killzone (e.g.- player being killed by an enemy, etc..). Here, we begin setting up the player respawn function in the GameManager script:

SettingUpRespawn

One thing to note above is that the newly introduced ‘Awakefunction is called before the ‘Start’ function. To keep the code more logical to follow and process, the ‘Awake’ function is used here to setup the GameManager ‘instance‘ before any code in the ‘Start’ function is executed. This is done in order for the KillPlayer script to call the Respawn function. The same is done in the PlayerController script; that is, an awake function is used to setup the PlayerController as an instance of itself when the game starts. However, to actually make the player respawn using these instances, we also require a new function called a Coroutine. A coroutine can be used to execute code to perform a series of events, and more importantly, allows the ability to pause the execution of that code in between while other code is executed (i.e.- in the update functions):

RespawningWithCoroutine

It can be a bit difficult to explain and understand the code (and I won’t go any further than what’s described above), but essentially, using a coroutine this way can allow us to achieve the following player respawn effect in the game:

BasicPlayerRespawn

Next week, we will finish setting up the player respawn by fixing the camera and jumping animation glitch upon respawning (as you may or may not have noticed) as well as including a fade out transition during the respawning.

I hope you enjoyed reading this week’s blog post. Stay tuned for next week’s!

– Taklon

3D Platformer GameDev Series – Weekly Blog #4: Jump Animation, Fixing Game Logic, and Improving Aesthetics/Controls

Hello everyone! I am now officially one month into the 3D Platformer Udemy course! Today, I will use what I learned last week in implementing idling and running animation states in order to add a jumping animation to our robot player. Along the way, I will fix some of the ‘game logic‘ concerning the player’s jumping ability and speed. Finally, I will setup and improve some of the general game aesthetics and controls. Alrighty, let’s dive right into Unity!

We begin by opening our Player Animator again and adding a new state for “Jumping”. We then assign our built-in robot jumping animation to it, disable exit time, and set an appropriate fixed duration for the animation (similar to what was done for the idling and running states last week):

AssignJumpAnimation(Animator)

Next, we create and assign a boolean parameter called “Grounded” (similar to the way we created the “Speed” float parameter before). To transition from our “Idle” to “Jumping” state, we can trigger this by setting a condition whereby the “Grounded” parameter is false (Note: the same condition applies for our “Running” to “Jumping” transition – which is not depicted below):

State Transition (idle to jumping)

The opposite transition (from “Jumping” to “Idle”) is triggered when “Grounded” is true and the “Speed” is less than 0.1 (Note: the same condition for grounded is true for our “Jumping” to “Running” transition except speed must also be greater than 0.1 – not depicted below):

State Transition (jumping to idle)

In our player controller script, we add a line of code at the bottom that would determine the value of “Grounded” (similar to how we had set and determined the value of “Speed” in the line of code just above it). At this point, we shall also fix a game logic issue whereby the player can jump higher and higher without ever touching the ground. This can be done by using a Unity function called “isGrounded” on our character controller (not to be confused with the “Grounded “parameter in our animator as it is not the same thing!) – which checks to see if the player is on the ground before the jump button can be pressed again:

JumpAnimationScript

A second game logic issue occurs when the player holds down two adjacent directional keys to move diagonally, causing the player to move almost twice as fast! In order to fix this issue, we add a line of code before the movement speed is determined to normalize the player movement speed regardless of the directional input.

Another game logic issue persists when the player walks off the edge of a platform. In this case, the player snaps instantly to the ground below the platform as a result of the speed of the gravity on the player continuing to increase indefinitely (until the jump button is pressed). This can be fixed by resetting the gravity speed to zero whenever the player is on the ground:

NormalizingMovementAndFallingOffEdgeFix

And onto the game aesthetics now! The first thing we can do is to hide the mouse cursor in the game. To do this, we add the following two lines of code in a new Game Manager script:

GameManagerScript (hide mouse)

Finally, we re-assign and add additional controls to enable full game controller compatibility. Of course, a must for any 3D platformer is to be able to rotate the camera – often achieved on the right analog stick:

SetupControllerInputs

Alas, our robot player is complete with most if not all of its game logic issues resolved! And… we can now use an X-box controller to test out the controls!

PlayerControllerAndAnimatorFinal

Next week, I will learn how to create a “killzone” (an area which would “kill” our player upon entering it). This would set the stage for us to implement a respawn system for our robot player. Thanks for reading and stay tuned!

– Taklon

3D Platformer GameDev Series – Weekly Blog #2: Player Movement, Jumping, and Camera Tracking

Alrighty, it’s Sunday! As I mentioned last week, at the end of every week, I shall update everyone on my progress in the 3D Platformer Udemy course I am taking. If you have not checked out my opening blog post for this GameDev series, I do recommend having a read there as a preface before carrying on here.

So, am I enjoying this course so far? Absolutely! I must say, when it comes to understanding the course material, my decision to take a slow and measured approach to learning is really helpful, particularly in my retaining that knowledge. To prove how effective my approach has been, I will demonstrate today how basic player movement, jumping, and camera tracking can be achieved without referring to any of the course material.

To begin making a 3D platformer in Unity, the first step is to setup the game environment or scene. In Unity, the default 3D game scene contains a basic camera and a simple light source. The first thing to include in the scene is… well, a platform! For this, a simple planar surface is added to the scene – and just so it resembles the ground a bit more, a green material is applied to it. Next, a player model is required. Here, a 3D model of a robot is used (this was an asset provided in the course):

BasicGameEnvironment

After the game scene is set up, basic (planar) player movement and jumping can be achieved by the following C# script (Note: the coding in the yellow text boxes allow the player to “jump” while the rest of the code is responsible for lateral movement using the “WASD” keys, arrow keys, and/or game controller):

2. BasicPlayerMovement (with jumping)

I won’t get into what each variable, function, and parameter does in each line of coding (which in my opinion is all very interesting), but I can assure you that I can explain all of it as a result of this course. You see, the course instructor, James Doyle, has done an amazing job in explaining all of the concepts clearly and concisely – even using examples to illustrate his point at times. Essentially, what I can show is that the following result is produced when the above script is attached to the player model:

basicplayermovementandjump

So far so good. However, we run into an issue where the player can walk off of the screen and/or disappear out of the camera’s view. How do we get around this? What is crucial in any 3D platformer? Camera tracking. For this, Unity has in its Package Manager toolkit an asset called “Cinemachine“. After installation, a “FreeLook” Camera object is conveniently added to the game scene. Once added, it replaces the default main camera and a plethora of camera settings are then available:

UnityCinemachine

First (see blue box in the picture above), the “Follow” parameter is set to reference the player mesh and the “Look At” parameter to reference the mesh of the character’s head. After, the following script (see coding in red boxes below) is necessary for the camera tracking to work whenever the player inputs commands to move the character around the environment (Note: The third red box down replaces an earlier line of coding which now allows the player to move in the appropriate direction regardless of where the camera is positioned around the player):

4. BasicPlayerMovement (camera tracking)

Again, I won’t go into how the coding works, but I can show that the script above produces the following result:

cameratrackingplayermovement

Notice how the camera is now following the player (the robot) around the environment and when the mouse is moved around, the camera is essentially looking at the robot’s head. Indeed, I have found that Cinemachine is a powerful tool in Unity.

To conclude today’s blog post, whether you are a game developer reading this or not, I hope that you can appreciate the work and process behind making a 3D platformer. And along the way, I hope this will inspire you to start or continue on a project of your own. I look forward to next week, where I will demonstrate here how to implement player rotation and animate our player robot to give him some form of (apparent) life! Stay tuned!

– Taklon

3D Platformer GameDev Series – Weekly Blog #1: Introduction

Welcome to the start of my new GameDev series for my blog! This series will focus exclusively on the genre of 3D platform games which are also referred to as ‘3D platformers’ and will be herein referred to as such. Unfortunately, games that contain ‘platforming’ mechanics but are not classified as 3D platformers will be excluded from this blog post. For example, these games primarily fall under the genres of action and/or adventure albeit contain secondary 3D platforming mechanics as well (sorry Zelda and Goemon fans!). Simply put, “3D platformer” is defined as a subgenre in such games where platforming is not the main focus or element of the game.

Further along in this opening blog post, we will deepen our understanding of what defines a 3D platformer technically. After, we will take a stroll down memory lane and name some of the best and most popular 3D platformers, which may arguably be the golden era when they were first being developed and released. And in subsequent weekly blog posts, I will share my journey of making my own simple 3D platformer beginning with my progress in another Udemy course I have recently enrolled in: “Learn to make a 3D Platformer Game with Unity“.

So technically-speaking, what makes a true 3D platformer? As a gamer, the answer may not be as clear as one would expect. As a game developer, the answer is simple. As the name suggests, in a 3D platformer, the player needs to be able to control the ability to jump and move while jumping in an exclusively 3D environment. This means that 3D games whereby jumping is automated (i.e. – the player cannot control the movement of the character whilst in the air) are not true 3D platformers. Rather, these games may contain ‘platforming’ mechanics but fall outside the genre of them being classified as 3D platformers. The same goes with ‘isometric’ games (2D graphics with 3D gameplay) and 2.5D (3D graphics viewed on a 2D plane); these are not true 3D platformers by definition.

AlphaWavesFirst3DPlatformer
Alpha Waves (1990) – First 3D Platformer developed by Infogrames. Primitive 3D graphics. Click here to check out its gameplay!

So what are some of the best and most popular 3D platformers? Personally, I think some of the best ones were released on the Playstation 1 and N64. Ah yes.. the mid 90s to late 90s. Super Mario 64, Crash Bandicoot, and Spyro the Dragon were no doubt many fan favourites. What are some of your favourites, personally?

SuperMario64
Super Mario 64 (1996)
CrashBandicoot
Crash Bandicoot (1996)
SpyroTheDragon
Spyro The Dragon (1998)

 

 

 

 

For a comprehensive list of what was claimed to contain every 3D platformer made from 1990 up to 2018, be sure to check out out Gameranx’s article on the subject matter! Below is also a graph from the article which seems to suggest there was nearly a decade (1998 to 2006) when 3D platformers were especially popular.

3Dplatformersgraph (1990 to 2018)_gameranx
A chart showing the number of 3D platformer titles released each year from 1990 to 2018. Source: Every 3D Platformer Ever Made, Gameranx (Filippidis, 2018).

Despite less mainstream 3D platformers being released nowadays, you may be wondering why I still want to learn how to make a 3D platformer. First and foremost, I just think they’re a lot of fun to play. Not to mention, they seem to be one of the only genres of games I can tolerate watching an entire speedrun of – and in absolute awe at that. But above all, I feel that 3D platformer as a subgenre is what defines and brings many action-adventure games to life that we have all come to love.

Be sure to drop a comment and let me know what some of your favourite (and least favourite) 3D platformers are. And stay tuned for the next blog post in this weekly GameDev series, every Sunday!

– Taklon

So Taklon, what’s in store ‘for 2020’?

On New Year’s Day, I revealed that I had been struggling with dedicating time and finding motivation to improve my skills involving graphics, animation, and game design – all of which speaks to the essence of my blog.

Needless to say, the first few months of 2020 leading up to today have been stressful, uncertain, and rather grim for everyone. As I am writing this blog post, the Covid-19 pandemic continues to weigh down on every single one of us and is expected to continue to do so for months ahead at the very least.

From early to mid-February (just before the Covid-19 outbreak had occurred here in Canada), I was fortunate to had the opportunity to travel to Japan for the first time – my first solo trip abroad. Memories of the time I spent there, are thus, still fresh in my mind. And if I had to choose, highlights of my trip involved visiting awe-inspiring places such as the Studio Ghibli Museum and Team Borderless Digital Art Museum. But above all, I am finding that it was moments of complete solitude in Japan that I enjoyed and appreciated the most as it really gave me a chance to look back and to look forward ahead on what I wanted and continue to want to do in life.

Looking back, last April, I began working with Blender 2.80. At that time, I also took a dive right into the Unity game engine along with some coding in C#. With the help of some YouTube tutorials, I worked on a game. Although I made some progress in the end, I regret to say that I will be putting this project aside for good. It was a valuable experience nonetheless:

taklongameabandon

Flash forward one whole year later and I am realizing that following tutorials on YouTube and essentially replicating more-or-less what is shown isn’t exactly how I want to approach the learning process moving forward, especially in an area such as game development. So, I figured since I had a successful experience with the previous Udemy course I had taken, I decided to enroll in another course on Udemy: Learn to Make a 3D Platformer Game with Unity:

udemy3Dplatformercourseimage

Unlike the previous Udemy course I had taken, the instructor in this new course I am taking does not provide tests or encourage his students to test themselves to see if they understood the material after they complete a course section. Thus, my approach for completing this course is very simple. That is, I will go through each section of the course as slowly and as many times as necessary. The process to my approach is twofold. First, I will move on to the next course section if and only if I can produce the material in the current section on my own. Secondly, I will re-visit older sections (not necessarily just the previous section) as I reach further into the course.

My endgoal objective is to be able to take everything that I learned in the entire course and make a 3D platformer game on my own using original game assets I have made myself in Blender (instead of using the ones provided in the course) – in other words, this means making a simple, original, and complete 3D platformer game without referring to any course notes or videos or tutorials online (i.e.- YouTube).

Last but not least, I will be committing to weekly blogs on my progress for this course! So do stay tuned for my first blog post on this ‘GameDev’ series, where I will begin by sharing my thoughts on 3D platformer games in general. 🙂

– Taklon

My First Game Jam Experience!

Hey everyone! In my previous blog post, I mentioned that I had joined my first ever game jam with an ol’ buddy of mine! I figured that instead of a written blog post about my first game jam experience, I’ll do a vlog instead! Here it is (I recommend watching in HD and fullscreen if possible):

After participating in this jam and using all the artistic knowledge and skills I have gained in the past year (since I started writing this blog), I now have a better understanding of where my strengths and weaknesses lie in 3D modelling and animation in Blender – and how that translates to other areas/fields such as game development. You see, this game jam had pressured me to churn out work rather quickly in order to meet a strict deadline and also forced me to come up with a compromise between quality and quantity of the game assets themselves. And while it was a bit stressful at times, it was also rather satisfying and a lot of fun!

No doubt, I may yet participate in another game jam before the end of this year! We shall see…

– Taklon

GameDev Blog #3: Basic Items, Equipment, and Inventory System

After implementing walk and run movement for our player, I started creating some basic interactable objects which would also show up as items in a player inventory system. In addition, I made a few simple pieces of equippable items such as clothes.

So far, I am trying my best to spend a minimal amount of time working on the aesthetics and UI for 2D/3D models and sprites since they can be re-designed and/or their level of detail can be raised later. Instead, the bulk of my time has been used towards primarily completing all the functional systems (e.g.- player movement, inventory, combat, etc..), and of course, a lot of time is spent constantly debugging and trying to get things to import and work properly in both Blender and Unity.

Interactable Environment Object

blueherbBlue herbs can be picked up in the game scene/environment. Once picked up, they appear in the player inventory. Later, they can be used as a consumable item to restore  some of the player’s health.

itempickupandinventorysystem

Equippable Items/Equipment

vagabondshirtA simple, default equippable shirt for the player.

vagabondpants
A simple, default equippable pair of pants for the player.

equippingclothesEquipment will appear on the left-side in the inventory once equipped (this will be implemented at a later point). For the next update, I will add a basic weapon and design an enemy to prepare for the combat system.