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

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!

Devlog 2: Level Design

One of the challenges I had when creating the levels is art. It is a skill that I am working on improving but at the same time I need to be productive and take a fast run in order to finish the game on time. I had to find a solution that can make my life a bit easier when it comes to the arts.

To start, I used the sprites that Jonathan used in his course “The Ultimate Guide to Mobile Game Development” and I used the skills I learned in that course to build a tile-map for the first level. Now I have a simple level where I used the dungeon sprites that were provided in that course. Then I decided to build another level with the same tileset, but I was thinking that I shouldn’t have all the levels having the same dungeon-y theme. I need to create levels with variable themes so that levels won’t be boring.

Level 2 of Insanity
Level 2 of Insanity

Thankfully a friend of mine, who is a graphic designer, referred me to a website called Freepik. This website has a big set of sprites that you can use to build your own 2D game varying from 2D characters with their animations to tilesets to GUI items and a lot more. Basically what I did is that I downloaded almost all the tilesets from that website and I had to find my way through Adobe Illustrator to extract those tiles, make a sprite sheet with the correct sizes so I can slice them properly in Unity and create the tilemaps. I have to admit, the results turned out to be great! So if you are a game developer who is not good at art like me, I recommend that you use this website as a good start.

Then it came the time to decide which traps should I implement to make the game challenging and at the same time fun. The idea that I have is that I wanted the player to advance through the game bit by bit. I don’t want level one to have tough traps and tricky jumps, otherwise, the player will get bored from the game; but rather, let’s start with an easy level and get tougher the more the player advances through the game. The traps that I am initially thinking about are the following:

  1. Spikes (of course)
  2. Circular Saws (stationary and moving).
  3. Fire (bring the heat!)
  4. tracking missiles? (not yet sure whether I should include this or not.)

When it comes to the behavior of those traps, I tried as much as I could to make the behavior of those traps modular. So basically I have built a universal class called TrapDamageBehavior. This class is responsible for killing the player if it collides with the trap. This class can work with any trap that I can think of. Now some of those traps are not stationary. For example, The Circular Saws tend to move back and forth in their tracks at the level. For this scenario, I wanted to do some OOP. Basically, I have created a generic parent class called MovableObject that Inherits from MonoBehavior. Here is its code:

public class MoveableObject : Monobehavior
{
    #region Private Protected Variables

    /// <summary>
    /// The object's point A
    /// </summary>
    [SerializedField] protected Transform pointA;

    /// <summary>
    /// The object's point B
    /// </summary>
    [SerializedField] protected Transform pointB;

    /// <summary>
    /// The movement speed
    /// </summary>
    [SerializedField] protected float _movementSpeed;

    #endregion
}

This class has two points, A and B, where the object can move between and a movement speed variable. Now I can create another class called OscillatingMovement that defines the movement of any object that needs to move between two points. That class will inherit from MovableObject and use points A and B and the movement speed variable. This class has a function called Movement where the object is moved from one point to another back and forth. The code of the function is this:

public void Movement()
{
    //positionToMoveTo is initialized in start to pointA

    transform.position = Vector3.MoveTowards(transform.position, positionToMoveTo.position, _movementSpeed * Time.Deltatime);

    if (transform.position == pointA.position)
        positionToMoveTo = pointB;
    else if (transform.position == pointB.position)
        positionToMoveTo = pointA;
}

I was able to use this class to move all the circles saw traps as well as the moving platforms in my game; I even used the same class to move the level target which is the gem in the same manner. All that I have to do is to reference PointA and PointB for any moving object in the scene and define a movement speed and the object will move between Point A and B right away. The reason why I thought of building the movement of those objects in this way is that I am trying as much as I can to reuse the parent class with multiple objects. For example, If I am to implement the missile that I may need to create a child class that only uses point A for example as a spawn point and point B be the player last location upon spawning and the missile can then move towards point B but not in an oscillating movement but rather a one-directional movement.

There is still a lot to consider and to think about when it comes to the traps and I also see opportunities for optimization; but for now, this is how I approached my trap behaviors.

Devlog 1: Insanity

Hello, and welcome to my devlog where I will be documenting my journey in developing my first game, Insanity.

Insanity is a mobile 2D platformer game that is inspired by a game called Super Meat Boy. I am planning to publish it to the play and app stores by the end of 2020. At the beginning I had no idea what game I should be doing. I downloaded some free assets from the asset store and tried to build my own Third Person Controller, then I tried to animate that character and play around with it, but I didn’t really have a solid idea that I can work on from the beginning and take it all the way to release. At that time I was playing Super Meat Boy, and i thought… why not start with something similar to it. 2D and 3D Development are pretty much the same with few differences as per my knowledge with Unity so far. So I decided to start with developing a 2D Platformer game similar to Super Meat Boy but for mobile.

I developed my first level in that game and experimented with the character controller to try to make the player move. Thanks to the course “The Ultimate Guide to Mobile Game Development” that Jonathan Weinberger offered on Unity, I got familiar with tilemaps and with the basics of level design for mobile games, and this is where it all started. I had my notebook with me all the time to write down any idea that I may have for that game. The game is supposed to challenge the player where he/she has to go through multiple levels with obstacles and traps and make it all the way to collect the sacred gem in each level. When I first thought about Insanity, I thought that it should include the following:

  1. Lots of traps that the player has to overcome.
  2. Power ups that can help the player overcome some complex traps easily. The power ups that I thought about so far are an ability to dash and freeze time for the environment.
  3. The game should give the player a feeling of having to push forward. So the over all atmosphere of the game is drive the player forward to try and pass all the levels.
  4. The music should convey that feeling to the player. For now I am using as a pilot the soundtrack of Halo. I still need to work on its soundtracks, but this will do for now.

When you unlock all the levels the game will unload a mode called “Insanity Mode” where the player is challenged to finish the whole game in a single run. No checkpoints, no lives, no mercy. If the player dies, he/she has to start the game all over from the beginning. I am not sure yet if this is a good idea to make or not, but I guess things will be clearer towards the end of development.

Insanity Game
One of the levels in Insanity

One of the challenges that I have when developing this game is the art. When it comes to art, and designing good looking environments and animations I am not that skilled, so i tried as much as I can to get myself comfortable with Photoshop. I also found a great website where you can file some really good tilesets that you can use in your 2D game. The website is www.freepik.com you can find a lot of good sprites over there.

I am also using Unity Advertisements to play ads to the player. I will be talking more about the my approach towards the ads in later posts.

So far I have built only 4 levels, and I keep on expanding on the game’s features. Once I finish all the features that I have planned, I will continue on creating more levels.

Level Selection
Level selection menu in Insanity

I will be sharing more insights on my development journey of Insanity. If you like to give it a try, you down download the apk file from this link and give it a try. This is an initial version just to test how things are going when building it for android. Go ahead… Give it a try!

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

First Game Development Certificate

Hello Everyone! Today I am excited to share with you an important piece of news.

Today I got my first game development certificate. I finally started to pursuit my dream of becoming a game developer and this is step one. As i mentioned in my previous post, when it comes to video games, my passion just over grows me. I love video games; I love playing them, and i love making them.

This course was an introductory course to Unity engine where it teaches you the basics on have to make some good games. I will continue on expanding my knowledge to this field until i reach my ultimate goal 🙂