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

Advertisement

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

Lets refract a laser in Unity

In my previous post titled Reflecting laser light in Unity, I talked about reflecting a laser beam through simulated mirrors. I then thought to myself, if I am reflecting light, why not refract it as well and make the game a bit trickier?

The break down of this problem is pretty easy:

  1. First, we need to shoot the light and check whether it hits an object tagged as lens or not.
  2. If the laser hits a lens, we refract the light.

I would recommend before proceeding through article that you read the “Reflecting laser light in Unity” as it goes in details through some of the functions that I will go mention in this article.

To detect the type of the object we hit, I had to update the function CheckHit() by adding an additional “else if” statement to check for a collision with a lens. The updated function looks like this:

Figure 1: The updated CheckHit function

The first thing we need to do, just like the reflection, is to store the point of impact on the lens on the list of indices of the LineRenderer and from there we need to calculate the refracted direction of the new laser beam. After spending a lot of time learning about physics, I found a law called Snell’s Law that is used to describe the relationship between the angles of incidence and refraction, when referring to light or other waves passing through a boundary between two different isotropic media, such as water, glass, or air. If we assume that when the beam is not touching the lens it is traveling through the air, and when it hits the lens it travels through glass, then we have to use that law to calculate the refracted direction of the light when it passes from the air to the glass. This is Snell’s law:

Figure 2: Snell’s Law in vector form

where n1 is the refractive index of medium 1, n2 is the refractive index of medium 2, l is the direction of the light that is hitting the surface and n is the normal of the surface, theta1 is the angle between the light and the surface and theta2 is the angle between the refracted vector and the surface.

in figure1, you can see that n1 and n2 is set from two constants that were declared and initialized in the class with refractive indices depending on the media type, the vector norm is set to the normal of the hit.point and the incident corresponds to the direction of the laser when it hits the lens. Then we come to the most important function which is Refract() where the refracted vector is calculated through Snell’s law. the function looks like this:

Figure 3: The Refract() function

As you can see, the incident is normalized and then we plug in all the inputs into the equation to get a refracted vector. Once the new vector is calculated, we can now use the CastLaser() function with the new refracted vector to draw the new laser beam. But there is a problem, if you notice in figure 1, i am calculating an offset position based on the hit.point. The reason behind this is that the hit.point is located right on the box collider that is used in the object, the problem is that if we use CastLaser() with the new refracted laser direction and the hit.point, the ray casting condition in CastLaser() will return the same object again, because the ray hits the same object first. and thus we will recalculate the same vector, call CastLaser() again and keep going through the recursion until we get a stack overflow exception. To fix that problem, I moved the point in which the laser will be drawn a tiny bit so that it is not on the collider. This will ensure that the refracted light will not collide with the same lens.

This approach totally ignores the fact that the light should refract again when it is moving from the lens to the air, which means it should refract again, but for the purpose of this game, I decided to ignore it for now. Maybe I will make a separate article about it laser. But for now, here is how the refraction looks like:

Figure 4: The refracted laser demo

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

Make you game speak in different languages – the easy way!

Have you ever wondered how do games localize their games? what do we mean by localization? Localization is when you add multiple language support in your game. What if a player does not understand English but rather Arabic? Can we make a game that can run with multiple languages? With Unity, the answer is simply YES! Here are the simplest way you can make your game support multiple languages.

Once you import the localization package from Unity’s Package Manager you need to start setting up Unity’s Localization system by going to the Project Settings and then Localization. From there, click on Locale Generator. This where you will be presented with all the languages that Unity supports and all what you have to do is to check the languages that you want to support and press Generate Locales.

Figure 1: Arabic and English support are the selected Locales

Once you do that you will see the following two locales appearing in the available locales windows in the project settings:

Figure 2: Arabic and English appearing as the available locales

From there, all what you have to do is to create your Localization Table. Go to Window, Asset Management and then Localization Tables. From there Click on New Table Collection

Figure 3: The creation of localization tables

Give you table a name and click on Create String Table Collection. The table will be created and now you are ready to start creating your text and translations.

Lets say you have a UI Button that starts the game, the text on the button says “Start Game” and you want the player to switch the language and once the language is switched is should display “ابدأ اللعبة” in arabic. All what you need to do is to add a key and the sentence in the languages you support as shown in figure 4.

Figure 4: Localizing “Start Game” in the Localization Table

As you can see in figure 4. the key is a unique identifier for that translation and then under each column that corresponds to a language the translation is mentioned appropriately.

Now, how do we link that to the UI Text of the button? It is really simple to do that. All what you have to do is you need to add a component to the UI Text that is childed to the UI Button called “Localize String Event”. In that component, you need to do three things:

  1. In the String Reference, select from the table the key corresponding to the text you want to have in that button.
  2. In Element 0, Reference the Text component existing on that game object.
  3. In the Update String Event, add an event and reference the Text Component and then in the functions select the text property of the Text Component. This will allow the localization table to add the appropriate text depending on the selected language to the Text component.
Figure 5: the setup of the Localize String Event

Once you do that, it should work out of the box; and here is how it looks like this:

Figure 6: Localization 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!

A long time since…

It has been very long since I wrote a blog post that relates to this community. So, I will try to give a quick status update on what I am doing these days. After publishing Insanity on September 1st, 2020. I needed a break, so I took one full month off just to stop my brain from thinking or solving problems. It was well worth it. Now, as many of you may know, I am studying to enter a PMP exam by mid December. I am trying to get myself acquainted with project management in order to prepare myself for real life projects, whether they are personal, freelanced or even projects to studios if I get hired. My ultimate goal at for my game development journey is to become a creative director and direct the making of games. I already have, and still building, my technical expertise, so it won’t hurt to gain some management expertise as well. So wish me luck with that exam, please! I hate exams!!

I also won a grant that was offered by our government, where I attended the Game Design and Development Specialization offered by Michigan State University on Coursera for free. The specialization consisted of 5 courses:

  1. Intro to Game Development
  2. Principals of Game Design
  3. Game Development on Modern Platforms
  4. Entrepreneurship and the gaming industry
  5. Capstone Project for graduation.

It was a great experience and I completed the program on October 5th 2020. I learned a lot from this specialization especially when it came to game design. It also gave me an opportunity to attend seminars to developers, producers, designers and creative directors from the industry who work at EA, Ubisoft, Activision and Rockstar. It was eye opening and I am so glad I got through this experience.

How Insanity is doing So far?

Since I published Insanity, I have proudly made $0.53 :D. I got 1000+ downloads for the game on android and around 200+ downloads in iOS which is fine, but I didn’t make money out of it. This is okay, I was not really expecting my first game to be a hit or anything. The main goal of making Insanity was for me to experience making games, to live the whole journey from start to finish; to actually get something done and published to the public. I did that; and this is more than enough for me at this stage. I am not a person who like to take big leaps, but I always believe in a slow and steady approach to doing things. Whether I win or lose in the Ultimate Game Jam, having to build a game and get it out there, is just the greatest reward that I can get at the moment.

So… What’s Next then?

After resting a bit from Insanity, I started planning for a new project. I worked with my cousin for some time to come up with an idea for a competitive online game. We had some really good ideas and we almost finalized a High Concept Document; but then something great happened to me three weeks ago…

A friend of mine who works at a company in Egypt, called me and she was interested in the games I make and she started asking me questions about how long have I been doing this and whether I am interested in doing professional game development work and I told her that I was open for anything; and this is when it happened. She offered me an opportunity to be outsourced and work on a project that they signed with the government to create a game that raises the kids and youth awareness against COVID-19 and how can they protect themselves from the virus and stop its spread. I found myself saying, YES! One week later, I signed an official contract to lead the design and development of the game; and an NDA of course. Unfortunately, I won’t be able to share much of the development journey, but I will sure share with you all some screenshots when things start to take shape. So far, we got the client’s approval on the game idea and we are now waiting for their approval on the High Concept Document. Once approved, I will start the technical design and jump into Unity and Visual Studio. I have never been that happy! Hard work is finally paying off!

Now, my current PC can barely run URP, imagine if I want to do something on HDRP. I remember when I did Al Heck’s course on making beautiful levels, doing the level in HDRP was painful because of the processing power of my PC. So I decided to build a new PC so I can work on, and at the same time play games as well. Here are the specs that I bought:

  • CPU: AMD RYZEN 7 3700X 8-Core 16-Threads (Max Boost 4.4 GHz)
  • Mother Board: GIGABYTE B550 AORUS PRO AC
  • GPU: ASUS GeForce RTX 2080 SUPER ROG Strix 8GB GDDR6 Graphics Card
  • RAM: HyperX Fury Desktop Memory Single Stick 16GB 3200 MHz
  • SSD: Sabrent 512GB Rocket NVMe PCIe M.2 2280 Internal SSD High Performance Solid State Drive
  • HDD: 1TB Seagate BarraCuda
  • Case: XPG INVADER Mid-Tower PC Chassis Black
  • PSU: Seasonic 620 Watt Bronze (Not the best Wattage, but it will do for now)
  • Cooling: 3 CoolerMaster front intake fans, 1 XPG fan in the back as an exhaust, 1 XPG fan on the top as an exhaust. Cooler Master MasterLiquid ML240R Addressable RGB for CPU Cooling.
New PC Setup

At the end if I were to give anyone reading this post an advise. It is to never give up hope and just keep doing what yo are doing and always believe in yourself and in your dreams!

Cheers!

First FPS game!

As many have noticed, these days I started to learn game development. Through the last course that i took I learned the basics of Unity; I learned how to make 2D games as well as 3D games.

One of the projects that i worked on during the course was to create a 3D First Person Shooter (FPS) game. All the models imported into the project were created by Unity artists; so all i did was just the programming and the logic for the game.

I am pleased to share with you my first FPS game. you can download it from the link below and try it out. Feel free to leave a comment about the game.

Sci-Fi Shooter Game