Beginner, Tutorials, Uncategorized, Unity3D

Unity3D Animated Pause Menu, Part 4: Responding to Player Input

Now that we have a functioning animator controller, it’s time to accept player input so that we can actually pause the game and bring up the menu.

To do this, create a new C# script called PauseController. This will be a very simple script; it’s 20 lines including whitespace, because all it needs to do is update the isPaused parameter of our animator controller. Here it is, in all its glory:

You’ll want to add this to the scene, so go ahead and drop it on the Canvas game object and drag the animator component to the canvasAnimator slot in the inspector.

There are a couple interesting things to note here. First, the isPausedHash bit. Animator parameters are identified by strings in the animator window and when getting or setting parameters in code, but this can be inefficient when updating them frequently (say, every frame). The preferred solution is to precompute the internal identifier that the animator uses to refer to the parameter, which allows for optimized lookup. Animator.StringToHash allows us to do this: is takes the string parameter name, and returns an integer identifier that we can use in its place. The only problem is that the identifier is not stable (we can’t just fetch it once then store it, because it might change between builds or potentially between plays of the game), so we simply cache it during the startup lifecycle of the component.

Input settings
Input settings
The second bit is on line 15, where we use Input.GetButtonDown("Cancel"). We could have bound the pause button to a specific key on the keyboard, but we’ve instead chosen to bind it to what is termed as an “input axis,” in this case, the “Cancel” axis. By default, this is the escape key, but it can be redefined by you, or even by the player later, and provides much more flexibility. You can find your project’s axes (and modify them or create new ones) via the Edit > Project Settings > Input menu. Note also that the Cancel axis is the same one used by the UI event system by default, so by using it, you’re providing a more consistent experience for your players.

As I mentioned, this script is very simple: when the player activates the Cancel button (again, the escape key by default), we toggle the isPaused parameter in our animator controller. After adding the PauseController component to the scene, you can test it out in play mode. There’s one problem though: activating the pause menu doesn’t actually pause the game. The easiest solution to that is to simply adjust the time scale in the PauseController when we change the isPaused parameter, but I want to take a slightly different approach, using a state machine behaviour.

State Machine Behaviours

Unity’s StateMachineBehaviour is a class, like MonoBehaviour, which you can extent and add to one or more animator states, and which provides hooks to execute code in response to certain events, like entering or exiting the state. In our case, the behavior we want is to stop gameplay when we enter the Paused state of our animator, and resume gameplay when we leave it.

Create StateMachineBehaviour
Create StateMachineBehaviour
To create the StateMachineBehaviour, go to the Animator window, select the Paused state, and click the Add Behaviour button in the inspector, beneath the Transitions controls. Click New Script, and name it something like PauseSMB. Hit enter to confirm. Here’s what a newly-created script looks like:

You can see that there are five events that a StateMachineBehaviour handles: OnStateEnter, OnStateUpdate, OnStateExit, OnStateMove, and OnStateIK. These five states provide enormous flexibility in scripting your animations, and we’ll explore them in greater depth in another tutorial. For the purposes of our pause menu, though, we only care about two: OnStateEnter and OnStateExit. Uncomment those two, and remove the rest.

Pausing and unpausing the game is a simple matter: we simply adjust Time.timeScale to be either 0 (paused) or 1 (full-speed). There are more interesting things you can do with the time scale, but for the pause menu, we’re only interested in “full paused” and “full speed.” Change Time.timeScale to 0 in OnStateEnter, and change it to 1 in OnStateExit. Remember that we added the StateMachineBehaviour to the Paused state, so this reflects our expectations on how the game should behave: when we enter the state, the game should pause, and when we leave it, the game should resume again.

Here’s the code:

Just like the PauseController class, this is very simple. As I mentioned, we could have put this logic in the PauseController itself, but by instead putting it in a state machine behavior that is explicitly tied to the Paused state, we’re making a clean separation between “telling the game to pause” and “telling the game what to do when it’s paused.” Now it doesn’t matter if we always trigger the pause transition from the PauseController or if we eventually decide to add a new way to pause the game: the logic is in one place.

Setting Animator to Unscaled Time
Setting Animator to Unscaled Time
If you enter play mode and test things out, you’ll notice something strange: the game pauses properly (you’ll want to add something moving to the scene to confirm this), but the pause menu doesn’t appear until you unpause the game (at which point, it suddenly appears and plays the proper “transition out” animation). This is because by default, the Animator component respects Time.timeScale. When we hit escape to bring up the pause menu, we successfully transition to the Paused state, and then immediately halt the progress of the animation by setting Time.timeScale to 0 (you can confirm this by going to the Animator window and seeing the transition bar stuck at the very beginning). This is great for keeping character animations in sync with the game speed, but doesn’t work as well for animations that only happen while the game is paused. To remedy this, select the Canvas gameobject in the hierarchy, find the Animator component, and change Update Mode from Normal to Unscaled Time (remember to exit play mode first so that your changes are preserved).

At this point, we’ve set up our pause menu UI, animated it, and added code to allow the player to pause and unpause the game. We could call it good, but in the next section, we’ll talk about how to add a little polish to what we’ve created. Thanks for following along so far!

Beginner, Mecanim, Tutorials, Uncategorized, Unity3D

Unity3D Animated Pause Menu, Part 3: Setting up the Animator Controller

So far in our efforts to create an animated pause menu, we have set up the required UI elements for the menu, and created the animation clip that will drive the transition between the paused and unpaused states of the game. Now, we’re going to move ahead and set up the Animator Controller that will actually handle the user’s request to pause or unpause.

Default Pause Menu Animator In our Unity3D project, click the Canvas gameObject in the inspector, then open the Animator window (as far as I know, there is no hotkey for this, but you can find it in Window menu under the Animator label). You should see a fresh animator editor with three states: Any State, Entry, and Pause (or whatever you called the pause animation that we created in step 2), with a transition from Entry to Pause.

Creating a new default state
Creating a new default state (click to enlarge)

Any State doesn’t concern us in this tutorial, and Entry just indicates which state the animator controller will immediately transition to upon starting. This is currently Pause, but we’d like to start the game in an unpaused state, so go ahead and right click on the editing surface and select Create State > Empty, then right click on the new state (imaginatively called “New State”) and select Set as Layer Default State. In the inspector, go ahead and call this state Unpaused.

Now we need to create a transition, which is a set of conditions under which the animator controller will move from one state to another. In this case, our transition conditions are very simple: if the game is paused, we transition to the “Paused” state. To define this, we will create a new state machine parameter.

State Machine Parameters

State machine parameters are simply pieces of data that inform the animator controller about the condition of the game. They can take the form of floats, integers, booleans, or triggers (which are just a special case of boolean that resets immediately after being consumed by the state machine), and they are used in transition conditions to determine how the state machine should behave next. What makes them so powerful is that they can be set from code, which we’ll explore in the next segment of this tutorial.

In the case of the pause menu, we will drive it with a single boolean parameter: isPaused. To create this, select the Parameters tab on the left of the animator window, click the + icon, and select Bool. Name it isPaused and hit enter. You can leave it unchecked (the default).

State Machine Transitions

For our new parameter to be useful, we need to create some transitions that use it. As I mentioned above, a transition is a set of conditions that govern when the state machine moves from one state to another. These conditions can be timing-based (“wait for the end of this animation,” for example), or they can be condition-based.

Setting up the transition (click to enlarge)
Setting up the transition (click to enlarge)
We’ve already discussed one example of a condition: isPaused = true. Create this transition by right clicking on the Unpaused state, clicking Make Transition, then click on the Paused state. The transition is indicated by a white arrow pointing Unpaused -> Paused. Click on the transition arrow to select it, then in the inspector, uncheck Has Exit Time. This indicates that we don’t want to wait to transition: when the isPaused condition (which we will set up next) becomes true, the state machine should transition immediately from Unpaused -> Paused. In the Conditions list, click the + icon. Since isPaused is our only parameter, it will be selected by default, but if you had multiple, you could find it in the “key” dropdown on the left. Make sure the “value” dropdown is set to true, and we’re done setting up this transition.

You can test our progress so far by entering play mode, selecting the Canvas game object, and clicking the isPaused checkbox in the parameters list. You should see the pause menu animate in (if it’s animating in over and over again, you may have forgotten to uncheck the Loop Time box in the animator clip inspector), and if you uncheck the isPaused parameter checkbox, you should see… nothing. The pause menu will sit there, smugly defiant. This is because we’ve told the animator controller how to animate from Unpaused to Paused, but we haven’t yet specified how it should transition back to Unpaused when the player unpauses the game.

If we wanted to make the menu disappear instantly, we could just set up a transition from Paused -> Unpaused, give it a condition of isPaused = false, and be done with it. For completeness’s sake, let’s say that we want to play the same animation that we play when we’re pausing, but in reverse. To do this, we need to create a third state, which we’ll call Unpausing. Set a transition from Paused -> Unpausing (while you’re at it, you can create a transition from Unpausing -> Unpaused, which we’ll set up shortly), remembering to uncheck the Has Exit Time checkbox, then give it a condition of isPaused is false. Click on the Unpausing state node, and drag our pause animation into the Motion property slot of the inspector. This will indicate that we want to use the same animation. To specify that we want that animation reversed, change the Speed property from 1 to -1. Specifying a negative speed essentially means that we start at the end of the animation clip, and work our way forward, effectively performing all the motion encoded in the animation backward.

The last thing we have to do is to configure the transition Unpausing -> Unpaused. Remember how we discussed that one of the types of transitions is based on timing? That’s exactly what we want. The Unpausing state starts playing our transition animation. As soon as that’s done, we want to leave the Unpausing state and transition back to the Unpaused state. Click on the transition arrow pointing from Unpausing to Unpaused, and open the Settings flyout. Set Exit Time to 1 and Transition Duration to 0. Leave the Conditions list empty.

Go ahead and test it out in play mode, checking and unchecking the isPaused parameter to see the menu slide in and out smoothly. One thing I notice, though, that the exit animation (which is again just our enter animation played backward) seems to take a little too long: when I’m leaving the pause menu, I want to get back into the action quickly! Click the Unpausing state and change the speed multiplier from -1 to -2. Not only does this indicate that we want to play the animation in reverse of how it was recorded, we also want to play it at double speed. You can drive this value with a parameter, which opens up all sorts of possibilities, but that will be a subject for another lesson.

That’s it! You’re done setting up the animator controller! In the next installment, we’ll talk about how to drive the animator from code so that we can actually pause and unpause the game. Stay tuned!

Beginner, Tutorials, Uncategorized, Unity3D

Unity3D Animated Pause Menu, Part 2: Animating the UI elements

Following the setup of all the UI elements for the pause menu in part one, we’re now going to create an animation for the transition between the unpaused and paused states of the game. As a reminder, here’s a preview of the finished state of the pause menu, showing the transition animation:

Pause menu animating in and out with example gameplay in background
Pause Menu in Action

Before we get started, let’s talk a little bit about animation in Unity3D. Unity’s animation system, Mecanim, uses curves to represent motion. Most commonly, these motion curves drive the movement of 3D models, but you can actually use Mecanim to animate any public property that Unity knows how to serialize. We’re going to use this to our advantage in our pause transition to move UI elements around the screen.

With Mecanim, you can either edit the curves directly, or use the keyframe-based dopesheet to specific values, and let Mecanim figure out the curves for you. In this case, we’ll be use the dopesheet as it’s easier to work with and we’re not going to be doing anything too complex.

Open the Animation window (⌘6 on OSX, ctrl-6 on Windows), select the Canvas game object in the hierarchy, and click the Create button. Doing this will prompt you to create a new Animation asset, as well as creating a new animator controller and adding an Animator to the Canvas game object if it doesn’t already have one. Note that you could technically animate the menu elements directly, but as we split them up to allow for more complex transitions, and because we want to later be able to animate multiple, discrete UI elements with one animator controller, we’re going to add the animator to the Canvas, which is the highest-level parent of a UI element.

After creating a new animation clip, we enter “record” mode by default, but first we want to set all our pause menu UI elements to their default (unpaused) state. Click the red Record circle exit record mode, then select the panel background, panel contents, and title text, and move them off-screen. To achieve the transition effect I wanted, I moved the panel background on the x axis to the right, the panel content on the x axis to the left, and the title text on the y axis up. They don’t have to be a huge distance off-screen, just enough so that they’re not visible during gameplay (you can use the Game window to check this, or enter play mode to try it out). My UI view now looks like this:

Current UI Setup
Current UI Setup

With our initial state set up, we’re ready to animate! Select the Canvas game object and pick your pause animation out of the dropdown menu if it’s not already selected, then hit the red button to enter Record mode. You know that it’s working properly when your editor play mode buttons turn red:

We’ll want to add three properties: Panel Background > Rect Transform > Anchored Position, Panel Content > Rect Transform > Anchored Position, and Title > Rect Transform > Anchored Position. This adds keyframes for each property at 0:00 and 1:00 (one second). If you played your animation now, it would do… a whole lot of nothing, because the beginning and ending keyframes have the same value, which is in effect saying “do nothing for one second”. Let’s change that. Drag the playback head (the red line) to the one second mark (clicking on the keyframe at the time you want to change won’t have the desired effect) and “zero out” the Anchored Position properties, setting each UI element in the pause menu to the position that it should be in when the game is paused. You can either set them in the Animation window directly, set the appropriate fields on the Rect Transform in the inspector (animated fields turn red as well when in record mode), or reposition the elements by hand in the scene view.

With that done, hit play in the animation window. You’ll see the different elements of your pause menu slide in, but one second to bring up a menu is almost painfully slow. Players are nothing if not impatient, so we need to make the transition snappy to avoid frustrating them. Plus, I think that, rather than all the motion happening at once, it will look better if the background flies into place first, followed by the text and buttons sliding in, followed by the logo dropping into place. Exit animation play mode, and adjust the animation by dragging the keyframes in the dopesheet. I found that about a quarter second per element (so, multiples of 0:15 on the timeline), with the next element starting its motion as the previous reached its destination, felt about right for the feel I wanted to achieve. Here’s a look at my finished dopesheet, about 50% through the full animation (as indicated by the red playback head line):

Completed Dopesheet

With that, we’ve completed the animation for our pause menu elements. The last thing to do is select the animation clip asset we’ve created and uncheck the Loop Time property in the inspector, as a preparation for creating the pause transition state machine in the next tutorial post. Thanks for following along!

Beginner, Tutorials, Uncategorized, Unity3D

Unity3D Animated Pause Menu, Part 1: Setting up the UI

Today, we’re going to start building an animated pause menu in Unity3D. We’ll go through setting up the UI, animating the UI elements, creating the animator controller / state machine to transition from unpaused to paused, and actually pausing the game in response to player input. We’ll even get into a bit of polish and shine by making the game visible but blurred while the game is paused.

Here’s a preview of the finished product:

Pause menu animating in and out with example gameplay in background
Pause Menu in Action (click for higher quality)

Setting up the UI

Let’s get started! First things first, we’ll want to add a UI canvas (Create > UI > Canvas) if the scene doesn’t already have one. Since part of the pause animation involves the various components swooping in from off-screen, we want to make sure that our pause menu elements never accidentally appear on screen until we want them to.

Canvas Scaler Component With that in mind, go ahead and add a Canvas Scaler component to the Canvas GameObject. This controls how the UI elements parented under the canvas are scaled at various resolutions. I like to use Scale with Screen Size with a Reference Resolution of 1024×768, but you can set the reference resolution to whatever works for you. Either way, set the Match property to 0.5 to take screen width and screen height into account equally. This should help avoid situations where the edges of your pause menu UI elements become visible at higher resolutions.

Now we need to create the menu itself. The transition I have in mind is for the background panel of the menu to come in from one side, the buttons and text of the menu to come in from the other, and the game name or logo to drop in from above. This means that, while I would normally add the buttons as children of the background panel, I’m going to need to add the buttons to a sibling object of the panel. This will allow me to animate them separately without conflicts.

Anchor Presets
Anchor Presets
After adding the background panel (Create > UI > Panel), you’ll want to open the anchor presets by clicking on the crosshair-looking box in the upper left of the panel’s Rect Transform and shift-click the middle button to set the anchor and pivot of the panel to the middle of the screen. Then you can change the width and height of the panel. I chose 300 x 330 for a nice, chunky-looking box.

Now to create the content (buttons and text) that will go into the box. Select the canvas and add an empty child (Create > Create Empty), name it something like “Panel Contents,” then repeat the steps that you followed for the background panel: set the anchor and pivot to the middle of the screen, and give it the same height and width as the background panel. I added some text that reads “Paused” and set the anchor/pivot to stretch across the top of the container, then added another empty child to the Panel Contents game object, called “Buttons.”

On the Buttons game object, add a Vertical Layout Group component, which will automatically position our menu buttons in a nice column. Set Child Alignment to “Upper Center”, and make sure the width and height buttons are both checked for Child Force Expand, ensuring that the buttons use all the available space inside the layout group. Set padding and spacing values to whatever looks good to you: padding is how much space will be between the edge of the menu box and the buttons, and spacing controls how much vertical space there is between buttons. If you’re not sure, start with 10 and adjust from there. Make sure the anchor and pivot are set to the center of the container for the “Buttons” object, and give it a little space on Top in the Rect Transform so that the buttons don’t overlap with the “Paused” text.

The last step is adding a logo or other game text above the menu, which is just a text UI object with its anchor set to the top middle of the screen. If you’re using text and it vanishes when you try to make it larger, either increase the width and height of the text’s Rect Transform, or set Horizontal and Vertical overflows to “Overflow” in the text component’s Paragraph section.

The Situation so Far
The situation so far

In the next post, we’ll work on the animation that we’ll use for the pause transition.

Implementation Notes

The font I used was Bungee Regular, which is available under the SIL Open Font License.

If you need help with a color palette, searching “material design color palette” online can give some great examples to get you started. In particular, I like to use the colors provided by clrs.cc while prototyping.

Tutorials

Lerping the Matrix: Implementing Bullet Time in Unity

In this video, I talk about coroutines, and the proper use of Mathf.Lerp

And the code:

[code language=”csharp”]

using UnityEngine;
using System.Collections;

public class BulletTime : MonoBehaviour {
public float minTimeScale = .5f;
public float transitionTime = 1.0f;

bool isBulletTime = false;

// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {
if (Input.GetButtonDown ("Ability")) {
StopCoroutine("ToggleBulletTime"); // make sure we’re not trying to speed up and slow down at the same time
StartCoroutine("ToggleBulletTime");
}
}

IEnumerator ToggleBulletTime () {
isBulletTime = !isBulletTime;

float start = Time.timeScale;
float target = isBulletTime ? minTimeScale : 1.0f;
float lastTick = Time.realtimeSinceStartup; // we need to keep our own deltaTime, since Time.deltaTime is affected by changes to Time.timeScale
float t = 0.0f;

while (t <= 1.0f) {
t += (Time.realtimeSinceStartup – lastTick) * (1.0f / transitionTime);
t += Time.deltaTime * (1.0f / transitionTime);
lastTick = Time.realtimeSinceStartup;

Time.timeScale = Mathf.Lerp (start, target, t); // we need to use a constant start, not our current value, or we run about twice as fast as we’re intending
Time.fixedDeltaTime = 0.02f * Time.timeScale;

yield return null;
}
}

void OnGUI () {
GUI.Box (new Rect(Screen.width – 150, Screen.height – 50, 75, 25), Time.timeScale.ToString ());
}
}

[/code]

Tutorials

Creating a flashlight GameObject in Unity3D

I’ve been playing around with Unity 3D lately, and I put together a short tutorial video about some of what I’ve learned. Enjoy!

Here’s the code used in the video:

[code language=”csharp”]
using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Light))]
public class Flashlight : MonoBehaviour {
public GameObject source;
public AudioClip toggleSound;
Light _light;

// Use this for initialization
void Start () {
_light = GetComponent<Light>();
}

// Update is called once per frame
void Update () {
if(Input.GetButtonDown ("Flashlight")) {
_light.enabled = !_light.enabled;
AudioSource.PlayClipAtPoint(toggleSound, transform.position);
}

transform.Rotate(source.transform.rotation.eulerAngles – transform.rotation.eulerAngles);
}
}
[/code]

Symfony2, Tutorials

Using composer with Symfony2

So it’s been on the radar for a while, but Symfony2 recently switched over to composer for package management, moving away from the homebrewed bin/vendors install method. Playing around with it, a few things were non-obvious to me… and judging by the number of search engine hits on “symfony2 composer tutorial,” it’s apparently non-obvious to a few other people as well. So, I thought I’d just share some observations. Hope they’re helpful.

composer packages are not the same as git repos

The old dependency management system just cloned git repos, and locked them to a specific commit, tag or branch if you asked it to. It was simple, but it lacked functionality like dependencies of dependencies, version requirements, and so on. True, composer is a little more complicated, but it has all these features.

For example, if I tell composer to use the FOSRestBundle as a dependency in my project, but I don’t have the JMSSerializerBundle also listed, it will see that the RestBundle depends on the SerializerBundle, and download that as well. That lets you keep your composer manifest neat and tidy, without worrying about missing sub-dependencies.

You can search through available repos on packagist.org. Most of the well-maintained projects are available there (and I just condemned myself, because I don’t think my ACL manager bundle has a composer file yet. Oops).

The install command may not work like you’d expect

At least, it didn’t for me. I cloned the Symfony2 Standard Edition project, added the FOSUserBundle as a dependency, and ran php composer.phar install. It crunched a minute, said it was downloading some stuff… and I still didn’t end up with the user bundle in my vendor directory. lolwut.

As it turns out, the steps that the install command follows look something like this:

  1. Check for an existing composer.lock file. If one is not found, generate it from the contents of the composer.json manifest
  2. Ensure that the dependencies in the vendor directory match the dependencies required in the lock file, by downloading, updating or deleting vendor bundles as necessary

Coming into a project that has an existing lock file (which the Standard Edition does), running the install command will only ever operate against that lock file, no matter how much the manifest file is changed. The solution turned out to actually be quite simple: modify the manifest file, then run php composer.phar upgrade… the upgrade command will generate a brand spanking new lock file from the latest version of the manifest and update vendor dependencies against it. Simple, but non-obvious to me at first.

autoload.php just got a whole lot easier to manage

Easy as in, you don’t have to touch it at all most of the time. Symfony2 now uses composer’s autoloader, which quite magically knows how to load all of the dependencies that it has downloaded. Once you get all your dependencies in place (php composer.phar upgrade if you’re having trouble, remember), everything should Just Work, and you should only need to modify autoload.php if you have a library that needs special treatment.

script hooks are awesome

True story: you can provide composer with static methods on classes to handle certain events that happen during the composer lifecycle. For example, the Symfony2 Standard Edition calls methods in the SensioDistributionBundle on post-install and post-update to build the bootstrap cache file, clear the cache and install assets. Check ’em out.

This move is a good thing

Yeah, it’s different, and different is scary. But it’s good. Trust me. Remember what I said about focusing your efforts on writing application logic? Yeah, that applies to framework developers, too. Using composer lets the Symfony2 team focus their attention on the framework and its components, and still have the benefit of a feature-rich package manager. Win, all around.

composer isn’t just for Symfony2

Composer was inspired by Ruby’s bundler and node’s npm… it’s not just for Symfony2, you can use it for any PHP project. As long as your naming conventions are PSR-0 compliant, the composer autoloader will hook you tha eff up, homeboy. So have fun.

That about wraps it up, hope it helped. Any questions, post in the comments or shoot me an email.

Screencasts, Symfony2, Tutorials

Developing with Symfony2, part 1: Setting up shop

I’m pleased to announce that, after some technical difficulties, I have uploaded a Symfony2 screencast to YouTube. It’s part one of a series in which I’ll be walking through the development, from the ground up, of a working Symfony2 application… look for more installments in the coming weeks.

This screencast walks through a few of the basics:

  • downloading Symfony2 Standard Edition using git
  • using composer to install the framework dependencies
  • best practices for preserving privacy of sensitive information
  • making the logs/ and cache/ directories writable (note: if you can’t get this working, a good ol’ chmod -R 777 app/cache/ app/logs/ ought to get you started)
Tutorials

Two new tutorials on symfony2pros.com

I’ve been hard at spare-time (sort of like hard at work, only it pays less) on the Symfony2 tutorial site I mentioned previously; most of my time has been spent writing code, but I’m trying to seed the site with content as well, so I’ve cross-posted a couple of my previous Stack Overflow answers as tutorials:

I’m right in the middle of reworking the tutorial draft feature (which I consider to be core functionality, because I doubt most people can write a decent tutorial in one sitting), but I’m also working on another tutorial about converting request parameters into objects. Expect it sometime this week.