Mar 23, 2011
Posted on Mar 23, 2011 in Hints and Tips | 0 comments
Pausing a Unity game is easy. There are a couple of things you should be aware of, but we’ll get to those at the end of this tip. We’re going to add a few simple GUI buttons to control time within a basic Unity project.
Final Result Preview
Let’s take a look at the final result we will be working towards:
Step 1: Create a New Project
Let’s start off by opening Unity and creating a new project. You may want to add some animation or some kind of action to the proceedings, so that you can actually see an effect when we press the buttons. In the example provided, I just made some simple spinning cubes.
Opening a new project is nice and simple. Once Unity has finished loading, if you have it set to show the Project Wizard you can click the ‘Create New Project’ tab and enter a filename. Unity will take care of the rest. If the Project Wizard window doesn’t come up when you launch Unity, go to File > New Project.
Step 2: Create a New JavaScript Script
Unity has its own GUI system built in, which goes far beyond this tip. Let’s just say that everything GUI wise happens in a function called OnGUI and the GUI class provides a whole bunch of cool things, like a button.
Go ahead and create a new script through the Assets menu – select Assets > Create > JavaScript:
Your new script should appear in the Project window. Click once on the script and it should highlight so that you can rename it. Name the script “PauseScript” and hit enter. Now we want to start coding, so go ahead and double-click it this time. That should open up the default script editor with Unity’s template / default code already in it. Once the script editor is loaded up, delete the default code and replace it with the code below:
function OnGUI() {
// show a 'pause' button
if(GUI.Button(Rect(0,0,120,30),"TOGGLE PAUSE")){
// call our toggle function
doPauseToggle();
}
}
GUI.Button requires a Rect (which contains the x,y,width and height of our button) and the string to display within it. Finding out whether or not the button has been pressed is as simple as putting our GUI.Button draw method into an if statement.
Step 3: Coding the Pause Toggle Function
Here, we refer to a function that we are going to call doPauseToggle(). This will be a simple function that checks to see if we are paused or un-paused, then performs the correct action. Add the following code to the bottom of your PauseScript.js script, below the OnGUI function we added in Step 2:
function doPauseToggle() {
// here we check to see if we are running at a time scale above 0
if(Time.timeScale>0){
// time scale is above zero, so we need to pause the game here
pauseGame();
} else {
// time scale was less than zero, so we unpause the game here
unPauseGame();
}
}
Time.timeScale is how we deal with pausing the game. Essentially, we change the scale at which time is passing. When timeScale is 1.0, the time is realtime. At zero (0), time is paused. So in our doPauseToggle function we simply check to see if time is greater than zero, un-paused, if so we call a new pauseGame() function. Otherwise, unPauseGame() is called.
Step 4: Coding Pause and Un-pause Functions
The functions in Step 3, pauseGame() and unPauseGame(), simply manipulate the Time.timeScale value to either 0 or 1. Add the following code to the bottom of your PauseScript.js script, below the code we added in Step 3:
function pauseGame () {
// set scale at which time passes to 0, freezing time(!)
Time.timeScale=0;
}function unPauseGame () {
// set scale at which time passes to 1, running at realtime again
Time.timeScale=1;
}
Believe it or not, that’s all we need to do to add a pause button to a Unity file. If you have some action in your Unity scene, you will now see that it pauses and un-pauses whenever we click the button! Note that if you don’t have anything going on in your scene, you won’t see anything happen when you hit play.
Step 5: Moving in Slow Motion
Are you thinking what I’m thinking? If 0 pauses and 1 makes it go, what about 0.5? Think bullet-time!
First, let’s go ahead and add a new button to our OnGUI() function. Drop this at the bottom of the function, just above the closing } brace.
// show a 'slowmo' button
if(GUI.Button(Rect(0,30,80,30),"SLOWMO")){
// call our toggle function
slowMo();
}
Now we need a new function to adjust the time factor to less than 1. Scroll down to the bottom of your PauseScript.js script and add this new function:
function slowMo () {
// set scale at which time 5asses to 0.1, running in slowmo
Time.timeScale=0.1;
}
…thus proving that you don’t have to be Neo for bullet-time in Unity!
Step 6: Double-time!
Finally, for fun, let’s make everything go a little crazy by playing in double time. Although I haven’t seen this used in an actual game mechanic, I have seen time scaled temporarily to get a particle effect up and running – it was a fire effect and the author wanted the screen to be filled with fire quickly to bring the background of his menu screen to life. He scaled time up high for a second after the menu loaded and the fire filled the screen. He then reduced time back to 1 so that the flames moved correctly and everything else in the game was at regular speed.
To add double time, we’ll follow the same procedure as in Step 5, adding a new button that will call a new function. The new function will simply set our timeScale to 2. Find the OnGUI() function in your PauseScript.js script and add the following, above the end of the function and above the closing } curly brace.
// show a 'double time' button
if(GUI.Button(Rect(0,60,120,30),"DOUBLE TIME")){
// call our toggle function
doubleTime();
}
Right. We have a button, let’s add in that doubleTime() function:
function doubleTime () {
// set scale at which time passes to 0.5, running in slowmo
Time.timeScale=2;
}
For fun, try adjusting the timeScale up to 100 and see what happens.
Let’s take stock of our script. Here’s the PauseScript.js in full, just in case anything bad happened along the way:
function OnGUI() {
// show a 'pause' button
if(GUI.Button(Rect(0,0,120,30),"TOGGLE PAUSE")){
// call our toggle function
doPauseToggle();
}
// show a 'slowmo' button
if(GUI.Button(Rect(0,30,80,30),"SLOWMO")){
// call our toggle function
slowMo();
}
// show a 'double time' button
if(GUI.Button(Rect(0,60,120,30),"DOUBLE TIME")){
// call our toggle function
doubleTime();
}
}
function doPauseToggle() {
// here we check to see if we are running at a time scale above 0
if(Time.timeScale>0){
// time scale is above zero, so we need to pause the game here
pauseGame();
} else {
// time scale was less than zero, so we unpause the game here
unPauseGame();
}
}
function pauseGame () {
// set scale at which time passes to 0, freezing time(!)
Time.timeScale=0;
}
function unPauseGame () {
// set scale at which time passes to 1, running at realtime again
Time.timeScale=1;
}
function slowMo () {
// set scale at which time passes to 0.1, running in slowmo
Time.timeScale=0.1;
}
function doubleTime () {
// set scale at which time passes to 0.5, running in slowmo
Time.timeScale=2;
}
Final Words and a Couple of Gotchas!
It is important to note that Time.timeScale will not affect code within an Update() function. Update takes place every “tick” and it happens outside of time scale, so if you need things to happen as the game is paused, such as a background animation, the place to put it is most likely Update. Check the Unity documentation for more information on this.
Note that if you change the Time.timeScale value, any time-related actions such as calls to the Invoke function or any timers that use values from Time.time will also be affected by the change. If your game runs at twice the speed, you will have to halve the speed of your time-based actions (for example, if you have a racing game with a lap timer and your Time.timeScale is set to 2.0, you will need to slow down the lap timer by a half for it to accurately measure time).
Physics reactions are not directly affected, so your game should run as it normally would collisions and physics-wise – only on a different time scale.
That’s it! Thanks for reading my quick tip. Play around with Time.timeScale and I look forward to seeing cool Matrix-like effects in your projects. Have fun, making games!



View full post on Activetuts+
Jan 3, 2011
Posted on Jan 3, 2011 in Hints and Tips | 0 comments
In this Quick Tip we are going to be using the ColorMatrixFilter and BlurFilter to create a Motion Trail effect.
We found this awesome author thanks to FlashGameLicense.com, the place to buy and sell Flash games.
Final Result Preview
Let’s take a look at the final result we will be working towards:
Step 1: Create Project and Set It Up
Create a new Project in FlashDevelop (or whichever editor you use), set the dimensions of the swf to 600×400 and the background to black (#000000).
Next, to set up the scene we are going to have two Sprites, one is for the main display to which we will add all the display objects and the other is for the Motion Trail effect that uses the main display as a reference.
private var _mainDisplay:Sprite = new Sprite();
private var _mtDisplay:Sprite = new Sprite();
And add the Sprites to the Stage.
//
// Set up Displays
// We have to add our two displays to the Stage
addChild(_mtDisplay);
addChild(_mainDisplay);
Now we are going to embed our star image for use, or if you want use your own image.
[Embed(source = '../../images/star.png')]
var star:Class;
The final thing we want to do for the setup is create a loop function. This is going to be updated every frame, for things like positioning and updating the Motion Trail. So make another function and an event listener to call it every frame.
Your Main.as class should look something like this.
package rtmTrail
{
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite
{
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
//
// Load Images
[Embed(source = '../../images/star.png')]
var star:Class;
//
// Set up Displays
// We have to add our two displays to the stage
addChild(_mtDisplay);
addChild(_mainDisplay);
// Add a new Event Listener for our loop function whenever we enter
// the frame to move the sprites and update our MotionTrail Effect
addEventListener(Event.ENTER_FRAME, loop);
}
private function loop(e:Event):void
{
}
private var _mainDisplay:Sprite = new Sprite();
private var _mtDisplay:Sprite = new Sprite();
}
}
Step 2: Sprites & TextField
To test the Motion Trail we are going to create ten Sprites from the star image and position them in random places. Additionally we are going to create a Point that tells us the speed and direction they will move. The first thing to do is create two Arrays to store this information; one is for the Sprite and the other is for the Point.
private var _sprites:Array = new Array();
private var _spritesDir:Array = new Array();
private var _txt:TextField = new TextField();
Add this to the init function to randomly create and place ten stars.
// Draw some stars
var spr:Sprite;
var bmp:Bitmap;
for (var i:int = 0; i < 10; i++)
{
spr = new Sprite();
bmp = new star();
spr.addChild(bmp);
bmp.smoothing = true;
spr.x = Math.random() * 240 + 80;
spr.y = Math.random() * 240 + 80;
// We are going to add the new sprite into the _sprites Array and a
// Point that tells us where to move the sprite in the _spritesDir Array.
_sprites.push(spr);
_spritesDir.push(new Point(Math.random() * 6, Math.random() * 6));
// Last thing to do is add it to our main Display
_mainDisplay.addChild(spr);
}
Now to create the TextField add this.
// Add a Text Field Too
_txt.defaultTextFormat = new TextFormat("arial", 18, 0xFF00FF);
_txt.text = "Real Time Motion Trail"
_txt.x = 20;
_txt.y = 10;
_txt.width = 200;
_mainDisplay.addChild(_txt);
Step 3: Control Sprite Movement
Now we have to move into our loop function for Sprite movement control. Fairly simple, use a for loop to go through each Sprite we have and if it hits the edge inverse the x or y of the Point so it goes in the other direction. We’ll also have to move the sprite in the loop by the values in the Point and, to make it more interesting, slowly rotate it.
private function loop(e:Event):void
{
// Update the Sprite Shapes
for (var i:int = 0; i < _sprites.length; i++)
{
// Check to see if the shape is at or out of the
// outer bounds so we can change direction
if (_sprites[i].x <= 0 || _sprites[i].x >= 600) _spritesDir[i].x = -_spritesDir[i].x;
if (_sprites[i].y <= 0 || _sprites[i].y >= 400) _spritesDir[i].y = -_spritesDir[i].y;
// Move the Sprite Shape
_sprites[i].x += _spritesDir[i].x;
_sprites[i].y += _spritesDir[i].y;
// Rotate Sprite Shape
_sprites[i].rotation += 2;
}
}
To move the TextField across the top to the left we just have to subtract from the x property every frame, and if it goes off screen set it back to the right side of the screen.
private function loop(e:Event):void
{
// Update the Sprite Shapes
for (var i:int = 0; i < _sprites.length; i++)
{
// Check to see if the shape is at or out of the
// outer bounds so we can change direction
if (_sprites[i].x <= 0 || _sprites[i].x >= 600) _spritesDir[i].x = -_spritesDir[i].x;
if (_sprites[i].y <= 0 || _sprites[i].y >= 400) _spritesDir[i].y = -_spritesDir[i].y;
// Move the Sprite Shape
_sprites[i].x += _spritesDir[i].x;
_sprites[i].y += _spritesDir[i].y;
// Rotate Sprite Shape
_sprites[i].rotation += 2;
}
// Move Text
_txt.x -= 4
if (_txt.x < -200) _txt.x = 600;
}
Having tested it, you should have seen something like this (with the stars and text moving around the screen of course).
Step 4: Create the MotionTrail Class
Now it is time to make our MotionTrail Class. What this class is going to do is take a DisplayObject which is drawn to its own display (a Sprite) and using a couple filters, faded and blurred.
So make your new MotionTrail.as Class and let it extend the Sprite Class.
For a little pre-setup for the steps to come we are going to create a few variables, first the _display to store a reference of the Main Display, a BitmapData to draw to, a Rectangle the size of the stage and a Point in the top-left corner for the filters. Last up is an Array for the ColorMatrixFilter.
package rtmTrail
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.geom.Point;
import flash.geom.Rectangle;
public class MotionTrail extends Sprite
{
public function MotionTrail(display:DisplayObject)
{
// Reference to the display used for the motion trail
_display = display;
// Make a BitmapData Object to draw to
// If you want to use this for your own project and the dimensions isn't 600x400
// then you would have to change it here and the rectangle below
_bitmapData = new BitmapData(600, 400, true, 0x000000);
// Some Stuff that the filters need inputed for it to work
_rect = new Rectangle(0, 0, 600, 400);
_pnt = new Point(0, 0);
_cMatrix = new Array();
// Add a little transparency so it doesn't take attention away from the Main Display
alpha = 0.6;
addChild(new Bitmap(_bitmapData));
}
private var _display:DisplayObject;
private var _bitmapData:BitmapData;
private var _rect:Rectangle;
private var _pnt:Point;
private var _cMatrix:Array;
}
}
Since we made this class we have to go back real quick to the _mtDisplay variable and change it from the Sprite Class to the MotionTrail Class, along with inputting the _mainDisplay variable.
private var _mainDisplay:Sprite = new Sprite();
private var _mtDisplay:MotionTrail = new MotionTrail(_mainDisplay);
Step 5: ColorMatrixFilter Array
To create our Matrix for the ColorMatrixFilter, the basic idea is to fade the colors away so we slowly reduce all the values back to zero. Add this to the constructor.
// Create Matrix for ColorMatrixFilter
_cMatrix = _cMatrix.concat([0.92, 0, 0, 0, 0]) // Red
_cMatrix = _cMatrix.concat([0, 0.92, 0, 0, 0]) // Green
_cMatrix = _cMatrix.concat([0, 0, 0.92, 0, 0]) // Blue
_cMatrix = _cMatrix.concat([0, 0, 0, 0.92, 0]) // Alpha
This will multiply each value of every pixel by 0.92 and as it does this each frame it will get smaller and smaller till it basically reaches its limit at 0. So the closer the values are to 1.0 the longer it takes to reach zero, which means a longer trail (and vice versa: the closer to 0.0 the shorter the trail).
Step 6: ColorMatrixFilter and BlurFilter
Now we create the ColorMatrixFilter and the BlurFilter.
The ColorMatrixFilter is going to use the Array we just made and we are going to create two BlurFilters. I found that using two BlurFilters gives a nice pulse effect and it doesn’t blur too slow or too fast, but if you rather have one that’s fine too.
Add the variables for the filters first.
private var _cFilter:ColorMatrixFilter;
private var _bFilter:BlurFilter;
private var _bFilter2:BlurFilter;
Create the Filters in the constructor
_cFilter = new ColorMatrixFilter(_cMatrix);
_bFilter = new BlurFilter(2, 2, 1);
_bFilter2 = new BlurFilter(8, 8, 1);
Step 7: Updating MotionTrails
Now it is time to create a function to update our Motion Trails. Make a function called update in the MotionTrail Class. To make the trail we have to draw the Main Display to the BitmapData each frame which makes the trail effect.
public function update():void
{
// Draw Display onto BitmapData
_bitmapData.draw(_display);
}
You should now have a trail if you run it, but of course Motion Trails fade away and we will make it fade away with the filters we made in the last step.
Step 8: Applying Filters
Now we can apply the filters to the BitmapData. We use the same BitmapData for the source, the _rect and _pnt variables for the sourceRect and destPoint respectively, and last is the filter we want to apply.
Since we have a few filters we don’t want to apply all of them every frame because doing that would slow things down too much. Instead, we are going to switch the ColorMatrixFilter and BlurFilter to work in different frames and switch the BlurFilters the same way too.
To switch them around we are going to have a variable to keep track of the frame and use the module operator to check.
private var _count:Number = 0;
public function update():void
{
// Draw Display onto BitmapData
_bitmapData.draw(_display);
// Apply Effects to BitmapData
if (_count % 2 == 0)
_bitmapData.applyFilter(_bitmapData, _rect, _pnt, _cFilter);
else
if (_count % 4 == 1)
_bitmapData.applyFilter(_bitmapData, _rect, _pnt, _bFilter);
else
_bitmapData.applyFilter(_bitmapData, _rect, _pnt, _bFilter2);
// Increase Count
_count++;
}
Now that the update function is finished we add it to our loop function.
// Update Motion Blur
_mtDisplay.update();
Conclusion Testing and Extending
Awesome! We’re finished with this Quick Tip and you can go ahead and test it out.
You should have gotten the same result as the sample swf and now you can try extending it. There are lots of different effects you can make, most of it if you understand the ColorMatrixFilter.
For example, you could fade the color of the trail to red by doing this:
// Offset Red Value by 30 each time
_cMatrix = _cMatrix.concat([0.92, 0, 0, 0, 30]) // Red
_cMatrix = _cMatrix.concat([0, 0.92, 0, 0, 0]) // Green
_cMatrix = _cMatrix.concat([0, 0, 0.92, 0, 0]) // Blue
_cMatrix = _cMatrix.concat([0, 0, 0, 0.92, 0]) // Alpha
Or you could also switch the colors making all the trails blue:
// Only Blue trails
_cMatrix = _cMatrix.concat([0, 0, 0, 0, 0]) // Red
_cMatrix = _cMatrix.concat([0, 0, 0, 0, 0]) // Green
_cMatrix = _cMatrix.concat([0.92, 0.92, 0.92, 0, 0]) // Blue
_cMatrix = _cMatrix.concat([0, 0, 0, 0.92, 0]) // Alpha
Thanks for reading. I hope you all learned something from this and it will prove useful in the future, possibly a cool new game using this effect.



View full post on Activetuts+