Let’s create a simple melee combo system!

The first game that comes into my mind when it comes to combos is Devil May Cry franchise. You can destroy a swarm of enemies with a single combo. The game is all about combat combos, you unlock skills that adds more moves to your combos, you breath combos, the game even rates your combos. So I thought to myself, why don’t I create one in Unity.

So, lets break down the problem, as usual, to smaller problems and tackle them one by one:

  1. Animations… We have to have animations that will make our combo.
  2. We need to create a state machine in Unity Animator so that the animations transition from one to another based on the player’s input.
  3. Speaking of input, we need to capture the player’s input (Mouse clicks) and as long as the player clicks the button within a certain time during the animation play, the next animation plays. If the player does not click the mouse with certain time, the character resets back to the idle state.

Sounds simple right? It is actually a pretty simple problem. Lets explore the solution step by step.

1. Getting the Animations:

I am not an animator. I know the basics on how to animate characters, but I don’t have that artistic sense on making super cool animations, especially for fighting games. The best tool you can use to get free animations is mixamo.com. You can visit that site, create an account for free and download as many animations as you like. The key thing here, is to make sure that the animations you are selecting for your combo match; which means, if the player character starts the combo by swinging a sword, then delivers a kick; you need to make sure that sword swing animation leads to the kick. Otherwise, the combo will look bad. This is very important, it is not purely technical, but a bit more of an artistic sense. The animations I picked are as follows:

Figure 1: The animations of the combo

You can also download the character models from mixamo.com as well and they are all rigged animations with Humanoid rigs. which is pretty cool.

I have also downloaded a Katana sword from GameDevHQ’s legendary filebase. After putting the Katana at the right place of the rig, we are ready to jump into the animations.

2. Creating the animation state machine

Unity’s animation system offers a very powerful tool to plot the way animations will work. Using Unity’s Animator you can create a state machine to link different animations together based on certain conditions. Now, lets think about how the combo will work. As you can see in figure 1, we have 5 attack animations and an idle animation. The player will always start at the idle animation which means that we will make the idle animation our default state. Then the combo, in its perfect state, will flow like this:

Idle > Attack1 >Attack2 > Attack3 > Attack4 >Attack5 >Idle

If the player keeps pressing the input buttons at the right time, the animations will play as per the diagram above, but if the player misses an input, at any attack state, the animation should then move to the idle state. This means that with every Attack state, we want to link that state with a transition to the idle state that gets played if the player does not press on the mouse button within the designated time frame. The state machine will look like this:

Figure 2: The combo state machine

As you can see, each animation has a two transitions, one to the next animation and another to the idle state. But, how do we do the transition. We need some kind of a trigger that we can set to trigger the transition to any animation. Luckily, Unity allows us to create parameters that we can call from the code and create conditions based on those parameters to transition from one animation to another. The best parameter I could think of to make this work is to use trigger parameters and set them when needed. If the parameter is set, the transition to the corresponding animation will play, if not, then the animation will transition to the idle state.

Figure 3: The trigger parameters for the animation transitions

Since we have five attack animations, I created five trigger parameters, each correspond to each animation; and within each transition I set the transition going to an attack animation to run if its corresponding attack trigger is set, all the transitions that are going from the attack animations to the idle animation are player on Exit Time. Here is an example of both.

Figure 4: The transition from the idle animation to the first attack animation
Figure 5: The transition from the first attack animation to the idle animation

As you can see in figures 4 and 5, when moving towards an attack animation the trigger parameter has to be set. If the animation finishes playing, then the animation state goes to idle.

With the animation state machine set, lets control the flow of animations through code.

3. Controlling the combo animation through code

On the player character, I created a script called ComboManager; this script handles the combo transitions and the user input. I started by creating the following variables:

Figure 6: The variables of the ComboManager

The first variable is an instance of the animator so we can call in the triggers and set them to do the animation transitions. The Combo Delay variable is the maximum amount of time the player can press the input key before the combo resets to the idle state. The numClicks variable counts the number of clicks the player has pressed to determine the animation state the character should move to. The lastClickTime captures the last time the player has pressed the input key.

In the Update() function then looks like this:

Figure 7: The ComboManager’s Update() function

I start by checking whether the time of the last input press has exceeded the threshold or not, if it did, I reset the number of clicks to zero that none of the animation events gets triggers (this will be shown later in the article)

Then I check for user input. For this demo, I use the mouse left click. If the left click is pressed we do multiple things:

  1. We capture the time in which that click was pressed, so we can compare it to the time threshold.
  2. increment the number of clicks to 1.
  3. Play the first attack animation but setting the trigger parameter “Attack1”. now the first attack animation is playing (Use a bit of your imagination to follow with the next part)

Finally I am just clamping the value of numClicks to be between 0 and 5 since I only have 5 animations for now.

We need then to set certain conditions to tell the animation controller to either transition to the next attack animation, or to the idle animation. Here is the problem. I want the player to press the mouse button before certain frames in the animation so they can land the next attack successfully. This means that within the animation we want to track the user input within certain key frames. How can we trigger some code when we reach to a certain key frame in Unity? The answer is, Animation Events.

Animation events allow you to enter an event in the animation dopesheet in which if the Unity at that key frame will execute a function of your choosing. Selecting where to put that animation event depends on your animations and where you want to transition to your combo attack. Simply move the animation cursor to the key frame you want and click on the Add Event button in the Animation tab. This is demonstrated in the figure below:

Figure 8: Adding an animation event in the dopesheet

As you can see, I am creating an event in the first attack animation so I can check for input to move to the second attack animation. What I did I figure 8 is that I picked the right key frame where I think will blend well with the next animation and created an animation event. Then in the top right corner, I selected a function called ComboAttack1Transition(). What is that function and what does it do?

In the ComboManager() script I created the following function:

Figure 9: The ComboAttack1Transition() function

This function does only one thing, to check whether the player at that point has clicked the left click two times or greater. If the condition is true, the “Attack2” trigger is set and the animation controller will transition to the second animation If not, then the first attack animation will continue playing until it finishes and then it will move back to the idle animation automatically. This same thing is done for all the other animations. In the second attack animation I picked the right key frame that blends well with the third attack animation, set an event and call the function ComboAttack2Transition() to check for the user input. The transition functions in the ComboManager script look like this:

Figure 10: The transition functions that are called from the animation events

The reason why we do not have a fifth transition function is because when the fifth attack animation is playing, we want it to transition to the idle animation when it finishes. That’s why on the transition from the fifth attack to the idle animation, the condition is set to run on Exit Time.

With that we have a working melee combo system.

Figure 11: The Combo System in Action

Lets make a 2D Archery game

Yesterday, I had an idea of making a simple 2D game in 1 hours, and I wanted to challenge myself to see whether I can actually do such thing or not. It turns about, I could! Yesterday, I made a very simple 2D Archery game. But I wanted the game to be interesting as well, so I decided that I would implement something like Angry Birds. You see, when you pull the bird on the slingshot the game kind of display to you a predicted trajectory of the bird when released and the further you pull the bird, the further it goes. So, lets break down the game into smaller problems and tackle them one by one:

  1. I want the bow to rotate with the mouse position so we can aim.

2. To make things easy, regardless of whether the player is holder the right click button or not, I want the game to always display a minimum trajectory prediction from the bow. The trajectory should be simulated.

3. If the player holds down the left click, the bow should charge power to shoot the arrow.

4. When the player releases the mouse left button, the arrow should shoot and follow the predicted trajectory.

5. The arrow should trigger an event if it hits a target.

6. A target that is moving up and down as a challenge to the player

7. If the arrow hits the target the following should happen: A) Increase the speed of target movement for added challenge. B) Play a particle effect at target position.

Now, lets start tackling one problem at a time.

  1. Rotate the bow with the mouse position.

I started by creating a 2D sprite and I did some search online for a cool bow and arrows to use in the game. I then assigned the bow image to the sprite renderer component in the game object and was ready to start coding.

I created a script called Bow, this script will be the main driver for all the bow functions. In the Update() function I started by calling a function CalculateBowRotation(). This function will calculate the rotation of the bow so that it is always pointing towards the mouse position. Here is the function code:

Figure 1: The CalculateBowRotation() function

The first need I needed to do is to calculate the mouse position with respect to the world space. As you Input.MousePosition give the position of the mouse in screen space. That will not give an accurate rotation of the bow because its coordinate system is in world space. Once this is done, I calculated the direction of the aim by subtracting the position of the mouse from the position of the bow and then normalize it. When this is done, I can now use the Atan2 function to calculate the new angle of the bow based on the position change of the mouse. When calculating the angle, don’t forget to convert the angle from radiant to degrees as the Atan2 function gives the result in radiant. Finally, just multiply the forward of the bow, because I want to rotate around the Z axis with the newly calculated angle and you got a rotating bow.

2. Calculate and display the trajectory prediction points

This is the hardest part in the entire game; but really, it is not that hard. First of all, we need to have an equation that calculates the position of each point across the trajectory. You can refer to this YouTube video to learn more about the equation that I am about to use.

The first thing I did is that I created a 2D circle with RigidBody2D component in it. Then I created a prefab out of that object. Then what you need to do is to instantiate the points into the game and then position them accordingly. Since we will be placing multiple points, then we need a list or an array to hold the generated points and then we need to instantiate those points at the same position. This should be done in the start function of the Bow script as you want those points to be added to the game once the Bow object starts. The code will look like this:

Figure 2: The Start() function of the Bow object

You can see in figure 2 that we have initialized an array of the prediction ball count and then just looped through it and instantiated prediction balls at the bow position. Now, we need to calculate each point’s position in the predicted trajectory.

In the Update function of the bow script, I created a function called CalculateArrowPrediction(). This function will calculate and place each point in on the predicted trajectory. The function looks like this:

Figure 3: The CalculateArrowPrediction() function

The only trick in this function is just to code the equation; and as you can see all I did is just to calculate each parameter and then plug them all into the equation and update the position of each point in the array. Let me, however, explain the rationale behind the calculation of t. t represents the correlation of the position of the point with respect to time. So basically, I want to say at time T, the point should be at that position. That’s why I am dividing the index of each point with the total length of the array so I can distribute them evenly across the path. Another thing to note in the function is V0 which is the initial velocity. It is calculated with respect to the aim direction. Keep the initial velocity in mind as we will refer later to it in this article. With that, we have plotted the prediction points correctly on the trajectory path.

3. Charge the Bow power when the player holds down the left click

The power of the bow is the initial velocity of the arrow. So basically, we want to increase the initial velocity with time to some maximum velocity if the player holds down the left click. This is done in the Update() function of the Bow script. The code looks like this:

Figure 4: The updates to the Start() and Update functions to reflect power charge of the bow

As you can see in figure 4, the Start() function has been updated with a line to initialize the initial velocity with the minimum velocity. In the update function when the left click is held down, the initial velocity in incremented with time and according to a charge speed. Pretty straight forward, right?

This takes us to the next step…

4. Shoot the arrow when the player releases the left click

I created a function called ShootArrow() that instantiates the arrow prefab and just shoots it. This function is called in the Update() function. The code looks like this:

Figure 5: The ShootArrow() function and updates to the Update() function

You can see in figure 5 that the implementation is straight forward. In the update function, I check for left button release, if that’s the case, the ShootArrow() function is called and the initial velocity of the arrow in reset to the minimum position. Then, in the ShootArrow() function, the arrow prefab is instantiated and then its velocity is set to the calculated initial velocity so it can move forward. You can also notice that I have implemented a fire rate functionality in order to limit the spamming of arrows in the game.

With that we have a functioning Bow. Let’s move on to the next step!

5. The arrow should trigger an event if it hits a target.

First of all, I created two additional sprites. One for the arrow and another for the target. Both have colliders set as triggers and both have RigidBody2D components. The arrow script should have an OnTriggerEnter2D function that gets called when the arrow hits the target and raise an event so other objects can act accordingly. The code for the arrow script looks like this:

Figure 6: The Arrow script

As you can see, I have defined an event called onTargetHit. this event is trigged in the OnTriggerEnter2D function if the arrow hits an object with a tag “Target”. Other objects can subscribe to that event to execute logic based on that event (We will see that later). Once the arrow hits the target, I disable the collider and change the velocity and gravity scale to zero because I want the arrow to stay stationary. Then I destroy the object. If the arrow did not hit anything, then it gets destroyed after 5 seconds from the call in the Start() function. That way, the hierarchy of the game is clean.

One other thing that I did the arrow to make it look better is that I created an additional script called RotateOnDirection. That script will rotate the arrow to align it to the direction it is moving towards. The script looks like this:

Figure 7: The RotateOnDirection Script

As you can see in figure 7, in the Start() function the initial position of the arrow is assigned to the position on instantiation. Then in the update function the direction of movement is calculated. Finally the angle is calculating by the Atan2 function, just like the bow’s rotation.

6. A target moves up and down to challenge the player

For this one to work, I created two empty game objects and made them children to the target. I also made the target sprite object a child of an empty game object that holds the sprite and the two points.

Figure 8: The setup of the target in the scene

Them I created a script called Target and assigned it to the Target_sprite object to control the movement of the target. In the Update() function of that script a Movement() function is called every frame to move the target between both points. Here is the function code

Figure 9: The Movement() function for the target

As you can see in figure 9, we reference both points and have a movement speed. Then I initialized a variable to hold the position in which the target should move towards as point A. In the Update() function then called the movement function which in turn moves the target between point A and point B.

7. Execute actions when the arrow hits the target.

Remember the onTargetHit event that I created in the Arrow script? This is where it comes in handy. What I need to do is to make the Target script subscribe to that event so that if raise, the Target script executes a function that then do some logic based on that. The updated code of the Target script looks like this:

Figure 10: The updated Target script

As you can see, I have created a function called TargetHit. This is the function that will be called when the event onTargetHit is raised. You can see that in the Start() function the Target script is subscribing to the event and in the OnDisabled() it is unsubscribing. All what TargetHit() does, is that it plays a particle effect that is a child of the Target_sprite object and increases the movement speed by 1. Now, of course there has to be a maximum speed at the end, otherwise things will get crazy later on.

With that we have a functioning 2D Archery game that can be done in 2 hours.

You can try the game I created by clicking here.

Figure 11: The game in action

Lasers and Mirrors: Let’s make it a multiplayer game.

Ok, the game has matured a lot now. But playing alone a puzzle game can be a bit boring. Why don’t we make it an online game where friends can play together? Sounds great right?

When we are creating a multiplayer game we need understand one simple concept. That is each game works as a client and it needs to communicate with a server. That server can hold the logic of the game, tracks the game’s progress and sends information to other clients such as health of other players, bullets shot and other things. You can also make a certain player host a game like Among Us where players create rooms and other players join the room and play together. You can either create this whole server/client logic on your own or you can just use one of the tools available to make things easy.

This is where Photon comes in handy. Photon is a plugin for unity that you can use for free to create multiplayer games. In this article I will explain how I turned this game, from a single player game to a multiplayer game.

First you need to go to Photon’s Website and create an account. Once you do that you will be taken to your Dashboard. In the mean time, head to PUN 2 — Free page in Unity’s Asset Store. Purchase it, and then import it into your project. When the import is done it will ask you to enter the app ID of your game. This is where you need to head to the dashboard of your photon account.

Figure 1: Photon Dashboard

Click on the Create A New App button. This will take you a another page where you can create your app.

Figure 2: The Create a New Application form

All you need to do in that form is to make sure that Photon PUN is selected for Photon Type and enter the name of your game. When you are done, click on Create. This will create an App ID for your game and you can see it in your dashboard.

Figure 3: The App ID of the created game

Now, copy that app ID from the dashboard and paste it into PUN’s welcome window and click on Link App and now your game is linked to Photon. 

With all the logistics out of our way, lets start coding.

Before we do that, lets see what we need to do:

  1. First we need to connect to the server.
  2. When the game is connected to a server, we need to move the player into a lobby so they can create of join games.
  3. Whether the player creates of joins a game, the player needs them to be directed towards a newly created room or an existing room.

I started by creating a loading scene that starts with the game. This scene has a GameObject that is responsible for connecting to the Photon server.

Figure 4: The Loading scene

The Connect To Server GameObject contains a script that connects to the Photon server:

Figure 5: The ConnectToServer Class

As you can see we are using a new namespace for PUN so we can use its functionalities. The beauty of this library is that it has a class called MonoBehaviorPunCallbacks; this class inherets from MonoBehavior so you can use it with GameObjects and at the same time leverage the callbacks of PUN. When the object starts we connect to the PUN server using the default settings. Then we have two call backs:

  1. OnConnectedToMaster: this is called when the game connects to the server and as you can see, when the connection is successful we then join a lobby.
  2. OnJoinedLobby: this is called when the game successfully joins a lobby. At this point we want the game to transition to the lobby scene so the player can create or join rooms.

The Lobby is another scene that contains more UI. In the lobby the player can create a nickname for themselves, create a new room or join an existing room.

Figure 6: The game’s lobby

In that scene we have a GameObject that manages the creation or joining of rooms. The script of that class looks like this:

Figure 7: The CreateAndJoinRooms Class

As you can see in figure 7, I am referencing the input fields where the player input resides. Then I have two public functions: CreateRoom() and JoinRoom() these two functions are linked to the Create Room button and Join Room button’s OnClickEvent. These two functions simply make sure that the player has a nickname added and then The CreateRoom() function create a new room with the room name given; and JoinRoom() function joins a room by its name. Finally there is a PUN callback called OnJoinedRoom() that gets called when the game joins the room and at this point you want the game to move to the game scene. If you notice, we are not using the SceneManager to transition to the game scene instead we are using PhotonNetwork to do the transition. The reason behind that is that we want to move to the scene with the room’s session. If we use SceneManager we will only transition to a local version of the scene and not the scene corresponding to the room created.

The way I designed the game is that when a player joins the room, the game assigns either a Mirror or a Lens to the player. Only the assigned player should be able to control their own object and no other object. Doing this is pretty straight forward. First, you need to move you player prefabs from their existing folders to a folder called Resources. If the folder does not exist, you have to create it yourself and add the spawnable prefabs in it. Otherwise PUN will not be able to identify which prefabs to respawn.

Figure 8: The Resources folder with the player objects

Then I created a GameObject to manage the spawning of the player prefabs into the level. This script should have a reference to the player prefabs and I have created bounds so I spawn the prefabs in random locations.

Figure 9: The SpawnPlayers references

The script of SpawnPlayers is this:

Figure 10: SpawnPlayers Script

As you can see in figure 10, in the start function, we pick a random position to insatiate the player, then I pick a random player prefab (Mirror or Lens) and insatiate the player prefab in the level.

One important step is that you need to update the player prefabs and add the following components to it: Photon View and Photon Transform View Classis. Photon View basically tells the system that that certain prefab belongs to which user. Photon Transform View Classic simply syncs any change in position or rotation to the prefab with the other players. If you do not add that component, you will be moving and rotating the prefab in your screen but it will remain stationary in all the other screens. I did the same with both the Mirror Prefab and the Lens Prefab

Figure 11: The Photon components added to the player prefab

To make sure that the player is only able to move their prefab I modified the MoveObject script a bit. Now, it looks like this:

Figure 12: The updated MoveObject functions

All I did is that in the OnMouseDown and OnMouseDrag I added a condition so that the drag logic executes if and only if the view is the player’s.

I also wanted to do is to display the player’s nickname on top of the player’s prefab, just like other Multiplayer games. All I did is that I added a child canvas and marked its Render Mode to be World Space so it displays on the player and not as a static interface item. In that canvas, I added a Text object to hold the player’s nickname.

Figure 13: The added Canvas for player nickname

Then I created a script on the player prefab to handle the assignation of the nickname to the Text object. The script looks like this:

Figure 14: The PlayerNameTag Script

As you can see the script has a reference to the Text object so it can update it. In the start function we check whether the photon view is the player’s or not. If it is, we don’t want to display the nickname of the player on their own object. Otherwise, we simple grab the nickname from Photon View and assign it to the Text Object.

When the game is won, the GameManager then calls a function from the NetworkManager Object to disconnect from the current room and return to the lobby. The NetworkManager Script looks like this:

Figure 15: The NetworkManager Script

The DisconnectPlayer() function is called from the Game Manager. That function starts a coroutine that leaves the room and once the game leaves the room it loads the lobby scene so the player can join or create another room.

One of the things that I noticed when testing is that every player gets a different level than the other. If you remember from my previous post, the game automatically places the laser and the target at random positions. The problem now is that, each game manager in every client creates its own level by placing the laser and target in different positions at each client. What needs to happen is that I want the host to somehow communicate with the clients and tell them that this is where they should put the laser, and this is where they should put the target; so we need to sync the levels in the clients to match the one at the host. After a lot of research, I found that this is very wasy to implement.

First, Since we need to check who’s game manager is this (A host or a client) we have to add a Photon View component to the Game Manager Object.

Figure 16: The Photon View Component added to the Game Manager

I also did slight modifications to the GameManager script where I declared global variables to define the selected indices of both the laser and target positions. I have also modified the start function of the script to look like this:

Figure 17: The updated Start function in the GameManager script

As you can see in figure 17, I encapsulated the script to select a random position to be only done by the master client which is the host. The question now is, how to we send the selected indices to the clients so they position the laser and target at the exact same place? There is a function called OnPhotonSerializeView() which can be implemented by implementing an interface called IPunObservable. This function is called by PUN several times per second so that the script can write and read synchronization data for the photon view. The function looks like this:

Figure 18: The OnPhotonSerializeView() function

What happens here is that the function checks whether the current view is writing or not and since this is the host (for the purpose of this game), the function will be sending data and not reading. Basically, I put both indices as a Vector2 and serialize it for the stream to write it. If the client is not writing, then, I read the data from the steam as Vector2 and grab the correct transforms from the array and place both the laser and target at the correct positions as the host. With that done, I created a system where the client level are in sync with the host’s level.

This is how you create a very simple multiplayer game!

Figure 19: The Multiplayer system in action

Lasers and Mirrors: Let’s make it a game!

If you have been following my previous two posts about reflecting and refracting a laser beam in unity. You must have been wondering, how will the player win the game. What is the challenge. Well, this game is supposed to be a dynamic puzzle game, where the player(s) should use all available resources in the level (Mirrors and Lenses) to make the laser hit a target object. The condition here is that ALL objects in the scene must be used. In this article as well I will talk about randomizing the position of the laser and target every time the level starts

Lets break down the first problem:

  1. We need to have a game object in the scene that is marked as a target with a box collider.
  2. When the laser beam collides with either a mirror or a lens, we need to add the game object’s instance ID into a dictionary. The reason I am using a dictionary is because I want to make sure that every object is added only once (laser may hit the same object twice).
  3. If the laser beam collides with an object marked as “Target” then we need to start checking whether the player won or not.
  4. To check whether the player has won or not, a Game Manager object needs to know how many usable objects are in the scene (Mirrors and Lenses) and compare it with the count of objects added to the dictionary. If they are equal, then the player wins. If not, the game continues!

Coding the solution is also straight forward. First I declared the dictionary as follows:

Figure 1: The dictionary that will hold the collided objects

In the CheckHit() function, I did two things:

  1. Added the Mirror of laser to the dictionary when the laser collides with it
  2. Added a condition to check for a win when the laser hits an object tagged as Target
Figure 2: The updated CheckHit() Function

As you can see in figure 2, the CheckWin() function is called from the GameManager Object and passed the number of objects added to the dictionary. The game manager then will compare that number with the total number of objects in the scene and declare a win if the number of objects is equal to the number of used objects in the scene.

Figure 3: The CheckWin function in the GameManager Object

With that done, the player will be able to have a challenge to win the level. However, so far the game is pretty static, the laser is always located at the same place, so does the target. How about randomizing the position in which the laser and the target are spawned so we can make the game a bit more dynamic and interesting?

This problem is easy to solve. What I did is that I created multiple empty GameObjects in the level:

Figure 4: The spawn locations of the laser and target

Then I assign all those locations into an array of Transforms in the GameManager Object:

Figure 5: The referenced locations in the GameManager Object

When the GameManager object starts, I randomly pick two different positions from the array and insatiate both the laser and target prefab into those positions. 

Figure 6: The Start function of the GameManager

As you can see from figure 6, I am getting two random positions from the array for the laser and the target. The reason why I have a while loop in the functions is to make sure that both location are not the same. When this is done, I insatiate both objects to the transforms and child them to the transforms in order to align them to their rotation as well.

With that, we have a functioning game that changes every time the level starts.

Figure 7: The game in action

Reflecting laser light in Unity

I am working these days in prototyping a simple puzzle game where the player needs to direct a laser beam towards a target using mirrors. The map should contain some obstacles that stops the light from moving forward.

To break down that problem we need first to write it in simple words. How do we reflect shoot the laser from a point and make it move and react to certain objects and reflect?

Lets break down the problem:

  1. We need to have a start point of the laser. That point can be the object where the laser will be shot from.
  2. We need to track the laser in the direction it is moving towards and see whether it will collide with an object or not.
  3. If the laser hits an object tagged as a mirror, we need to do two things; we need to calculate the direction of the reflected beam, and we need to store the point of impact in the mirror as a point within the laser beam.
  4. Repeat point 2, 3 and 4 until we either hit an object that is not a mirror, or not hit anything at all. If the laser does not collide with any thing, we will set its end point to be a point that is out of the screen bounds to give the illusion that the laser is shooting to infinity.

With that out of the way, lets examine the code. First, we will render the laser using the LineRenderer component, this will give us big fixability into drawing the line with multiple points. To make this super easy, I created a script and called it LaserBeam. This class does not inherit from MonoBehavior and its sole job is to calculate the points of the laser and draw it on the screen. I also decided to create the component using the code. Here are the variables of the class:

Figure 1: The variables used in the LaserBeam class

As you can see in figure 1, the most important variable is the List of laser indices this is where all the points of the line renderer will be store to draw the line on the screen.

Then, I created the class constructor that initializes the object and starts calculating the path of the laser.

Figure 2: The class constructor

The constructor initializes and adds the LineRenderer component into the game object and then calls the function CastLaser() that shoots the laser and calculates it path.

Figure 3: The CastLaser() function

As demonstrated in figure 3, the first thing we need to do is to store the current point we are at in the list of indices of the laser. At the very beginning that point will be the transform.position of the game object shooting the laser. They we need to create a ray starting from that position and shooting upward for the prototype the initial direction is transform.up because I want the laser to be shot upward. Then in the if statement, we do basic ray casting and we check what we hit. If we hit anything, we get into the CheckHit() function, if not, we add an index to a very far point and then draw the ray to give the illusion of shooter the laser to infinity.

The actual magic happens in the CheckHit() function; here is the code of the function:

Figure 4: CheckHit Function

The first thing we need to do is to know where we collided with. Did the laser collide with a mirror object or a wall. If the laser collided with a wall, we add the collision point as an index in the list and draw the laser and that’s it.

If the laser hits an object that is tagged as a mirror, then we need to calculate the new direction of the laser. Thankfully, and without getting into complex math, Unity provides a great function that reflects a vector off a plane defined by a normal. We already know the direction that we came from, and RaycastHit can provide the normal of the point where the laser collided. Using those two pieces of information we can calculate the new reflected direction using Vector3.Reflect(). So, we store the point of collision in the list of indices and then calculate the new direction using the Vector3.Reflect() function. Then we input the new point and the new direction and call CastLaser() again; and thus, we are recursively drawing the line. If you examine CastLaser() and CheckHit() functions you can see that the exit criteria from the recursion is either we hit a wall, or hit nothing at all.

The UpdateLaser() function is straight forward as we need to iterate through the entire list of indices and just add them all into the LineRenderer component. Unity will automatically draw the line for you once you add the indices.

Figure 5: The UpdateLaser Function

The laser game object it self contains a different script that inherits from MonoBehavior, that scripts destroys and creates the laser beam in every frame. With that, I have a functional reflection system that I can use in my game!

Figure 6: The reflection system in action

Project Osiris – Devlog #1: Character Movement

One of the things that fascinate me about video games is the ability to tell stories and allow the player to be part of it. These immersive experiences are what make video games epic. I remember the tears I shed when General Shepard killed Ghost and Roach in cold blood after having a very tough time in the mission titled “Loose Ends” in Call of Duty: Modern Warfare 2. I was too mad at Shepard and I remember that I cried a lot when that cutscene was playing. Since that moment, my dream of creating a video game that tells an epic story has started. Today, that dream is in progress and I am finally ready to tell a story of mine

This is where Project Osiris comes in!

Yes, Project Osiris is a code name of a video game that I started developing on April 2nd, 2021 that tells an epic story about the ancient Egyptian civilization. I don’t want to get into details about the game in order not to spoil the idea but through the game the player will take a role of an Egyptian god who tries to restore balance in Egypt. The player will engage in epic battles, fight big monsters from the Egyptian Mythology and spar 1:1 with Egypt’s greatest gods.

I started with working on a high concept document that lays out the game in terms of functionality, enemy types and powers that each will poses. I have to say designing a game from scratch is challenging but fun. At the moment, I am working on the Game Design Document (GDD). I should be able to complete the full design of the game by the end of April 2021.

However, being a geek and someone who cant stop writing code, I jumped into unity and I started prototyping a basic third person controller. Yes, the game will provide the player with a third person view of the player. To make the game easy to port into other platforms, I used Unity’s new Input System in order to layout the controls for the keyboard. This is how the basic layout that I started with looks like:

Figure 1: The player input layout

The use of Unity’s new input system will allow me in the future to enable control use with ease and without doing any changes to the code. I have future plans into building the game for consoles, but it is too early to decide now on this. As you can see in figure 1, the player can move using the WASD buttons and can jump using the space bar and look around using the mouse. the MouseLook action is then liked to the Virtual Camera that is responsible for tracking the player. I did this by adding a Cinemachine Input provider component into the virtual camera, this will override the needs for the standard input.

Figure 2: Cinmachine Input Provider component

With this setup, I created a player character with the most complex graphics that any GPU can ever handle!

Figure 3: The player character

At this point I was ready to start coding a simple third person controller. For this case, I wanted to use Unity’s character controller to handle the movement and the ground check for me. I started with creating the below variables:

Figure 4: The controller’s variables

Afterwards, I initialized the input system for player controls and some other variables in the start and awake functions

Figure 5: The unity functions and initializations

You may have noticed that I tend to comment my code a lot. I do this because it is very important to make your code understandable by other people who may review you code or even be working with you. Also, a great man once said:

Always comment your code as if the one reviewing it is a serial killer who knows where you live!

Let’s get back to the code and examine the Move() function This is where the magic is happening. this function is divided into to major parts. The part where the player moves and we align the player forward vector with the camera’s direction and the other is to handle the jump. Here is the code that makes the player move in the direction of the camera:

Figure 6: The player movement section with respect to the camera’s direction

The code looks straight forward but I want to explain a bit the lie where I calculate the target angle. Imagine the the player is looking at a direction, call it x, now put a point at that line, then imagine that the camera is looking at another direction and plot a point on that line and call it y. These two line will intersect at some point and you want to calculate the angle between those two lines because this is the angle in which the player should turn in order to be aligned with the camera’s forward direction. The function that can calculate the angle for us is an Atan2 function.

Figure 7: Atan2 Function

As you can see in figure 7, the angle can be calculated by the function atan2(y, x). However, in our case the atan2 function will look like this atan2(x,y). The reason behind this is that we are facing the forward direction and according to tan part in sohcahtoa, the tan of theta is calculated by the opposite/Adjacent. Since we are looking forward (the direction of the positive Y axis) The opposite of the angle is a line parallel to the X-axis and the Adjacent is the Y-axis as shown in the diagram below.

Figure 8: the calculation of the the new theta

After calculating the target angle, I used the SmoothDampAngle function offered by Unity to smoothen the angle. Without the use of this function the player will snap to the new rotation, instead I wanted the player to have a smooth transition when rotating the desired direction.

The final thing that I did is to code the functionality for jumping which is straight forward.

Figure 9: The jumping code

The reason why I am caching the value of the yVelocity in a global variable is that I don’t want the y position to be overwritten every frame when the movement direction is calculated otherwise the player will jump in the current frame and will snap to the group in the frame right after it.

With this, I was able to create a basic third person controller that works like a charm. There are so many other things that I am planning on implementing but these are for a later blog post. Here is how it looks like:

Figure 10: The third person controller in action

Creating cutscenes with Unity’s Timeline

One of the things that make video games amazing is the ability to tell and experience stories. You can make the player engage with the game’s protagonist; or have compassion on the game’s antagonist. Back in the days of PlayStation 1, I was fascinated by the idea of having cut scenes in the game. It never came into my mind that you can actually play some kind of movies in a game. I used to call those cartoons 🙂 For many years, the idea of telling epic stories in games has haunted my thought. The Call of Duty Modern Warfare trilogy were just brilliant in the way they tell the story during the loading screen. The amazing story of God of War and how you feel bad for Kratos and so many other games that tell breath taking stories. All of these experiences and stories are told during cutscenes! Back in school I used to make short films and visual effects using Adobe After Effects and I always dreamed of being able to do something like this but in video games. Today I am telling you that this dream came true, and I finally was able to create my first cutscene and story in a video game using Unity3D.

Making cutscenes in Unity has been an absolute thrill and it is all thanks to GameDevHQ’s amazing Cinematography course offer to its Pro members. For this project I used GDHQ’s Filebase. If you don’t know what Filebase is, then you are missing alot. Filebase is this insane library of assets for Unity that you can use to make games. They have everything that you can imagine, in AAA quality.

To start with, you have to have some kind of imagination to how the scenes will look like, what the environment is and how you want your camera’s to pan through the scene. This can be all found in the director’s note. Usually these notes imagine the scene through simple sketches along with camera movement guides. They put you on a starting position to getting the correct shots of you scene.

Figure 1: Director’s Notes of the entry scene

In the above image you can see that the director is plotting the entry scene of the level. The director wants the player character to glide down the rope and you can see in the notes and in the arrow that the camera should pan downwards. Then there should be a shot from a far showing the player dropping down in the dark corner of the room. From that point, the animators should start animating the scene a 3D software, export it to a format that Unity can understand and then it is time to import that animation clip into Unity. This is where the all the magic happens.

After importing the animation clip, you want to plan your shots, how do you know what shots to take and for how long? You guessed it, from the director’s notes. You want to do exactly as the director has intended. The first thing I did here is that I started planning for the shots. I creating multiple Virtual Cameras that are scattered across the scene.

Figure 2: Virtual Camera’s scattered in the scene

In figure 2 you can see the “CM” icons, these are all virtual camera positioned at a starting place where I want the camera to start panning from. The one that is selected above is the camera that pans down while the player character is gliding down the rope.

Figure 3: A director’s note of another shot
Figure 4: Another Virtual Camera for another shot in the same scene

Figure 4 is another shot taken from a different angle of the entry scene. Now when this shot is active, the player should be already on the ground and according to the director’s notes in figure 3. This is basically the approach that you want to take when planning out your shots before you start composing them. For each shot, I had a camera ready to be animated to give the panning effect desired by the director as shown in figure 5.

Figure 5: How the hierarchy looks like after adding all the camera for a scene

Now, Here comes the million dollar question; how do I compose the shot? How do I get all of these shots together and pan the camera. The first thought is that this has to be a very complex way and it would take days to compose only one shot in Unity. This is not the case in Unity. Unity has this module called Timeline which is an amazing tool to compose your shots, just like Adobe Premiere or Final Cut. IT IS THAT SIMPLE!

In figure 5, you can see a game object called Into_Cutscene. This object I added a Playable Director component. This component holds the timeline. From here, I referenced all the virtual cameras in the timeline and starting animating them just like any professional video editing software. You can see in figure 6 how the timeline looks like, and if you are a video editor, you will be able to relate to it alot!

Figure 6: Unity’s Timeline in action

In figure 6, you can see that we can control the camera movement through animation, we can control the audio as in music of voice over. I can also control other game objects in the scene! How awesome is that! After a scene is over, the game is triggered and the user can start controlling the player character.

Another thing that I did was to trigger cutscenes to play when the player reaches a certain point. I used a box collider, as demonstrated in figure 7, that I positioned in a scene and when the player enters that collider, it triggers the cutscene.

Figure 7: A box collider that triggers a scene.

The code to trigger the scene is the following:

public class GrabKeyCardActivation : MonoBehaviour
{
    public GameObject sleepingGuardCutScene;

    private void OnTriggerEnter(Collider other)
    {
        if(other.tag.Equals("Player"))
        {
            if (sleepingGuardCutScene != null)
                sleepingGuardCutScene.SetActive(true);

            GameManager.Instance.HasCard = true;
        }
    }
}

This is the approach that I used in creating cutscenes in the game. At the end, this is what I came up with:

Figure 8: The cutscene with the level

I have to say, working on this mini game has been an absolute thrill to me and I cant wait to start working on the stories that I want to tell!

Devlog 5: Insanity’s Alpha Version Update

On February 16th, 2020,  I released my first game, Insanity, on itch.io as an alpha version for testing. I consider this as one of the most important milestones in my career as a game developer, as I never imagined that I would go this far. It was nice to see people downloading the game, giving it a try, and giving you feedback on how the game felt, or where things went wrong. It was such a great experience.

But where are we now with the game? What is the upcoming plan? I have been thinking a lot about this lately, and I have been a bit confused on whether to add some additional features to the game, or leave it as it is, and work on creating more levels and getting it ready for the release? Being indecisive is one of the things that you get to face when you do not have a proper scope document for your game; ironically speaking, I am starting a PMP exam prep course tomorrow, so this should help me in planning my next game better. I finally decided this quarrel in my head; I decided that I will not add any more features to the game, and I will start creating additional levels and challenges, and finally polish the game for release. I do not want to consume my brain by adding features and forget that I do have a deadline for releasing the game.

So what are the updates of Insanity so far? Here is a list of the most common issues that the testers reported in the alpha version:

  1. Interface issue: Almost all the bugs that the testers reported were related to this topic. The game’s menu has visual problems when it runs on other phones that have an aspect ratio that is not 16:9. It looks like the menu is going off the screen. I resolved this issue by downloading an asset from the asset store called Resolution Magic. This asset adjusts the camera’s orthographic size based on the aspect ratio of the display. What you do is that you define a canvas that you want to be visible, and the asset adjusts whatever is within that canvas according to the screen size.

Resolution Magic Canvas
The area in yellow is the canvas where all items within will be fitted with any screen’s aspect ratio.

  1. Coin Stacking: It seems that there was a bug that I oversaw when it comes to counting the collected coins. The correct behavior of the game should add the accumulated coins to the total count if and only if the player passes the level. It seems that in some cases, when the player dies, the coin counter does not reset, and the player accumulates the coins collected. I was able to fix this bug by taking a more in-depth look into the “PlayerPrefs” of the game; it should be working fine in the upcoming releases.
  2. I had a couple of comments on the controls of the game, and they are all divided into two significant opinions. Opinion #1: Keep the right and left arrows as they are as they provided more precision in character movement, especially in narrow areas. Opinion #2: Replace the two buttons with an on-screen joystick. Adding a joystick will allow the player not to remove their finger off the screen if they want to change direction. I think this is a valid opinion, but when I first started working on Insanity, I used an on-screen joystick, and somehow the controls did not feel right.

I am not quite sure which input method I should use, and I would love to see your opinions on this down in the comments, so feel free to share those ideas in the comments section, and let’s discuss this.

I received other suggestions with regards to Ad placement and a couple more on adding a timer functionality to each level so the users can speed run each level. While I think this idea is a great one, I think I will postpone it till the end of development. I will keep in mind when designing the levels that they need to be a speed run friendly to allow the players to speed run them fluidly, but I will keep the implementation of the timer and saving it to later in development.

I was also able to implement Insanity’s ultimate challenge, “Insanity Mode.” This mode is all about finishing the whole game in a single run. If the player dies, then you respawn back at level 1. I think if later I am to develop the speed run functionality in the game, then I would also include it in “Insanity Mode.” That way, the player can be challenged to finish the game in a single run, as fast as possible.

Insanity Mode
Insanity mode in action

So far, I think the game is looking good. I still need to work on many things and do many optimizations to the game, but that may be for a later time.

I really want to thank everyone who gave my game a try and submitted feedback or a bug report. The game is still on itch.io if you’re going to give it a try. You can download it by clicking here.

Devlog 4: Music Composition

Music is an essential part of any video game. They can change the mood of any scene drastically. You can have an intense scene full of action but if the music is not good enough, you may lose interest in whats going on. That’s why, in my opinion, right now, AAA studios spend a lot of money with top composers to get their music right. These days when you listen to a track, sometimes you cannot differentiate whether this is made for a movie or a video game.

When it comes to Insanity, music plays a crucial part of the player experience. I want the player to feel excited, I want the player to get that feeling of moving forward, to overcome all the obstacles to win the level. I want the pace of the game to be fast. I am not planning on showing any between level graphics like a player level performance rating or so, once the player is done with a level, I will get him/her right into the next one. There is no stop or pause. The music needs to convey this experience as well. I want the music to be fast, loud and when it comes to progression I want it to always have major notes, so it implants that feeling into the player that no matter how hard the level is, the player can still do it.

I worked with my cousin who is a great aspiring musician; his name is Karim Ibrahim, you can follow him on twitter by clicking here, or find some of his work on Anghami by clicking here. We spend hours and hours thinking about the main theme of the music. What I understood from him is that you need to pick a melody, a master melody and this should be the theme of the music of your entire game. You can them take that melody and do all kind of variations to it, but you need to stick to the main theme. I am not a musician so maybe I am having a little hard time explaining this; but think of Assassin’s Creed as an example. We all know the famous theme of Assassin’s Creed, and we have heard it in almost all the different releases of the game; but sometimes you hear the theme in acoustic guitar, sometimes you hear it in an orchestra, maybe in a rock progression. You can use that theme and incorporate it in any music genre you want. We spent a lot of time trying to figure out a good melody that we can use and follow through out the composition of the music; and we finally got there! It was really exciting for me to get that music recorded and ready.

We basically recorded two small tracks, one for the menu and another for the level. The rationale behind the menu music is that it should put you in the mood. It need to be a little but slow, but at the same time powerful enough to prepare you for the challenges ahead. We thought of having a basic percussion of a drum kick followed by a clap, maybe to give a feeling of encouragement to the player to what is yet to come! So the pace of the menu music would be a little slow, but the pace of the levels will be fast, this would put a good contrast, I guess, so that if the player switches back to the menu, things will get a little bit less intense.

I have to say when we finished recording the menu music and I added it into unity, the feeling I had was just priceless. The game started to have its own identity. It started to have its own unique feeling. To be honest, this experience has been one of the greatest experiences in my life so far and I am so thankful that my game has reached this stage. I will leave you here with a small snippet of what we did.

Devlog 3: Insanity’s Experience

One of the things that I was thinking about when i was working on my game is its experience. Any good game, in my opinion has to make the player feel something. Some games make their players feel powerful, smart, afraid, sad or even angry! I remember playing a game called I AM BREAD… Oh, that game made me want to find the developer that made it and just punch him/her in the face! But that what makes a game good, in my opinion; even if not a lot of people like it.

So, what do I want the player to feel when playing Insanity? I want the game to be challenging, fun and at the same time to make the player feel unstoppable. Now, the important question is: how can I convey this feeling to the player? The first thing that I thought of was the Music. Music can set the mood for any game. It can turn a glorious winning scene into the saddest scene you have even seen. For now, I am using the Mjolnir mix track for Halo 2; it is fast, using high keys and the progression of the music makes you feel that you just want to keep going forward. Now, I cannot just use that track in the game I am planning to release, but this track helped me in knowing what kind of music I want to include in my game. I want the music to be badass!

What else can I do to enhance the experience of my game? The Controls? Of course… the simpler and more efficient and responsive the controls are to the player, the smoother the game is, and the player will focus more on the game rather than having understand a complex controlling system (of course that case if for Mobile gaming). At first I was thinking of just using a joystick and put it on the left of the screen and the jump button would be on the right; something like Pubg’s controls. But I thought that this will be too complicated for my game; besides, the player will never have to do upwards or downwards in the game. So I decided to create the control system in buttons. A button that you press so the player moves forward and another for backward movement and a jump button. The movement buttons are close to each others to make movement for the player easy. The jump button is located to the left as most players have a muscle memory of jumping using the right hand.

Insanity Game
The controls of insanity at the bottom of the screen.

The plan for Insanity goes beyond music and controls, but also through game play. The player has to finish the whole game before he/she can unlock two additional modes for the game:

  1. Time Trial: Where the player can select a level and do it within his/her time. The player can break his/her own record by playing the level again and finishing it in less time.
  2. Insanity Mode: The ultimate mode of Insanity. This mode’s challenge is to finish the whole game in a single run. Which means that you have only one health point through out the game. If you die at any level, you restart the game from level 1.

I am thinking of incorporating the game with Google play games, and introduce trophy system to the game in order to make the game more rewarding to the player, but I need to think about it. Not sure if this will be available in version 1.0

For now, these are my thoughts when it comes to the Insanity Experience. I am sure, I will come up with more ideas along the way; after all, this is my first game ever. and I can’t wait to get it released!