Saturday, May 10, 2014

Unity3D Native 2D - A little about collision detection

As I mentioned before, all of my game objects actually use the 3D version of the colliders/rigidbodies.  This is because Unity currently lacks the features in its 2D API to support different force modes.  Now that I've mentioned all of the core game objects necessary for the game, let's look at how collision detection can finish the core game loop.  There are two conditions for the game over state; The player can hit the columns or the player can hit the floor.  The character is expected to behave differently when we collide with these objects. I fthe player hits the columns, then I expect the player to fall down to floor before the game over screen appears.  If the player hits the floor, I expect the player to immediately go to the game over screen.  To deal with these two conditions, I declare two new layers in the Unity project as shown below.


In code, I can reference these layers by their index values.  In Unity, when a trigger collider hits another collider, we can listen for this event using several API functions.  The one I will be using is OnTriggerEnter.  Let's take a look at the code that is needed for handling death.


The alive variable allows us to control whether we should listen to player input.  By wrapping the input code with an if statement that checks if the player is alive, I can stop the player from jumping once the bird hits something.  Notice in the Death method, we send out an event call and this is because other systems such as the ColumnScroll script needs to stop their scrolling when the player dies.  So in the ColumnScroll, we do something like the following.



This wraps up most of the core functionality I used in Unity and its Unity2D API to create a FlappyBird clone. If you have a question or feedback, feel free to leave a comment below!

Tuesday, April 29, 2014

Unity3D Native 2D - Column Creator

Source Code and executable can be found in the post here

For today's post, I'll discuss the system involved with generating columns for the player to jump between.

First, let's talk about the way each column works.  A column involves three game objects, a game object that represents the top column, another that represents the bottom column, and the last one which represents the "Pass Zone".

As you imagine, each of the game object that represents a column will have a box collider associated with them. The "Pass Zone" also contains a box collider and allows the game to know when a player has successfully passed an obstacle.  To make the column scroll across the screen, I create a ColumnScroll.cs script that looks like the following:


Now that we have one column in place, we need a system to generate them procedurally so the player has a constant stream of columns to pass through.  So in the scene hierarchy, I create a game object with a script called ColumnCreator.cs



This script is fairly simple as you noticed. The core of the logic lies in the coroutine where the system continuously spawn a column at a given spawn point every spawnInterval. Lastly, given our previous post about event listener, I create a start game event and when the start game event is called, the main game class can call the StartSpawn method to begin spawning of the columns.

Monday, April 14, 2014

Unity3D Native 2D - Game Flow + Event Listeners

Source Code and executable can be found in the post here

Last time, I talked about creating animations using the sprites from the sprite sheet and using them to set up various animation states in the Animator Controller.  This time, I'm going to take a quick detour before continuing onto the code that controls the Animator Controller.  Today, I want to talk about the overall game flow and how that is represented in this project.

Let's say the player starts up the game and enters the main menu. How do we go from this:


to this:


There needs to be some type of manager that knows that when the player presses start, the game needs to transition into some other game state which spawns the columns, scrolls the background, enables player input on the bird, etc.  One way to solve this method is to use a state machine.  Logically, we can represent each transition in the game as a separate state.  Take this project for example, I could represent the main menu as one game state, and create another game state called "In Game" that we can transition to and from.

One possible, and simple, implementation idea might be to have a enum variable that represents each state. Then in an update method, you can have if statements that will contain logic to deal with each state.  However, you may notice that we spend a lot of cycles doing useless work.  The only time that we transition from the main menu to the game state is when the user presses the start button.  So then, how do we avoid the need to constantly poll and perform unnecessary state checks?  One solution is to use event listeners.  

Event listeners allow objects to listen to specific events they are interested in, and respond when those events are triggered.  For example, the game logic can listen for the "Start button clicked" event, and when that event triggers, performs the necessary tasks to start a game.  Here's an example of my Message class.


So in this project for example, I have a Game.cs script which manages the flow of the game.  The Game.cs script is interested in when the player clicks the start button so it can tell other systems to begin and start a game.  To achieve this, we do something like the following :

Then to trigger the startGame event, we do something like :

One downside to this implementation is that debugging can be a little more difficult.  Because of the fact that code is no longer centralized in one core file, debugging and stepping through issues may require the programmer to follow the bread crumb trail and back track through various files.

Wednesday, March 26, 2014

Unity3D Native 2D - Player Controller pt 2 - Mecanim + Animation

Source Code and executable can be found here

In this blog, I will discuss how to create animations and use Unity's built in Mecanim system to drive the animations that we want. As mentioned from the previous blogs, we now have a Sprite sheet with sprites that are split up so that it can be used individually.

To add a flapping effect, I manually created animation using the sprites from the sprite sheet via the Animation window ( Window -> Animation ). 


On the top left of this window with the player selected, you can click on it and choose Create New Clip to make a new animation file.  Once created, you'll be able to look up the animation any time by clicking on the same top left area. To create the animation, I located the three relevant sprites of the bird in the sprite sheets and I simply dragged them onto the timeline area.

To create a looping animation, I had to make sure the first and the last frame is the same so that when the animation reaches the end and jumps back to frame 1, the exact same sprite is shown.  The time in which the sprites are placed are determined by simply playing the animation and watching if the animation looks smooth or not.  More formal planning can be used such as making sure animations run on 25FPS which means within the one second time line, you would equally space 25 sprite frames.  Once this animation is completed, I create 3 more animations. 
  • Idle - An animation with just 2 frames
  • Flap up - Similar to flap but with the addition that the sprite is animated upwards
  • Flap down - Similar to flap but with the addition that the sprite is animated downwards
For the Flap up and Flap down animations, by clicking on the Add Curve button, I added a curve for Transform -> Rotation.  Then for each sprite frame, I just made sure the rotation of the selected game object is rotated to reflect "up"(45 degrees Z axis) vs "down" (-45 degrees Z axis).  The reason why I added two more animations is so that we can blend them to get a nice smooth transition of the bird looking up and it jumps and the bird looking down when it starts to fall.

Now in the Assets folder, I create an Animator Controller that will house and drive the animations that I've created.  I opened up the Animator screen by double clicking on the Animator Controller.  The Animator Controller allow us to easily transition between animation through code and also allow us to create animation trees more easily.  I first drag the idle animation into the controller window.  This creates an Idle animation state that the player sprite can go to as a default animation.  The default animation state is always colored orange.  The starting default state can be easily changed just by right clicking on the state that you want to be the default and selecting the "Set as default" option.  

The next step is to create a blend tree.  First, I want the speed of the bird to determine whether the bird will look up or down.  Therefore, I create a parameter called speedY of type float that will dictate how the blend tree will blend.

Now, I create a new blend tree by right clicking on any place in the Animator window and selecting Create State -> From New Blend Tree.  Double clicking it will make the Animator window go one layer in 


On the right hand side you'll notice that the we can pick the parameter the blend tree uses as well as a list of animations to blend from (An empty blend tree will have an empty list).  First, pick the speedY as the parameter, then click on the little plus sign right below the Motion category to add new motion fields.


Then drag the 3 flapping animations into each list making sure that order matters.



To link the idle animation to the blend tree, I create a transition simply by right clicking on the idle state and selecting "Make Transition". This creates a line that I can connect to the blend tree.  I create a reverse one so that I can go back to the idle state.  I created another parameter of type bool that is used as the transition parameter between the idle and the blend tree state.


With this, the animation is complete and we can use our game logic to drive the bird animations.
Next time, I will talk about the code involved to drive the animations.


Wednesday, March 19, 2014

Unity3D Native 2D - Player Controller pt 1

Source Code and executable can be found here

In Flappy Bird, the player taps on the screen to force the bird to flap.  This flapping motion applies an upward force to the bird.  The player uses this game mechanic to avoid obstacles.  In this blog post, I will talk about how we can achieve this effect in Unity3D.

To start off, I created a player game object that will contain the necessary components.  In this game, the player need to have the following functionality:
  1. Drawn onto the screen.
  2. Perform a jump when the user taps
  3. Animate i.e. Flapping
  4. Collision Detection
Displaying the bird is very simple. As part of the native 2D functionality, Unity has provided a component called Sprite Renderer.  This component allow us to determine the current sprite that is being drawn as well as the layer that our bird will be drawn on.  Layering will be discussed later and will be important once we add a background and UI.  The Sprite Renderer contains a Sprite property which contains a null reference.  Simply drag the bird sprite in the project onto this field and the player game object should display the bird.

To perform a jump when the user taps, I decided to use Unity's PhysX system to drive the bird's motion.  To do this I add a Rigid Body Component onto the player.  Then I created a PlayerController.cs script.  The code to tap is the following:

To make the game values easier to tweak, I decided to add a gravity and tapForce variable that is visible in the inspector.  This gives me better control on how high the bird should jump and how powerful gravity will be.  The Rigidbody variable is to simply cache off the component so we can be more efficient.  The tapDir variable defines the direction the bird will move when we tap.  Lastly, through playtesting, I found out I needed a tapped variable that disabled gravity for the one frame that the player tapped.  Line 33 through 39 shows the code necessary to detect a mouse click and then apply a force afterwards.  You'll notice on line 35 that the rigidbody is reset when the user taps and before we apply a force to the bird.  This is because at that point in time, forces from a previous frame such as the previous tap or gravity is still affecting the rigidbody and is making the rigidbody move in some direction.  Therefore, to give a consistent jump effect, I need to clear the velocity prior to adding a force.  When I do apply a force, I apply it in ForceMode.Impulse which simulates an instantaneous force.  Along with setting the gravity to zero on that frame, it helps give a nice jump quick jump effect..

You may have noticed that I am simply using a Rigidbody as opposed to a Rigidbody2d which is included in Unity's new native 2D API.  I initially tried using that component but found its option lacking.  The main issue was that the Rigidbody2d provided no way of applying an Impulse type force.  This made the jump effect feel slow as it expected a force to be applied over time.

I will talk about Animation in the next blog. 

Sunday, March 16, 2014

Unity3D 2D experimentation

Hello!

It has been awhile since I've updated this blog.  Since the last blog, I've graduated, moved to a new city (Dallas, Texas), and I am currently working at Escalation Studios.  Recently I've had some off time to work on some side projects and I decided to take a look at Unity3D's native 2D tools.  For my first experimentation, I decided to create a clone of Flappy Bird.  I've included the project and the executable at the bottom of the post.

 Here's a few screen shots:



For this example, I grabbed the necessary art assets at http://www.spriters-resource.com/mobile_phone/flappybird/sheet/59537/.

As part of the native 2D tools, Unity can automatically split the sprites up in a sprite sheet.  After importing the texture into the project, I simply clicked on the texture, and under the inspector tab, change the sprite mode from single to multiple.


At this point, I can click on the Sprite Editor window and ask Unity to split the textures up for me.

I will discuss the implementation details in the upcoming blogs. Stay tune!

Here's the windows executable : https://db.tt/iwKu6yFT

Here's the project file ( Unity 4.3.3 ) : https://db.tt/DqDB5cqr