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