3D Platformer GameDev Series – Weekly Blog #11: Player Health UI

Hey everybody! How was everyone’s first week of summer? Any new or exciting plans out there for anyone? Myself…? Not much given that the pandemic is still very much present where I live – although places are starting to open up these past two weeks. Needless to say, I will continue each week towards my goal in completing the 3D Platformer course by this Fall. Without further ado, I will demonstrate how to update the UI to display the player’s health today.

Back at the start of Week #6, you may recall a UI object called a canvas being added to the game scene. The canvas is used to display UI elements such as the UI image for a fade in/fade out black screen added earlier. A new UI element introduced today is the UI text which is created and added to the canvas to display the player’s health points:

PlayerHealthUIText

In addition to displaying the player’s health as text, a UI image is created and added to display the player’s health bar. To keep the UI elements organized, an empty called ‘UI’ is created containing the text and image:

UI (HealthText+Image)

And as always, in the ‘UIManager’ script, variables are declared to be assigned by the UI HealthText and HealthImage:

UIManager Script (healthText+healthImage variables)

Next, similar to how an array was created in the ‘PlayerController’ script to store all the player pieces (or game objects found in the player armature), an array is created in the ‘HealthManager’ script to store all the images (or sprites) for the player health bar:

Healthmanager Script (healthBarImages sprite array)
AssignHealthBarImagesToArray

Finally, in order to update the player health points and health bar, a function called ‘UpdateUI()’ is added to the HealthManager script (see below). Appropriately, the ‘UpdateUI()’ is called in four functions within this script: “Hurt”, “ResetHealth”, “AddHealth”, “PlayerKilled” – essentially any function which would cause the player’s health to change.

HealthManagerScript (UpdateUI function)

As you can see in the script above, instead of using ‘for loops’ (as I have done all along), I learned to use “switch statements” this time –  another way to write conditional statements.

And alas, to see the player health UI (text and image) update in the game as the player takes damage, heals, is instantly killed, and respawns:

PlayerHealthUI (health display update)

And with that, that concludes this week’s blog post! I was hoping that I would have enough time this past week to move onto the next course lesson and add the next object to the scene, but work has been rather busy as usual. >< So, that will have to come about next week!

Have a good week everyone and stay safe!

– Taklon

3D Platformer GameDev Series – Weekly Blog #10: Health Pickup and Particle System Effects

Oh my… the weeks sure are rolling by. I am now about one third of my way through the 3D Platformer Udemy Course! Today, I will add another object to the game scene for player health pickup. Afterwards, I will revisit the particle system and use it to create some interesting effects when the player is killed.

If you have read my last few blog posts in previous weeks, you should know by now how game assets or objects are added into Unity and programmed to interact with the player. Just like the checkpoint or the spike trap added earlier, a game asset of a heart container for the health pickup is added into the game scene with an appropriate-sized collider for the player to potentially enter:

HeartPickup (add to game scene)

In the same way the checkpoint and spike trap were set up, the ‘Is Trigger’ on the ‘Health Pickup’ collider is enabled to allow the following ‘HealthPickup’ script attached on the object to work:

HealthPickupScript

And in the ‘HealthManager’ script, for the “AddHealth” function:

HealthManagerScript (addhealth function added)

As you can see above, the coding and logic for the health pickup is very straight-forward. The result when the game is run, is thus, rather simple (the heart disappears when the player walks over to it and the player is healed):

HealthPickup

Next, it is time to revisit Unity’s built-in particle system. This was used a few weeks back to generate lights to appear from an active checkpoint. Today, the particle system will be used again to create a death effect for the player when killed. In order to do this, the following code is first entered into the ‘GameManager’ script (see yellow and green boxes):

GameManagerScript (updated for player death effect)

Here, a new method called “Instantiate” is introduced above. Instantiate means to create a copy/clone of any object or any prefab (in or outside of the game scene), returns it, and allows the copy to appear at a newly specified location and rotation. Already, I can think of so many ways the instantiate method can be used in game development; from inventory systems to character customization to enemy transformations, I anticipate this will be a method I will utilize more and more in my game development endeavours.

Now, back to Unity. After setting up the script, the next step is to create a particle system effect (two systems grouped together make up the effect here):

PlayerDeathEffect object (particle system)

As you can see, there are a lot of different parameters to adjust and play around with in Unity’s particle system to achieve a desired or intended effect. For the player death effect, general parameters that are changed include the Duration, Looping, Start Lifetime, Start Speed, Start Size, 3D Start Rotation, and Gravity Modifier. Various parameters within the following are also added, taken away, changed, and/or adjusted: Emission (burst time, number of particles, etc..), Shape (the shape of the volume in which particles are emitted; i.e.- spherical), Size over Lifetime (particle size from beginning to end; i.e.- linearly big to small), Collision (physics can affect particles), Renderer (how the particles are rendered; i.e.- particles are cubes).

After creating the ‘Player Death Effect’ prefab, it is assigned to the ‘deathEffect’ variable in the ‘GameManager’ script that was set up earlier:

PlayerDeathEffect (assign in game scene)

Alas, to see how the effect looks in the game:

PlayerDeathEffect (in-game)

I must admit, lately I have been coming up with some ideas for a 3D platformer now that I have a little bit of development knowledge for the genre. This may be premature of me to say, but I really hope that I can finish this course by September or October. In effect, that will leave me with a bit of time until the end of the year to come up with a simple and fun design for a game to develop next year. My goal is to create an original 3D platformer in 2021 while continuing the weekly blogs to share my development process  for it (which would include any and all struggles along the way… *nervous chuckle*).

Anyway, I hope you enjoyed the (longer) read this week! Stay tuned for next week when I learn how to update the UI to display the player’s health and add another new object to the scene! Can you guess what that object would be? 🙂

– Taklon

3D Platformer GameDev Series – Weekly Blog #9: Player Invincibility

Howdy all! I hope everyone’s been doing well and perhaps finding their own ways to navigate through these times. For me, working on the 3D Platformer course and writing these weekly blogs have helped me relieve some of my recent stresses at work. I highly recommend others to do the same and perhaps even start their own blogs. If anyone does happen to blog, do let me know in the comments as I would love to see what you have to share with the world!

Alrighty, let’s get right into this week’s update on the 3D Platformer Course, shall we? After learning how to implement player knockback last week, the next thing to do today is to grant the player invincibility after getting hurt or taking damage.

We begin with the HealthManager script that we started last week:

HealthManagerScript (implement invincibility)

And to see it in action against the spike trap we added to the scene last week:

PlayerInvincibility

Looks good! However, there are many ways to show or represent invincibility in games. One of the simplest tricks is to make the player flash for the duration of the invincibility. This is simply done by programming the player to hide and unhide repeatedly. Still, the approach in Unity is a bit tricky. The first step is to create an array in the ‘PlayerController’ script to store all the “pieces” (or objects) found in the player armature:

PlayerPieces array (PlayerControllerScript)PlayerPieces (for invincibility flashing)

You may recall a few weeks ago when we created an array to find all the checkpoints in the scene – well now, we will use the array and update the ‘HealthManager’ script:

HealthManagerScript (showing invincibility by player flashing)

What’s noteworthy perhaps in the script above is the use of a math function called “Floor” (rounds the result down to the nearest whole number) and a computing operation called “modulo” (divides a number by a specified number – 2 in this case – and gives a remainder); these are used to perform a check on whether a number is an even or odd number. Little did I realize I have come to understand the following: Yes, understanding math may not be essential to game development – however, it sure makes a lot of cool and powerful things happen more easily!

And so, here is the end result of player invincibility and flashing:

PlayerFlashingWhenInvincible

That’s it for this week’s blog post! Thank you for reading, as always. Stay tuned for next week when I learn to complete the rest of the health system!

– Taklon

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 #3: Player Rotation, Idling, and Running

Hello everyone! I’m almost a month into the 3D Platformer Udemy course now! This week, I will be covering Player Rotation, Idling, and Running. Let’s dive into Unity right away!

We’ll first start off with the relevant C# script (this is the same “PlayerController” script attached on our player object that we started working on last week):

BasicPlayerMove (rotating the player smoothly)

Now, I mentioned last week that I would not go into dissecting C# scripts. However, there is one class of functions in Unity of relevance to 3D game development that I feel would be remiss if I didn’t highlight here. This key class of functions is called the ‘Quaternion‘. The Qua-what now?! To simply put, a quaternion is used to represent rotations. It forms methods such as Quaternion.Euler, Quaternion.LookRotation, and Quaternion.Slerp. These methods (all used in the script above) allow us to do the following three things, respectively: to move our player in the appropriate direction according to the rotation of the camera, to rotate our player, and to do so in a smooth manner. With the use of quaternions in our script, the following result is produced:

playersmoothrotation

Next, let’s breathe some life into our robot! We’ll implement some animations to make our robot appear to look around (while standing still) and run as well. First, we create an Animator Controller and attach that to our player object. In the animator window (see below), we create two different states for the robot: ‘Idle’ and ‘Run’. We also create two transitions between the two states (as represented by the white arrows) as well as a parameter called ‘Speed’ to manage the conditions for these transitions to trigger later on:

PlayerAnimator (idle+run)

By clicking a state, an animation can be assigned to that state. The player robot model has built-in animations that can be used. For example, the “Robot_Idle” animation is assigned to the ‘Idle’ state as shown below:

AssignAnimation

It is important to note that for the transition from the ‘Idle’ to the ‘Run’ state, it should not have an exit time (meaning the transition can occur before the animation of the idle state is complete). Also, the transition should have a fixed duration (meaning it takes a specified amount of time to go from the ‘Idle’ to the ‘Run’ state):

StateTransition (idle to run)

The opposite also holds true (exit time should be disabled and there should be a fixed duration) for our player to go from its ‘Run’ state to its ‘Idle’ state:

StateTransition (run to idle)

In the last two screenshots above (on the bottom right), you may notice that we’ve assigned the “Speed” parameter we created earlier to the transitions. This allows us to set conditions that would trigger those transitions. If the speed for the ‘Idle’ state is 0 (zero), then for the ‘Idle’ to ‘Run’ transition, we want to set a condition that this transition would occur only if the ‘Speed’ parameter is – say – greater than 0.1. And for the ‘Run’ to ‘Idle’ transition, the condition for ‘Speed’ should then be less than 0.1.

Finally, in our player controller script, we create an Animator class to allow us to assign the animator controller we created to our player object. In our script, we also determine the value of the ‘Speed’ of the player based on whether the player is pressing/holding down any of the movement directional keys:

Script (idle or running animation)

Essentially, if the movement keys are being pressed, then the ‘Speed’ would be greater than 0.1 causing the ‘Run’ state/animation to trigger. If the movement keys are not or no longer being pressed, then the ‘Speed’ would approach zero and the ‘Idle’ state/animation will trigger. Our robot player looks a lot more lively now, don’t you think?

player_idling+running anim

I hope this week’s blog was a good read for everyone! I look forward to next week where I will finish setting up the player robot by giving it a jumping animation, fixing some ‘game logic’ issues with the robot’s speed and jumping ability, and start managing some of the game controls and general aesthetics. 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