Unity Manual
Welcome to Unity.
Unity is made to empower users to create the best interactive entertainment or multimedia experience that they can. This manual is designed to help you learn how to use Unity, from basic to advanced techniques. It can be read from start to finish or used as a reference.
The manual is divided into different sections. The first section, User Guide, is an introduction to Unity's interface, asset workflow, and the basics of building a game. If you are new to Unity, it is recommended that you start learning by reading the Unity Basics subsection.
The iOS Guide addresses iOS specific topics such as iOS-specific scripting API, optimizations, and general platform development questions.
The Android Guide addresses Android specific topics such as setting up the Android SDK and general development questions.
The next section, FAQ, is a collection of frequently asked questions about performing common tasks that require a few steps.
The last section, Advanced, addresses topics such as game optimization, shaders, file sizes, and deployment.
When you're done reading, be sure to take a look at the Reference Manual and the Scripting Reference for further details about the different possibilities of constructing your games with Unity.
If you find that any question you have is not answered in this manual please ask on Unity Answers or Unity Forums. You'll definitely find your answer there.
Happy reading,
The Unity team
The Unity Manual Guide contains sections that apply onto to certain platforms. Please select which platforms you want to see. Platform-specific information can always be seen by clicking on the disclosure triangles on each page.
Table of Contents
- User Guide
- Unity Basics
- Building Scenes
- Asset Import and Creation
- Creating Gameplay
- Getting Started with iOS Development
- Unity iOS Basics
- Unity Remote
- iOS Scripting
- iOS Hardware Guide
- Optimizing Performance in iOS.
- Account Setup
- Features currently not supported by Unity iOS
- Building Plugins for iOS
- Preparing your application for "In App Purchases"
- Customizing the Splash screen of Your Mobile Application
- Trouble Shooting
- Reporting crash bugs on iOS
- Getting Started with Android Development
- Getting Started with Native Client Development
- Getting Started with Flash Development
- FAQ
- Unity 3.5 upgrade guide
- Upgrading your Unity Projects from 2.x to 3.x
- Activation
- Game Code Questions
- Graphics Questions
- How do I Import Alpha Textures?
- How do I Use Normal Maps?
- How do I use Detail Textures?
- How do I Make a Cubemap Texture?
- How do I Make a Skybox?
- How do I make a Mesh Particle Emitter? (Legacy Particle System)
- How do I make a Splash Screen?
- How do I make a Spot Light Cookie?
- How do I fix the rotation of an imported model?
- How do I use Water?
- HOWTO-exportFBX
- HOWTO-ArtAssetBestPracticeGuide
- How do I import objects from my 3D app?
- Workflow Questions
- Advanced
- Vector Cookbook
- AssetBundles (Pro only)
- AssetDatabase
- Build Player Pipeline
- Rendering Paths
- Profiler (Pro only)
- Lightmapping Quickstart
- HDR (High Dynamic Range)
- Linear Lighting (Pro Only)
- Occlusion Culling (Pro only)
- Level of Detail (Pro Only)
- Camera Tricks
- Loading Resources at Runtime
- Modifying Source Assets Through Scripting
- Generating Mesh Geometry Procedurally
- Using Mono DLLs in a Unity Project
- Execution Order of Event Functions
- Optimizing Graphics Performance
- Reducing File Size
- Understanding Automatic Memory Management
- Platform Dependent Compilation
- Generic Functions
- Debugging
- Plugins (Pro/Mobile-Only Feature)
- Textual Scene File Format (Pro-only Feature)
- Streaming Assets
- Command line arguments
- Running Editor Script Code on Launch
- Shaders
- Graphics Emulation
- Network Emulation
- Security Sandbox of the Webplayer
- Overview of available .NET Class Libraries
- Visual Studio C# Integration
- Using External Version Control Systems with Unity
- Analytics
- Check For Updates
- Trouble Shooting
User Guide
This section of the Manual is focused on the features and functions of Unity. It discusses the interface, core Unity building blocks, asset workflow, and basic gameplay creation. By the time you are done reading the user guide, you will have a solid understanding of how to use Unity to put together an interactive scene and publish it.
We recommend that new users begin by reading the Unity Basics section.
- Unity Basics
- Building Scenes
- Asset Import and Creation
- Creating Gameplay
Unity Basics
This section is your key to getting started with Unity. It will explain the Unity interface, menu items, using assets, creating scenes, and publishing builds.
When you are finished reading this section, you will understand how Unity works, how to use it effectively, and the steps to put a basic game together.
|
|
Learning the Interface
First Launch
Let's begin learning Unity. If you have not yet opened Unity, you can find it inside on Windows, or on Mac. The Unity Editor will appear. Take your time to look over the Unity Editor interface and familiarize yourself with it. The Main Editor Window is made up of several Tabbed Windows, called Views. There are several types of Views in Unity, each with a specific purpose.

Project View

Every Unity project contains an Assets folder. The contents of this folder are presented in the Project View. This is where you store all the assets that make up your game, like scenes, scripts, 3D models, textures, audio files, and Prefabs. If you right-click on any asset in the Project View, you can choose ( on Mac) to actually see the asset itself in your file system.
Important Note: You should never move project assets around using the OS since this will break any metadata associated with the asset. Always use the Project View to organize your assets.
To add assets to your project, you can drag any file from your OS into the Project View, or use . Your asset is now ready to be used in your game. For more information about working with assets, skip ahead to the Asset Workflow section of the manual.
Scenes are also stored in the Project View. Think of these as individual levels. For example, the Islands Scene loads by default when Unity first launches. To create a new Scene, use ( on Mac). To save the current Scene into the Project View, use ( on Mac).
Some game assets need to be created from within Unity. To do this, use the drop-down, or .

The Create drop-down
This will allow you to add scripts, Prefabs, or folders to keep your project organized. You can rename any asset/folder by pressing on Windows, or on Mac, or with two paced clicks on the asset name. If you hold the key while you expand or contract a directory, all subdirectories will also be expanded or contracted.
Hierarchy

The Hierarchy contains every GameObject in the current Scene. Some of these are direct instances of asset files like 3D models, and others are instances of Prefabs -- custom objects that will make up much of your game. You can select and Parent objects in the Hierarchy. As objects are added and removed from the scene, they will appear and disappear from the Hierarchy as well.
Parenting
Unity uses a concept called Parenting. To make any GameObject the child of another, drag the desired child onto the desired parent in the Hierarchy. A child will inherit the movement and rotation of its parent. You can now expand and contract the parent to see its children in the Hierarchy without affecting your game.

Two unparented objects

One object parented to another
To learn more about Parenting, please review the Parenting section of the Transform Component page.
Toolbar

The Toolbar consists of five basic controls. Each relate to different parts of the Editor.
Transform Tools -- used with the Scene View
Transform Gizmo Toggles -- affect the Scene View display
Play/Pause/Step Buttons -- used with the Game View
Layers Drop-down -- controls which objects are displayed in Scene View
Layout Drop-down -- controls arrangement of all ViewsScene View

The Scene View
The Scene View is your interactive sandbox. You will use the Scene View to select and position environments, the player, the camera, enemies, and all other GameObjects. Maneuvering and manipulating objects within the Scene View are some of the most important functions in Unity, so it's important to be able to do them quickly.
Scene View Navigation
See Scene View Navigation for full details on navigating the scene view. Here's a brief overview of the essentials:
- Hold the right mouse button to enter Flythrough mode. This turns your mouse and keys (plus and for up and down) into quick first-person view navigation.
- Select any GameObject and press the key. This will center the Scene View and pivot point on the selection.
- Use the arrow keys to move around on the X/Z plane.
- Hold and click-drag to orbit the camera around the current pivot point.
- Hold and middle click-drag to drag the Scene View camera around.
- Hold and right click-drag to zoom the Scene View. This is the same as scrolling with your mouse wheel.
You might also find use in the Hand Tool (shortcut: ), especially if you are using a one-button mouse. With the Hand tool is selected,
Click-drag to drag the camera around.
Hold and click-drag to orbit the camera around the current pivot point.
Hold ( on Mac) and click-drag to zoom the camera.In the upper-right corner of the Scene View is the Scene Gizmo. This displays the Scene Camera's current orientation, and allows you to quickly modify the viewing angle.

You can click on any of the arms to snap the Scene Camera to that direction and change it to Isometric Mode. While in Isometric Mode, you can right-click drag to orbit, and Alt-click drag to pan. To exit this mode, click the middle of the Scene Gizmo. You can also Shift-click the middle of the Scene Gizmo any time to toggle Isometric Mode.
Positioning GameObjects
See Positioning GameObjects for full details on positioning GameObjects in the scene. Here's a brief overview of the essentials:
When building your games, you'll place lots of different objects in your game world. To do this use the Transform Tools in the Toolbar to Translate, Rotate, and Scale individual GameObjects. Each has a corresponding Gizmo that appears around the selected GameObject in the Scene View. You can use the mouse and manipulate any Gizmo axis to alter the Transform Component of the GameObject, or you can type values directly into the number fields of the Transform Component in the Inspector.

Scene View Control Bar

The Scene View control bar lets you see the scene in various view modes - Textured, Wireframe, RGB, Overdraw, and many others. It will also enable you to see (and hear) in-game lighting, game elements, and sound in the Scene View. See View Modes for all the details.
Game View

The Game View is rendered from the Camera(s) in your game. It is representative of your final, published game. You will need to use one or more Cameras to control what the player actually sees when they are playing your game. For more information about Cameras, please view the Camera Component page.
Play Mode

Use the buttons in the Toolbar to control the Editor Play Mode and see how your published game will play. While in Play mode, any changes you make are temporary, and will be reset when you exit Play mode. The Editor UI will darken to remind you of this.
Game View Control Bar

The first drop-down on the Game View control bar is the Aspect Drop-down. Here, you can force the aspect ratio of the Game View window to different values. It can be used to test how your game will look on monitors with different aspect ratios.
Further to the right is the toggle. While enabled, the Game View will maximize itself to 100% of your Editor Window for a nice full-screen preview when you enter Play mode.
Continuing to the right is the toggle. While enabled, all Gizmos that appear in Scene View will also be drawn in Game View. This includes Gizmos drawn using any of the Gizmos class functions.
Finally we have the button. This shows Rendering Statistics window that is very useful for Optimizing Graphics Performance.

Game View Stats of your game.
Inspector

Games in Unity are made up of multiple GameObjects that contain meshes, scripts, sounds, or other graphical elements like Lights. The Inspector displays detailed information about your currently selected GameObject, including all attached Components and their properties. Here, you modify the functionality of GameObjects in your scene. You can read more about the GameObject-Component relationship, as it is very important to understand.
Any property that is displayed in the Inspector can be directly modified. Even script variables can be changed without modifying the script itself. You can use the Inspector to change variables at runtime to experiment and find the magic gameplay for your game. In a script, if you define a public variable of an object type (like GameObject or Transform), you can drag and drop a GameObject or Prefab into the Inspector to make the assignment.

Click the question mark beside any Component name in the Inspector to load its Component Reference page. Please view the Component Reference for a complete and detailed guide to all of Unity's Components.

Add Components from the menu
You can click the tiny gear icon (or right-click the Component name) to bring up a context menu for the specific Component.

The Inspector will also show any Import Settings for a selected asset file.

Click to reimport your asset.

Use the drop-down to assign a rendering Layer to the GameObject. Use the drop-down to assign a Tag to this GameObject.
Prefabs
If you have a Prefab selected, some additional buttons will be available in the Inspector. For more information about Prefabs, please view the Prefab manual page.
Other Views
The Views described on this page covers the basics of the interface in Unity. The other Views in Unity are described elsewhere on separate pages:
- The Console shows logs of messages, warnings, and errors.
- The Animation View can be used to animate objects in the scene.
- The Profiler can be used to investigate and find the performance bottle-necks in your game.
- The Asset Server View can be used to manage version control of the project using Unity's Asset Server.
- The Lightmapping View can be used to manage lightmaps using Unity's built-in lightmapping.
- The Occlusion Culling View can be used to manage Occlusion Culling for improved performance.
Customizing Your Workspace
Customizing Your Workspace
You can customize your Layout of Views by click-dragging the Tab of any View to one of several locations. Dropping a Tab in the Tab Area of an existing window will add the Tab beside any existing Tabs. Alternatively, dropping a Tab in any Dock Zone will add the View in a new window.

Views can be docked to the sides or bottom of any existing window
Tabs can also be detached from the Main Editor Window and arranged into their own floating Editor Windows. Floating Windows can contain arrangements of Views and Tabs just like the Main Editor Window.

Floating Editor Windows are the same as the Main Editor Window, except there is no Toolbar
When you've created a Layout of Editor Windows, you can Save the layout and restore it any time. You do this by expanding the Layout drop-down (found on the Toolbar) and choosing . Name your new layout and save it, then restore it by simply choosing it from the Layout drop-down.

A completely custom Layout
At any time, you can right-click the tab of any view to view additional options like Maximize or add a new tab to the same window.

Asset Workflow
Here we'll explain the steps to use a single asset with Unity. These steps are general and are meant only as an overview for basic actions. For the example, we'll talk about using a 3D mesh.
Create Rough Asset
Use any supported 3D modeling package to create a rough version of your asset. Our example will use Maya. Work with the asset until you are ready to save. For a list of applications that are supported by Unity, please see this page.
Import
When you save your asset initially, you should save it normally to the Assets folder in your Project folder. When you open the Unity project, the asset will be detected and imported into the project. When you look in the Project View, you'll see the asset located there, right where you saved it. Please note that Unity uses the FBX exporter provided by your modeling package to convert your models to the FBX file format. You will need to have the FBX exporter of your modeling package available for Unity to use. Alternatively, you can directly export as FBX from your application and save in the Projects folder. For a list of applications that are supported by Unity, please see this page.
Import Settings
If you select the asset in the Project View the import settings for this asset will appear in the Inspector. The options that are displayed will change based on the type of asset that is selected.
Adding Asset to the Scene
Simply click and drag the mesh from the Project View to the Hierarchy or Scene View to add it to the Scene. When you drag a mesh to the scene, you are creating a GameObject that has a Mesh Renderer Component. If you are working with a texture or a sound file, you will have to add it to a GameObject that already exists in the Scene or Project.
Putting Different Assets Together
Here is a brief description of the relationships between the most common assets
- A Texture is applied to a Material
- A Material is applied to a GameObject (with a Mesh Renderer Component)
- An Animation is applied to a GameObject (with an Animation Component)
- A sound file is applied to a GameObject (with an Audio Source Component)
Creating a Prefab
Prefabs are a collection of GameObjects & Components that can be re-used in your scenes. Several identical objects can be created from a single Prefab, called instancing. Take trees for example. Creating a tree Prefab will allow you to instance several identical trees and place them in your scene. Because the trees are all linked to the Prefab, any changes that are made to the Prefab will automatically be applied to all tree instances. So if you want to change the mesh, material, or anything else, you just make the change once in the Prefab and all the other trees inherit the change. You can also make changes to an instance, and choose from the main menu. This can save you lots of time during setup and updating of assets.
When you have a GameObject that contains multiple Components and a hierarchy of child GameObjects, you can make a Prefab of the top-level GameObject (or root), and re-use the entire collection of GameObjects.
Think of a Prefab as a blueprint for a structure of GameObjects. All the Prefab clones are identical to the blueprint. Therefore, if the blueprint is updated, so are all the clones. There are different ways you can update the Prefab itself by changing one of its clones and applying those changes to the blueprint. To read more about using and updating Prefabs, please view the Prefabs page.
To actually create a Prefab from a GameObject in your scene, first create a new Prefab in your Project View. Name the new Prefab whatever you like. Then, click on the Game Object in the scene that you want to make into a Prefab. Drag it to the new Prefab, and you should see the Game Object's name text turn blue. You have now created a re-usable prefab.
Updating Assets
You have imported, instantiated, and linked your asset to a Prefab. Now when you want to edit your source asset, just double-click it from the Project View. The appropriate application will launch, and you can make any changes you want. When you're done updating it, just Save it. Then, when you switch back to Unity, the update will be detected, and the asset will be re-imported. The asset's link to the Prefab will also be maintained. So the effect you will see is that your Prefab will update. That's all you have to know to update assets. Just open it and save!
Optional - Adding Labels to the Assets.
Is always a good idea to add labels to your assets if you want to keep organized all your assets, with this you can search for the labels associated to each asset in the search field in the project view or in the object selector.
Steps for adding a label to an asset:
- Select the asset you want to add the label to (From the project view).
- In the inspector click on the "Add Label" icon (
) if you dont have any Labels associated to that asset.
- If you have a label associated to an asset then just click where the labels are.
- Start writing your labels.
Notes:
- You can have more than one label for any asset.
- To separate/create labels, just press space or enter when writing asset label names.
Creating Scenes
Scenes contain the objects of your game. They can be used to create a main menu, individual levels, and anything else. Think of each unique Scene file as a unique level. In each Scene, you will place your environments, obstacles, and decorations, essentially designing and building your game in pieces.
Instancing Prefabs
Use the method described in the last section to create a Prefab. You can also read more details about Prefabs here. Once you've created a Prefab, you can quickly and easily make copies of the Prefab, called an Instance. To create an instance of any Prefab, drag the Prefab from the Project View to the Hierarchy or Scene View. Now you have a unique instance of your Prefab to position and tweak as you like.
Adding Component & Scripts
When you have a Prefab or any GameObject highlighted, you can add additional functionality to it by using Components. Please view the Component Reference for details about all the different Components. Scripts are a type of Component. To add a Component, just highlight your GameObject and select a Component from the menu. You will then see the Component appear in the Inspector of the GameObject. Scripts are also contained in the menu by default.
If adding a Component breaks the GameObject's connection to its Prefab, you can always use from the menu to re-establish the link.
Placing GameObjects
Once your GameObject is in the scene, you can use the Transform Tools to position it wherever you like. Additionally, you can use the Transform values in the Inspector to fine-tune placement and rotation. Please view the Transform Component page for more information about positioning and rotating GameObjects.
Working with Cameras
Cameras are the eyes of your game. Everything the player will see when playing is through one or more cameras. You can position, rotate, and parent cameras just like any other GameObject. A camera is just a GameObject with a Camera Component attached to it. Therefore it can do anything a regular GameObject can do, and then some camera-specific functions too. There are also some helpful Camera scripts that are installed with the standard assets package when you create a new project. You can find them in from the menu. There are some additional aspects to cameras which will be good to understand. To read about cameras, view the Camera component page.
Lights
Except for some very few cases, you will always need to add Lights to your scene. There are three different types of lights, and all of them behave a little differently from each other. The important thing is that they add atmosphere and ambience to your game. Different lighting can completely change the mood of your game, and using lights effectively will be an important subject to learn. To read about the different lights, please view the Light component page.
Page last updated: 2009-02-16Publishing Builds
At any time while you are creating your game, you might want to see how it looks when you build and run it outside of the editor as a standalone or web player. This section will explain how to access the Build Settings and how to create different builds of your games.
is the menu item to access the Build Settings window. It pops up an editable list of the scenes that will be included when you build your game.

The Build Settings window
The first time you view this window in a project, it will appear blank. If you build your game while this list is blank, only the currently open scene will be included in the build. If you want to quickly build a test player with only one scene file, just build a player with a blank scene list.
It is easy to add scene files to the list for multi-scene builds. There are two ways to add them. The first way is to click the button. You will see the currently open scene appear in the list. The second way to add scene files is to drag them from the Project View to the list.
At this point, notice that each of your scenes has a different index value. Scene 0 is the first scene that will be loaded when you build the game. When you want to load a new scene, use Application.LoadLevel() inside your scripts.
If you've added more than one scene file and want to rearrange them, simply click and drag the scenes on the list above or below others until you have them in the desired order.
If you want to remove a scene from the list, click to highlight the scene and press . The scene will disappear from the list and will not be included in the build.
When you are ready to publish your build, select a Platform and make sure that the Unity logo is next to the platform; if its not then click in the button to let Unity know which platform you want to build for. Finally press the button. You will be able to select a name and location for the game using a standard Save dialog. When you click , Unity builds your game pronto. It's that simple. If you are unsure where to save your built game to, consider saving it into the projects root folder. You cannot save the build into the Assets folder.
Enabling the Development Build checkbox on a player will enable Profiler functionality and also make the Autoconnect Profiler and Script Debugging options available.
Desktop
Web Player Streaming
Streaming Web Players allow your Web Player games to begin playing as soon as Scene 0 is finished loading. If you have a game with 10 levels, it doesn't make much sense to force the player to wait and download all assets for levels 2-10 before they can start playing level 1. When you publish a Streaming Web Player, the assets that must be downloaded will be sequenced in the order of the Scene file they appear in. As soon as all assets contained in Scene 0 are finished downloading, the Web Player will begin playing.
Put simply, Streaming Web Players will get players playing your game faster than ever.
The only thing you need to worry about is checking to make sure that the next level you want to load is finished streaming before you load it.
Normally, in a non-streamed player, you use the following code to load a level:
Application.LoadLevel("levelName");
In a Streaming Web Player, you must first check that the level is finished streaming. This is done through the CanStreamedLevelBeLoaded() function. This is how it works:
var levelToLoad = 1;
function LoadNewLevel () {
if (Application.CanStreamedLevelBeLoaded (levelToLoad)) {
Application.LoadLevel (levelToLoad);
}
}
If you would like to display the level streaming progress to the player, for a loading bar or other representation, you can read the progress by accessing GetStreamProgressForLevel().
Offline webplayer deployment
If the Offline Deployment option is enabled for a webplayer then the UnityObject.js file (used to interface the player with the host page) will be placed alongside the player during the build. This enables the player to work with the local script file even when there is no network connection; normally, UnityObject.js is downloaded from Unity's webserver so as to make use of the latest version.
Building standalone players
With Unity you can build standalone applications for Windows and Mac (Intel, PowerPC or Universal, which runs on both architectures). It's simply a matter of choosing the build target in the build settings dialog, and hitting the 'Build' button. When building standalone players, the resulting files will vary depending on the build target. On Windows an executable file (.exe) will be built, along with a Data folder which contains all the resources for your application. On Mac an app bundle will be built, containing the file needed to run the application, as well as the resources.
Distributing your standalone on Mac is just to provide the app bundle (everything is packed in there). On Windows you need to provide both the .exe file and the Data folder for others to run it. Think of it like this: Other people must have the same files on their computer, as the resulting files that Unity builds for you, in order to run your game.
Inside the build process
The building process will place a blank copy of the built game application wherever you specify. Then it will work through the scene list in the build settings, open them in the editor one at a time, optimize them, and integrate them into the application package. It will also calculate all the assets that are required by the included scenes and store that data in a separate file within the application package.
- Any GameObject in a scene that is tagged with 'EditorOnly' will be not be included in the published build. This is useful for debugging scripts that don't need to be included in the final game.
- When a new level loads, all the objects in the previous level are destroyed. To prevent this, use DontDestroyOnLoad() on any objects you don't want destroyed. This is most commonly used for keeping music playing while loading a level, or for game controller scripts which keep game state and progress.
- After the loading of a new level is finished, the message: OnLevelWasLoaded() will be sent to all active game objects.
- For more information on how to best create a game with multiple scenes, for instance a main menu, a high-score screen, and actual game levels, see the Scripting Tutorial.pdf
iOS
Inside the iOS build process
The iPhone/iPad application build process is a two step process:
- XCode project is generated with all the required libraries, precompiled .NET code and serialized assets.
- XCode project is built and deployed on the actual device.
When "Build" is hit on "Build settings" dialog only the first step is accomplished. Hitting "Build and Run" performs both steps. If in the project save dialog the user selects an already existing folder an alert is displayed. Currently there are two XCode project generation modes to select:
- replace - all the files from target folder are removed and the new content is generated
- append - the "Data", "Libraries" and project root folder are cleaned and filled with newly generated content. The XCode project file is updated according to the latest Unity project changes. XCode project "Classes" subfolder could be considered as safe place to place custom native code, but making regular backups is recommended. Append mode is supported only for the existing XCode projects generated with the same Unity iOS version.
If Cmd+B is hit then the automatic build and run process is invoked and the latest used folder is assumed as the build target. In this case append mode is assumed as default.
Android
The Android application build process is performed in two steps:
- Application package (.apk file) is generated with all the required libraries and serialized assets.
- Application package is deployed on the actual device.
When "Build" is hit on "Build settings" dialog only the first step is accomplished. Hitting "Build and Run" performs both steps. If Cmd+B is hit then the automatic build and run process is invoked and the latest used file is assumed as the build target.
Upon the first attempt to build an Android project, Unity would ask you to locate the Android SDK, that is required to build and install your Android application on the device. You can change this setting later in .

When building the app to the Android, be sure that the device has the "USB Debugging" and the "Allow mock locations" checkboxes checked in the device settings.

You can ensure that the operating system sees your device by running adb devices command found in your Android SDK/platform-tools folder.
This should work both for Mac and Windows.

Unity builds an application archive (.apk file) for you and installs it on the connected device. In some cases your application cannot autostart like on iPhone, so you need to unlock the screen, and in some rare cases find the newly installed application in the menu.
Texture Compression
Under Build Settings you'll also find the option. By default, Unity uses ETC1/RGBA16 texture format for textures that don't have individual texture format overrides (see Texture 2D / Per-Platform Overrides).
If you want to build an application archive (.apk file) targeting a specific hardware architecture, you can use the option to override this default behavior. Any texture that is set to not be compressed will be left alone; only textures using a compressed texture format will use the format selected in the option.
To make sure the application is only deployed on devices which support the selected texture compression, Unity will edit the AndroidManifest to include tags matching the particular format selected. This will enable the Android Market filtering mechanism to only serve the application to devices with the appropriate graphics hardware.
Preloading
Published builds automatically preload all assets in a scene when the scene loads. The exception to this rule is scene 0. This is because the first scene is usually a splashscreen, which you want to display as quickly as possible.
To make sure all your content is preloaded, you can create an empty scene which calls Application.LoadLevel(1). In the build settings make this empty scene's index 0. All subsequent levels will be preloaded.
You're ready to build games
By now, you have learned how to use Unity's interface, how to use assets, how to create scenes, and how to publish your builds. There is nothing stopping you from creating the game of your dreams. You'll certainly learn much more along the way, and we're here to help.
To learn more details about using Unity itself, you can continue reading the manual or follow the Tutorials.
To learn more about Components, the nuts & bolts of game behaviors, please read the Component Reference.
To learn more about Scripting, please read the Scripting Reference.
To learn more about creating Art assets, please read the Assets section of the manual.
To interact with the community of Unity users and developers, visit the Unity Forums. You can ask questions, share projects, build a team, anything you want to do. Definitely visit the forums at least once, because we want to see the amazing games that you make.
Page last updated: 2011-10-31Tutorials
These tutorials will let you work with Unity while you follow along. They will give you hands-on experience with building real projects. For new users, it is recommended that you follow the GUI Essentials and Scripting Essentials tutorials first. After that, you can follow any of them. They are all in PDF format, so you can print them out and follow along or read them alongside Unity.
Note: These Tutorials are intended for use with the Desktop version of Unity, these will not work with Android or iOS devices (iPhone/iPad).
Also if you are searching for other resources like presentations, articles, assets or extensions for Unity, then you can find them here.
You can also check the latest additions about tutorials just by checking our Unity3D Tutorial's Home Page.
Page last updated: 2010-09-10Unity Hotkeys
This page gives an overview of the default Unity Hotkeys Click the image to download a printable PDF
Page last updated: 2011-07-20Preferences
Unity provides a number of preference panels to allow you to customise the behaviour of the editor.
General

| Auto Refresh | Should the editor update assets automatically as they change? |
| Always Show Project Wizard | Should the project wizard be shown at startup? (By default, it is shown only when the alt key is held down during launch) |
| Compress Assets On Import | Should assets be compressed automatically during import? |
| OSX Color Picker | Should the native OSX color picker be used instead of Unity's own? |
| Editor Analytics | Can the editor send information back to Unity automatically? |
| Verify Saving Assets | Should Unity verify which assets to save individually on quitting? |
| Skin (Pro Only) | Which color scheme should Unity use for the editor? Pro users have the option of dark grey in addition to the default light grey. |
External Tools

| External Script Editor | Which application should Unity use to open script files? |
| Editor Attaching | Should Unity allow debugging to be controlled from the external script editor? |
| Image Application | Which application should Unity use to open image files? |
| Asset Server Diff Tool | Which application should Unity use to resolve file differences with the asset server? |
| Android SDK Location | Where in the filesystem is the Android SDK folder located? |
| iOS Xcode 4.x support | Should support for Xcode 4.x be enabled for iOS build targets? |
Colors

This panel allows you to choose the colors that Unity uses when displaying various user interface elements.
Keys

This panel allows you to set the keystrokes that activate the various commands in Unity.
Cache Server

| Use Cache Server | Should the cache server be enabled? |
| IP Address | IP address of the cache server, if enabled |
Building Scenes
This section will explain the core elements you will work with to build scenes for complete games.
- GameObjects
- Using the Inspector
- Using the Scene View
- Searching
- Prefabs
- Lights
- Cameras
- Terrain Engine Guide
GameObjects
GameObjects are the most important objects in Unity. It is very important to understand what a GameObject is, and how it can be used. This page will explain all that for you.
What are GameObjects?
Every object in your game is a GameObject. However, GameObjects don't do anything on their own. They need special properties before they can become a character, an environment, or a special effect. But every one of these objects does so many different things. If every object is a GameObject, how do we differentiate an interactive power-up object from a static room? What makes these GameObjects different from each other?
The answer to this question is that GameObjects are containers. They are empty boxes which can hold the different pieces that make up a lightmapped island or a physics-driven car. So to really understand GameObjects, you have to understand these pieces; they are called Components. Depending on what kind of object you want to create, you will add different combinations of Components to the GameObject. Think of a GameObject as an empty cooking pot, and Components as different ingredients that make up your recipe of gameplay. You can also make your own Components using Scripts.
You can read more about GameObjects, Components, and Script Components on the pages in this section:
Page last updated: 2010-09-14The GameObject-Component Relationship
As described on the GameObjects page, a GameObject contains Components. We'll explore this relationship by discussing a GameObject and its most common Component -- the Transform Component. With any Unity Scene open, create a new GameObject (using on Windows or on Mac), select it and take a look at the Inspector.

The Inspector of an Empty GameObject
Notice that an empty GameObject still contains a Name, a Tag, and a Layer. Every GameObject also contains a Transform Component.
The Transform Component
It is impossible to create a GameObject in Unity without a Transform Component. The Transform Component is one of the most important Components, since all of the GameObject's Transform properties are enabled by its use of this Component. It defines the GameObject's position, rotation, and scale in the game world/Scene View. If a GameObject did not have a Transform Component, it would be nothing more than some information in the computer's memory. It effectively would not exist in the world.
The Transform Component also enables a concept called Parenting, which is utilized through the Unity Editor and is a critical part of working with GameObjects. If you would like to learn more about the Transform Component and Parenting, please read the Transform Component Reference page.
Other Components
The Transform Component just happens to be critical to all GameObjects, so each GameObject has one. But GameObjects can contain other Components as well.

The Main Camera, added to each scene by default
Taking a look at the Main Camera GameObject, we can see that it contains a different collection of Components. Specifically, a Camera Component, a GUILayer, a Flare Layer, and an Audio Listener. All of these Components provide additional functionality to the GameObject. Without them, there would be nothing rendering the graphics of the game for the person playing! Rigidbodies, Colliders, Particles, and Audio are all different Components (or combinations thereof) that can be added to any given GameObject.
Page last updated: 2010-09-14Using Components
Components are the nuts & bolts of objects and behaviors in a game. They are the functional pieces of every GameObject. If you don't yet understand the relationship between Components and GameObjects, we recommend that you read the GameObjects page before going any further.
A GameObject is a container for many different Components. By default, all GameObjects automatically have a Transform Component. This is because the Transform dictates where the GameObject is located, and how it is rotated and scaled. Without a Transform Component, the GameObject wouldn't have a location in the world. Try creating an empty GameObject now as an example. Click the menu item. Select the new GameObject, and look at the Inspector.

Even empty GameObjects have a Transform Component
Remember that you can always use the Inspector to see which Components are attached to the selected GameObject. As Components are added and removed, the Inspector will always show you which ones are currently attached. You will use the Inspector to change all the properties of any Component (including scripts)
Adding Components
You can add Components to the selected GameObject through the Components menu. We'll try this now by adding a Rigidbody to the empty GameObject we just created. Select it and choose from the menu. When you do, you will see the Rigidbody's properties appear in the Inspector. If you press Play while the empty GameObject is still selected, you might get a little surprise. Try it and notice how the Rigidbody has added functionality to the otherwise empty GameObject. (The y-component of the GameObject starts to decrease. This is because the physics engine in Unity is causing the GameObject to fall under gravity.)

An empty GameObject with a Rigidbody Component attached
You can attach any number or combination of Components to a single GameObject. Some Components work best in combination with others. For example, the Rigidbody works with any Collider. The Rigidbody controls the Transform through the NVIDIA PhysX physics engine, and the Collider allows the Rigidbody to collide and interact with other Colliders. A different example of Component combinations is a Particle System. They use a Particle Emitter, Particle Animator, and Particle Renderer to create a group of moving particles.
If you want to know more about using a particular Component, you can read about any of them in the Component Reference. You can also access the reference page for a Component from Unity by clicking on the small ? on the Component's header in the Inspector.
Editing Components
One of the great aspects of Components is flexibility. When you attach a Component to a GameObject, there are different values or Properties in the Component that can be adjusted in the editor while building a game, or by scripts when running the game. There are two main types of Properties: Values and References.
Look at the image below. It is an empty GameObject with an Audio Source Component. All the values of the Audio Source in the Inspector are the default values.

This Component contains a single Reference property, and seven Value properties. Audio Clip is the Reference property. When this Audio Source begins playing, it will attempt to play the audio file that is referenced in the Audio Clip property. If no reference is made, an error will occur because there is no audio to be played. You must reference the file within the Inspector. This is as easy as dragging an audio file from the Project View onto the Reference Property or using the Object Selector.

Now a sound effect file is referenced in the Audio Clip property
Components can include references to any other type of Component, GameObjects, or Assets. You can read more about assigning references on the Assigning References page.
The remaining properties on the Audio Clip are all Value properties. These can be adjusted directly in the Inspector. The Value properties on the Audio Clip are all toggles, numeric values, drop-down fields, but value properties can also be text strings, colors, curves, and other types. You can read more about these and about editing value properties on the Editing Value Properties page.
Testing out Properties
While your game is in Play Mode, you are free to change properties in any GameObject's Inspector. For example, you might want to experiment with different heights of jumping. If you create a Jump Height property in a script, you can enter Play Mode, change the value, and press the jump button to see what happens. Then without exiting Play Mode you can change it again and see the results within seconds. When you exit Play Mode, your properties will revert to their pre-Play Mode values, so you don't lose any work. This workflow gives you incredible power to experiment, adjust, and refine your gameplay without investing a lot of time in iteration cycles. Try it out with any property in Play Mode. We think you'll be impressed.
Removing Components
If you want to remove a Component, option- or right-click on its header in the Inspector, and choose . Or you can left-click the options icon next to the ? on the Component header. All the property values will be lost and this cannot be undone, so be completely sure you want to remove the Component before you do.
Page last updated: 2010-09-14The Component-Script Relationship
When you create a script and and attach it to a GameObject, the script appears in the GameObject's Inspector just like a Component. This is because scripts become Components when they are saved - a script is just a specific type of Component. In technical terms, a script compiles as a type of Component, and is treated like any other Component by the Unity engine. So basically, a script is a Component that you are creating yourself. You will define its members to be exposed in the Inspector, and it will execute whatever functionality you've written.
Read more about creating and using scripts on the Scripting page.
Page last updated: 2010-09-14Using The Inspector
The Inspector is used to view and edit Properties of many different types.
Games in Unity are made up of multiple GameObjects that contain meshes, scripts, sounds, or other graphical elements like Lights. When you select a GameObject in the Hierarchy or Scene View, the Inspector will show and let you modify the Properties of that GameObject and all the Components and Materials on it. The same will happen if you select a Prefab in the Project View. This way you modify the functionality of GameObjects in your game. You can read more about the GameObject-Component relationship, as it is very important to understand.

Inspector shows the properties of a GameObject and the Components and Materials on it.
When you create a script yourself, which works as a custom Component type, the member variables of that script are also exposed as Properties that can be edited directly in the Inspector when that script component has been added to a GameObject. This way script variables can be changed without modifying the script itself.
Furthermore, the Inspector is used for showing import options of assets such as textures, 3D models, and fonts when selected. Some scene and project-wide settings are also viewed in the Inspector, such as all the Settings Managers.
Any property that is displayed in the Inspector can be directly modified. There are two main types of Properties: Values and References.
Page last updated: 2010-09-13Editing Value Properties
Value properties do not reference anything and they can be edited right on the spot. Typical value properties are numbers, toggles, strings, and selection popups, but they can also be colors, vectors, curves, and other types.

Value properties on the inspector can be numbers, checkboxes, strings...
Many value properties have a text field and can be adjusted simply by clicking on them, entering a value using the keyboard, and pressing to save the value.
- You can also put your mouse next to a numeric property, left-click and drag it to scroll values quickly
- Some numeric properties also have a slider that can be used to visually tweak the value.
Some Value Properties open up a small popup dialog that can be used to edit the value.
Color Picker
Properties of the Color type will open up the Color Picker. (On Mac OS X this color picker can be changed to the native OS color picker by enabling under .)
The Color Picker reference in the inspector is represented by:

Color Picker reference in the inspector.
And opens the Color Picker just by clicking on it:

Color Picker descriptions.
Use the Eyedropper Tool when you want to find a value just by putting your mouse over the color you want to grab.
RGB / HSV Selector lets you switch your values from Red, Green, Blue to Hue, Saturation and Value (Strength) of your color.
Finally, the transparency of the Color selected can be controlled by the Alpha Channel value.
Curve Editor
Properties of the AnimationCurve type will open up the Curve Editor. The Curve Editor lets you edit a curve or choose from one of the presets. For more information on editing curves, see the guide on Editing Curves.
The type is called AnimationCurve for legacy reasons, but it can be used to define any custom curve function. The function can then be evaluated at runtime from a script.
An AnimationCurve property is shown in the inspector as a small preview:

A preview of an AnimationCurve in the Inspector.
Clicking on it opens the Curve Editor:

The Curve Editor is for editing AnimationCurves.
Wrapping Mode Lets you select between Ping Pong, Clamp and Loop for they Control Keys in your curve.
The Presets lets you modify your curve to default outlines the curves can have.
Editing Reference Properties
Reference properties are properties that reference other objects such as GameObjects, Components, or Assets. The reference slot will show what kind of objects can be used for this reference.

The Audio Clip property slot shows that it accept references to objects of type Audio Clip

Now an Audio Clip file is referenced in the Audio Clip property.
This type of referencing is very quick and powerful, especially when using scripting. To learn more about using scripts and properties, please view the Scripting Tutorial on the tutorials page.
Object references can be assigned to a reference property either by drag and drop or by using the Object Picker.
Drag and Drop
You can use drag and drop simply by selecting the desired object in the Scene View, Hierarchy, or Project View and dragging it into the slot of the reference property.
If a reference property accepts a specific Component type (for example a Transform) then dragging a GameObject or a Prefab onto the reference property will work fine provided that the GameObject or Prefab contains a component of the correct type. The property will then reference the component in question, even though it was a GameObject or Prefab you dragged onto it.
If you drag an object onto an reference property, and the object is not of the correct type, or does not contain the right component, then you won't be able to assign the object to the reference property.
The Object Picker
You can click on the small target icon next to a reference slot to open the Object Picker.

References to the Object Picker from the Editor.
The Object Picker is a simple window for assigning objects in the inspector after allowing you to preview and search those available.
Although the Object Picker is really easy to use, there are a few things you should be aware of. These are described below.

Anatomy of the Object Picker.
- Search: When there are lots of objects in the picker, you can use the Search field to filter them. This search field can also search objects using their Labels.
- View Selector: Switches the base of the search between objects in the scene and assets.
- Preview Size: This horizontal scroll bar lets you increase/decrease the size of your preview objects in the preview window. With this you can see more or fewer objects in the preview window at any moment.
- Preview Window: Here are all the objects that reside in your Scene/Assets folder filtered by the Search field.
- Object Info: Displays information about the currently selected object. The content of this field depends on the type of object being viewed, so if for example you pick a mesh, it will tell you the number of vertices and triangles, and whether or not it has UV's and is skinned. However, if you pick an audio file it will give you information such as the bit rate of the audio, the length, etc.
- Object Preview: This also depends on the type of object you are viewing. If you select a mesh, it will display you how the mesh looks, but if you select a script file, it will just display an icon of the file.
The Object Picker works on any asset you have in your project, which can be a video, a song, a terrain, a GUI skin, a scripting file, or a mesh; it is a tool you will use often.
Hints
- Use Labels on your Assets and you will be able to find them more easily by searching for them using the search field of the Object Picker
- If you dont want to see the descriptions of the objects you can move the slider in the bottom middle of the preview window downward.
- If you want to see a detailed preview of the object, you can enlarge the object preview by dragging the slider in the bottom middle of the preview window.
Multi-Object Editing
Starting in Unity 3.5 you can select multiple objects of the same type and edit them simultaneously in the Inspector. Any changed properties will be applied to all of the selected objects. This is a big time saver if you want to make the same change to many objects.
When selecting multiple objects, a component is only shown in the Inspector if that component exists on all the selected objects. If it only exists on some of them, a small note will appear at the bottom of the Inspector saying that components that are only on some of the selected objects cannot be multi-edited.
Property Values
When multiple objects are selected, each property shown in the Inspector represents that property on each of the selected objects. If the value of the property is the same for all the objects, the value will be shown as normal, just like when editing a single object. If the value of the property is not the same for all the selected objects, no value is shown and a dash or similar is shown instead, indicating that the values are different.

Regardless of whether a value is shown or a dash, the property value can be edited as usual and the changed value is applied to all the selected objects. If the values are different and a dash is thus shown, it's also possible to right-click on the label of the property. This brings up a menu that lets you choose from which of the objects to inherit the value.

Multi-Editing Prefab or Model Instances
Prefabs can be multi-edited just like Game Objects in the scene. Instances of prefabs or of models can also be multi-edited; however certain restrictions apply: When editing a single prefab or model instance, any property that is different from the prefab or model will appear in bold, and when right clicking there's an option to revert the property to the value it has in the prefab or model. Furthermore, the Game Object has options to apply or revert all changes. None of these things are available when multi-object editing. Properties cannot be reverted or applied; nor will they appear in bold if different from the prefab or model. To remind you of this, the Inspector will show a note with Instance Management Disabled where the , , and buttons would normally appear.

Non-Supported Objects
A few object types do not support multi-object editing. When you select multiple objects simultaneously, these objects will show a small note saying "Multi-object editing not supported".
If you have made a custom editor for one of your own scripts, it will also show this message if it doesn't support multi-object editing. See the script reference for the Editor class to learn how to implement support for multi-object editing for your own custom editors.
Page last updated: 2012-01-23Inspector Options
The Inspector Lock and the Inspector Debug Mode are two useful options that can help you in your workflow.
Lock
The Lock lets you maintain focus on a specific GameObject in the Inspector while selecting other GameObjects. To toggle the lock of an Inspector click on the lock/unlock (
) icon above the Inspector or open the tab menu and select .

Locking the Inspector from the tab menu.
Note that you can have more than one Inspector open, and that you can for example lock one of them to a specific GameObject while keeping the other one unlocked to show whichever GameObject is selected.
Debug
The Debug Mode lets you inspect private variables of components in the Inspector, which are normally not shown. To change to Debug Mode, open the tab menu and select .
In Debug Mode, all components are shown using a default interface, rather than the custom interfaces that some components use in the Normal Mode. For example, the Transform component will in Debug Mode show the raw Quaternion values of the rotation rather than the Euler angles shown in the Normal Mode. You can also use the Debug Mode to inspect the values of private variables in your own script components.

Debug Mode in the Inspector lets you inspect private variables in your scripts and in other components.
The Debug mode is per Inspector and you can have one Inspector in Debug Mode while another one is not.
Page last updated: 2010-09-09Using The Scene View
The Scene View is your interactive sandbox. You will use the Scene View to select and position environments, the player, the camera, enemies, and all other GameObjects. Maneuvering and manipulating objects within the Scene View are some of the most important functions in Unity, so it's important to be able to do them quickly.
Page last updated: 2010-09-06Scene View Navigation
The Scene View has a set of navigation controls to help you move around quickly and efficiently.
Arrow Movement
You can use the to move around the scene as though "walking" through it. The up and down arrows move the camera forward and backward in the direction it is facing. The left and right arrows pan the view sideways. Hold down the key with an arrow to move faster.
Focusing
If you select a GameObject in the hierarchy, then move the mouse over the scene view and press the key, the view will move so as to center on the object. This feature is referred to as frame selection.
Orbit, Move and Zoom
Orbiting, moving and zooming are key operations in Scene View navigation, so Unity provides several alternative ways to perform them for maximum convenience. All of these controls can be used regardless of which transform tool is selected. Holding down will increase the rate of movement and zooming.
Mouse
If you are using a three-button mouse, the following controls can be used to orient the scene view:-
- Orbit: Hold and click-drag to orbit the camera around the current pivot point.
- Move: Hold and middle click-drag to drag the camera around.
- Zoom: Hold and right click-drag to zoom the camera.
For two-button mice or trackpads, holding down ( on the Mac) with the left button will activate the Move operation. On the Mac, holding down and while left clicking will activate Zooming. Additionally, the mouse scrollwheel can be used to zoom the view.
When the hand tool is selected (shortcut: ), the following mouse controls are also available:-
Click-drag to drag the camera around.
Hold and click-drag to orbit the camera around the current pivot point.
Hold ( on Mac) and click-drag to zoom the camera.Flythrough Mode
The Flythrough mode lets you navigate the Scene View by flying around in first person similar to how you would navigate in many games.
- Click and hold the right mouse button.
- Now you can move the view around using the mouse and use the keys to move left/right forward/backward and the and keys to move up and down.
- Holding down will make you move faster.
Scene Gizmo
In the upper-right corner of the Scene View is the Scene Gizmo. This displays the Scene View Camera's current orientation, and allows you to quickly modify the viewing angle.

You can click on any of the arms to snap the Scene View Camera to that direction and change it to Isometric Mode. While in Isometric Mode, you can right-click drag to orbit, and Alt-click drag to pan. To exit this mode, click the middle of the Scene Gizmo. You can also Shift-click the middle of the Scene Gizmo any time to toggle Isometric Mode.

Perspective mode.

Isometric mode. Objects do not get smaller with distance here!
Mac Trackpad Gestures
On a Mac with a trackpad, you can drag with two fingers to zoom the view. You can also use three fingers to simulate the effect of the scene gizmo: drag up, left right or down to activate top, right, front or perspective views, respectively.
Page last updated: 2011-11-09Positioning GameObjects
When building your games, you'll place lots of different objects in your game world.
Focusing
It can be useful to focus the Scene View Camera on an object before manipulating it. Select any GameObject and press the key. This will center the Scene View and pivot point on the selection. This is also known as Frame Selection.
Translate, Rotate, and Scale
Use the Transform Tools in the Toolbar to Translate, Rotate, and Scale individual GameObjects. Each has a corresponding Gizmo that appears around the selected GameObject in the Scene View. You can use the mouse and manipulate any Gizmo axis to alter the Transform Component of the GameObject, or you can type values directly into the number fields of the Transform Component in the Inspector. Each of the three transform modes can be selected with a hotkey - W for Translate, E for Rotate and R for Scale.

- Click and drag in the center of the Gizmo to manipulate the object on all axes at once.
- At the center of the Translate gizmo, there are three small squares that can be used to drag the object within a single plane (ie, two axes can be moved at once while the third is kept still).
- If you have a three button mouse, you can click the middle button to adjust the last-adjusted axis (which turns yellow) without clicking directly on it.
- Be careful when using the scaling tool, as non-uniform scales (e.g. 1,2,1) can cause unusual scaling of child objects.
- For more information on transforming GameObjects, please view the Transform Component page.
Gizmo Display Toggles
The Gizmo Display Toggles are used to define the location of any Transform Gizmo.

Gizmo Display Toggles
- Position:
- will position the Gizmo at the center of the object's rendered bounds.
- will position the Gizmo at the actual pivot point of a Mesh.
- Rotation:
- will keep the Gizmo's rotation relative to the object's.
- will clamp the Gizmo to world space orientation.
Unit Snapping
While dragging any Gizmo Axis using the Translate Tool, you can hold the key ( on Mac) to snap to increments defined in the Snap Settings.
You can change the unit distance that is used for the unit snapping using the menu

Scene View Unit Snapping settings.
Surface Snapping
While dragging in the center using the Translate Tool, you can hold and ( on Mac) to snap the object to the intersection of any Collider. This makes precise positioning of objects incredibly fast.
Look-At Rotation
While using the Rotate Tool, you can hold and ( on Mac) to rotate the object towards a point on the surface of any Collider. This makes orientation of objects relative to one another simple.
Vertex Snapping
You can assemble your worlds more easily with a feature called Vertex Snapping. This feature is a really simple but powerful tool in Unity. It lets you take any vertex from a given mesh and with your mouse place that vertex in the same position as any vertex from any other mesh you choose.
With this you can assemble your worlds really fast. For example, you can place roads in a racing game with high precision and add power up items on the vertices of a mesh.

Assembling roads with Vertex Snapping.
Using vertex snapping in Unity is simple. Just follow these steps:
- Select the mesh you want to manipulate and make sure the Transform Tool is active.
- Press and hold the key to activate the vertex snapping mode.
- Move your cursor over the vertex on your mesh that you want to use as the pivot point.
- Hold down the left button once your cursor is over the desired vertex and drag your mesh next to any other vertex on another mesh.
- Release your mouse button and the key when you are happy with the results.
- acts as a toggle of this functionality.
- You can snap vertex to vertex, vertex to surface and pivot to vertex.
A video on how to use vertex snapping can be found here.
Page last updated: 2011-10-26View Modes
The Scene View control bar lets you choose various options for viewing the scene and also control whether lighting and audio are enabled. These controls only affect the scene view during development and have no effect on the built game.

Draw Mode
The first drop-down menu selects which Draw Mode will be used to depict the scene.

Draw Mode drop-down
- Textured: show surfaces with their textures visible.
- Wireframe: draw meshes with a wireframe representation.
- Tex-Wire: show meshes textured and with wireframes overlaid.
- Render Paths: show the rendering path for each object using a color code: Green indicates deferred lighting, yellow indicates forward rendering and red indicates vertex lit.
- Lightmap Resolution: overlay a checkered grid on the scene to show the resolution of the lightmaps.
Render Mode
The next drop-down along selects which of four Render Modes will be used to render the scene.

Render Mode drop-down
- RGB: render the scene with objects normally colored.
- Alpha: render colors with alpha.
- Overdraw: render objects as transparent "silhouettes". The transparent colors accumulate, making it easy to spot places where one object is drawn over another.
- Mipmaps: show ideal texture sizes using a color code: red indicates that the texture is larger than necessary (at the current distance and resolution); blue indicates that the texture could be larger. Naturally, ideal texture sizes depend on the resolution at which the game will run and how close the camera can get to particular surfaces.
Scene Lighting, Game Overlay, and Audition Mode
To the right of the dropdown menus are three buttons which control other aspects of the scene representation.

The first button determines whether the view will be lit using a default scheme or with the lights that have actually been added to the scene. The default scheme is used initially but this will change automatically when the first light is added. The second button controls whether skyboxes and GUI elements will be rendered in the scene view and also shows and hides the placement grid. The third button switches audio sources in the scene on and off.
Page last updated: 2011-11-10Gizmo and Icon Visibility
Gizmos and icons have a few display options which can be used to reduce clutter and improve the visual clarity of the scene during development.
The Icon Selector
Using the Icon Selector, you can easily set custom icons for GameObjects and scripts that will be used both in the Scene View and the Inspector. To change the icon for a GameObject, simply click on its icon in the Inspector. The icons of script assets can be changed in a similar way. In the Icon Selector is a special kind of icon called a Label Icon. This type of icon will show up in the Scene View as a text label using the name of the GameObject. Icons for built-in Components cannot be changed.
Selecting an icon for a GameObject
Selecting an icon for a script
Showing and Hiding Icons and Gizmos
The visibility of an individual component's gizmos depends on whether the component is expanded or collapsed in the inspector (ie, collapsed components are invisible). However, you can use the Gizmos dropdown to expand or collapse every component of a given type at once. This is a useful way to reduce visual clutter when there are a large number of gizmos and icons in the scene.
To show the state of the current gizmo and icon, click on in the control bar of the Scene or Game View. The toggles here are used to set which icons and gizmos are visible.
Note that the scripts that show up in the section are those that either have a custom icon or have an or function implemented.
The Gizmos dropdown, displaying the visibility state of icons and gizmos
The slider can be used to adjust the size used for icon display in the scene. If the slider is placed at the extreme right, the icon will always be drawn at its natural size. Otherwise, the icon will be scaled according to its distance from the scene view camera (although there is an upper limit on the display size in order that screen clutter be avoided).
Page last updated: 2011-11-09Searching
When working with large complex scenes it can be useful to search for specific objects. By using the Search feature in Unity, you can filter out only the object or group of objects that you want to see. You can search assets by their name, by Component type, and in some cases by asset Labels. You can specify the search mode by choosing from the Search drop-down menu.
Scene Search
When a scene is loaded in the Editor, you can see the objects in both the Scene View and the Hierarchy. The specific assets are shared in both places, so if you type in a search term (eg, "elevator"), you'll see the the filter applied both visually in the Scene View and a more typical manner in the Hierarchy. There is also no difference between typing the search term into the search field in the Scene View or the Hierachy -- the filter takes effect in both views in either case.

Scene View and Hierarchy with no search applied.

Scene View and Hierarchy with active filtering of search term.
When a search term filter is active, the Hierarchy doesn't show hierarchical relationships between GameObjects, but you can select any GameObject, and it's hierarchical path in the scene will be shown at the bottom of the Hierarchy.

Click on a GameObject in the filtered list to see its hierarchical path.
When you want to clear the search filter, just click the small cross in the search field.
In the Scene search you can search either by Name or by Type. Click on the small magnifying glass in the search field to open the search drop-down menu and choose the search mode.

Search by Name, Type, or All.
Project Search
The same fundamentals apply to searching of assets in the Project View -- just type in your search term and you'll see all the relevant assets appear in the filter.
In the Project search you can search by Name or by Type as in the Scene search, and additionally you can search by Label. Click on the small magnifying glass in the search field to open the search drop-down menu and choose the search mode.

Search by Name, Type, Label, or All.
Object Picker Search
When assigning an object via the Object Picker, you can also enter a search term search to filter the objects you want to see.
Page last updated: 2011-11-10Prefabs
A Prefab is a type of asset -- a reusable GameObject stored in Project View. Prefabs can be inserted into any number of scenes, multiple times per scene. When you add a Prefab to a scene, you create an instance of it. All Prefab instances are linked to the original Prefab and are essentially clones of it. No matter how many instances exist in your project, when you make any changes to the Prefab you will see the change applied to all instances.
Creating Prefabs
In order to create a Prefab, you must make a new blank Prefab using the menu. This blank Prefab contains no GameObjects, and you cannot create an instance of it. Think of a new Prefab as an empty container, waiting to be filled with GameObject data.

A new, empty Prefab. It cannot be instanced until you fill it with a GameObject.
To fill the Prefab, you use a GameObject that you've created in the scene.
- Choose from the menu bar and name your new Prefab.
- In Hierarchy View, select the GameObject you wish to make into a Prefab.
- Drag & drop the GameObject from the Hierarchy onto the new Prefab in Project View.
After you have performed these steps, the GameObject and all its children have been copied into the Prefab data. The Prefab can now be re-used in multiple instances. The original GameObject in the Hierarchy has now become an instance of the Prefab.
Prefab Instances
To create a Prefab instance in the current scene, drag the Prefab from the Project View into the Scene or Hierarchy View. This instance is linked to the Prefab, as displayed by the blue text used for their name in the Hierarchy View.

Three of these GameObjects are linked to Prefabs. One of them is not.
- If you have selected a Prefab instance, and want to make a change that affects all instances, you can click the button in the Inspector to select the source Prefab.
- Information about instantiating prefabs from scripts is in the Instantiating Prefabs page.
Inheritance
Inheritance means that whenever the source Prefab changes, those changes are applied to all linked GameObjects. For example, if you add a new script to a Prefab, all of the linked GameObjects will instantly contain the script as well. However, it is possible to change the properties of a single instance while keeping the link intact. Simply change any property of a prefab instance, and watch as the variable name becomes bold. The variable is now overridden. All overridden properties will not be affected by changes in the source Prefab.
This allows you to modify Prefab instances to make them unique from their source Prefabs without breaking the Prefab link.

A linked GameObject with no overrides enabled.

A linked GameObject with several (bold) overrides enabled.
- If you want to update the source Prefab and all instances with the new overridden values, you can click the button in the Inspector.
- Note that the root's position and rotation will not be applied, as that affects the instances absolute position and would put all instances in the same place. However position and rotation from any children or ancestors of the root will be applied as they are computed relative to the root's transform.
- If you want to discard all overrides on a particular instance, you can click the button.
Imported Prefabs
When you place a mesh asset into your Assets folder, Unity automatically imports the file and generates something that looks similar to a Prefab out of the mesh. This is not actually a Prefab, it is simply the asset file itself. Instancing and working with assets introduces some limitations that are not present when working with normal Prefabs.

Notice the asset icon is a bit different from the Prefab icons
The asset is instantiated in the scene as a GameObject, linked to the source asset instead of a normal Prefab. Components can be added and removed from this GameObject as normal. However, you cannot apply any changes to the asset itself since this would add data to the asset file itself! If you're creating something you want to re-use, you should make the asset instance into a Prefab following the steps listed above under "Creating Prefabs".
- When you have selected an instance of an asset, the button in the Inspector is replaced with an button. Clicking this button will launch the editing application for your asset (e.g. Maya or Max).
Lights
Lights are an essential part of every scene. While meshes and textures define the shape and look of a scene, lights define the color and mood of your 3D environment. You'll likely work with more than one light in each scene. Making them work together requires a little practice but the results can be quite amazing.

A simple, two-light setup
Lights can be added to your scene from the menu. Once a light has been added, you can manipulate it like any other GameObject. Additionally, you can add a Light Component to any selected GameObject by using .
There are many different options within the Light Component in the Inspector.

Light Component properties in the Inspector
By simply changing the Color of a light, you can give a whole different mood to the scene.

Bright, sunny lights

Dark, medieval lights

Spooky night lights
The lights you create this way are realtime lights - their lighting is calculated each frame while the game is running. If you know the light will not change, you can make your game faster and look much better by using Lightmapping.
Rendering paths
Unity supports different Rendering Paths, these paths affect mainly Lights and Shadows, so choosing the correct rendering path depending on your game requirements can improve your project's performance. For more info about rendering paths you can visit the Rendering paths section.
More information
For more information about using Lights, check the Lights page in the Reference Manual.
Page last updated: 2011-10-24Cameras
Just as cameras are used in films to display the story to the audience, Cameras in Unity are used to display the game world to the player. You will always have at least one camera in a scene, but you can have more than one. Multiple cameras can give you a two-player splitscreen or create advanced custom effects. You can animate cameras, or control them with physics. Practically anything you can imagine is possible with cameras, and you can use typical or unique cameras to fit your game's style.
The remaining text is from the Camera Component reference page.
Camera
Cameras are the devices that capture and display the world to the player. By customizing and manipulating cameras, you can make the presentation of your game truly unique. You can have an unlimited number of cameras in a scene. They can be set to render in any order, at any place on the screen, or only certain parts of the screen.

Unity's flexible Camera object
Properties
| Clear Flags | Determines which parts of the screen will be cleared. This is handy when using multiple Cameras to draw different game elements. |
| Background | Color applied to the remaining screen after all elements in view have been drawn and there is no skybox. |
| Culling Mask | Include or omit layers of objects to be rendered by the Camera. Assign layers to your objects in the Inspector. |
| Projection | Toggles the camera's capability to simulate perspective. |
| Perspective | Camera will render objects with perspective intact. |
| Orthographic | Camera will render objects uniformly, with no sense of perspective. |
| Size (when Orthographic is selected) | The viewport size of the Camera when set to Orthographic. |
| Field of view | Width of the Camera's view angle, measured in degrees along the local Y axis. |
| Clipping Planes | Distances from the camera to start and stop rendering. |
| Near | The closest point relative to the camera that drawing will occur. |
| Far | The furthest point relative to the camera that drawing will occur. |
| Normalized View Port Rect | Four values that indicate where on the screen this camera view will be drawn, in Screen Coordinates (values 0-1). |
| X | The beginning horizontal position that the camera view will be drawn. |
| Y | The beginning vertical position that the camera view will be drawn. |
| W (Width) | Width of the camera output on the screen. |
| H (Height) | Height of the camera output on the screen. |
| Depth | The camera's position in the draw order. Cameras with a larger value will be drawn on top of cameras with a smaller value. |
| Rendering Path | Options for defining what rendering methods will be used by the camera. |
| Use Player Settings | This camera will use whichever Rendering Path is set in the Player Settings. |
| Vertex Lit | All objects rendered by this camera will be rendered as Vertex-Lit objects. |
| Forward | All objects will be rendered with one pass per material, as was standard in Unity 2.x. |
| Deferred Lighting (Unity Pro only) | All objects will be drawn once without lighting, then lighting of all objects will be rendered together at the end of the render queue. |
| Target Texture (Unity Pro/Advanced only) | Reference to a Render Texture that will contain the output of the Camera view. Making this reference will disable this Camera's capability to render to the screen. |
| HDR | Enables High Dynamic Range rendering for this camera. |
Details
Cameras are essential for displaying your game to the player. They can be customized, scripted, or parented to achieve just about any kind of effect imaginable. For a puzzle game, you might keep the Camera static for a full view of the puzzle. For a first-person shooter, you would parent the Camera to the player character, and place it at the character's eye level. For a racing game, you'd likely want to have the Camera follow your player's vehicle.
You can create multiple Cameras and assign each one to a different Depth. Cameras are drawn from low Depth to high Depth. In other words, a Camera with a Depth of 2 will be drawn on top of a Camera with a depth of 1. You can adjust the values of the Normalized View Port Rectangle property to resize and position the Camera's view onscreen. This can create multiple mini-views like missile cams, map views, rear-view mirrors, etc.
Render Path
Unity supports different Rendering Paths. You should choose which one you use depending on your game content and target platform / hardware. Different rendering paths have different features and performance characteristics that mostly affect Lights and Shadows.
The rendering Path used by your project is chosen in Player Settings. Additionally, you can override it for each Camera.
For more info on rendering paths, check the rendering paths page.
Clear Flags
Each Camera stores color and depth information when it renders its view. The portions of the screen that are not drawn in are empty, and will display the skybox by default. When you are using multiple Cameras, each one stores its own color and depth information in buffers, accumulating more data as each Camera renders. As any particular Camera in your scene renders its view, you can set the Clear Flags to clear different collections of the buffer information. This is done by choosing one of the four options:
Skybox
This is the default setting. Any empty portions of the screen will display the current Camera's skybox. If the current Camera has no skybox set, it will default to the skybox chosen in the Render Settings (found in ). It will then fall back to the Background Color. Alternatively a Skybox component can be added to the camera. If you want to create a new Skybox, you can use this guide.
Solid Color
Any empty portions of the screen will display the current Camera's Background Color.
Depth Only
If you wanted to draw a player's gun without letting it get clipped inside the environment, you would set one Camera at Depth 0 to draw the environment, and another Camera at Depth 1 to draw the weapon alone. The weapon Camera's Clear Flags should be set to to depth only. This will keep the graphical display of the environment on the screen, but discard all information about where each object exists in 3-D space. When the gun is drawn, the opaque parts will completely cover anything drawn, regardless of how close the gun is to the wall.

The gun is drawn last, after clearing the depth buffer of the cameras before it
Don't Clear
This mode does not clear either the color or the depth buffer. The result is that each frame is drawn over the next, resulting in a smear-looking effect. This isn't typically used in games, and would likely be best used with a custom shader.
Clip Planes
The Near and Far Clip Plane properties determine where the Camera's view begins and ends. The planes are laid out perpendicular to the Camera's direction and are measured from the its position. The Near plane is the closest location that will be rendered, and the Far plane is the furthest.
The clipping planes also determine how depth buffer precision is distributed over the scene. In general, to get better precision you should move the Near plane as far as possible.
Note that the near and far clip planes together with the planes defined by the field of view of the camera describe what is popularly known as the camera frustum. Unity ensures that when rendering your objects those which are completely outside of this frustum are not displayed. This is called Frustum Culling. Frustum Culling happens irrespective of whether you use Occlusion Culling in your game.
For performance reasons, you might want to cull small objects earlier. For example, small rocks and debris could be made invisible at much smaller distance than large buildings. To do that, put small objects into a separate layer and setup per-layer cull distances using Camera.layerCullDistances script function.
Culling Mask
The Culling Mask is used for selectively rendering groups of objects using Layers. More information on using layers can be found here.
Commonly, it is good practice to put your User Interface on a different layer, then render it by itself with a separate Camera set to render the UI layer by itself.
In order for the UI to display on top of the other Camera views, you'll also need to set the Clear Flags to Depth only and make sure that the UI Camera's Depth is higher than the other Cameras.
Normalized Viewport Rectangle
Normalized Viewport Rectangles are specifically for defining a certain portion of the screen that the current camera view will be drawn upon. You can put a map view in the lower-right hand corner of the screen, or a missile-tip view in the upper-left corner. With a bit of design work, you can use Viewport Rectangle to create some unique behaviors.
It's easy to create a two-player split screen effect using Normalized Viewport Rectangle. After you have created your two cameras, change both camera H value to be 0.5 then set player one's Y value to 0.5, and player two's Y value to 0. This will make player one's camera display from halfway up the screen to the top, and player two's camera will start at the bottom and stop halfway up the screen.

Two-player display created with Normalized Viewport Rectangle
Orthographic
Marking a Camera as Orthographic removes all perspective from the Camera's view. This is mostly useful for making isometric or 2D games.
Note that fog is rendered uniformly in orthographic camera mode and may therefore not appear as expected. Read more about why in the component reference on Render Settings.

Perspective camera.

Orthographic camera. Objects do not get smaller with distance here!
Render Texture
This feature is only available for Unity Advanced licenses . It will place the camera's view onto a Texture that can then be applied to another object. This makes it easy to create sports arena video monitors, surveillance cameras, reflections etc.

A Render Texture used to create a live arena-cam
Hints
- Cameras can be instantiated, parented, and scripted just like any other GameObject.
- To increase the sense of speed in a racing game, use a high Field of View.
- Cameras can be used in physics simulation if you add a Rigidbody Component.
- There is no limit to the number of Cameras you can have in your scenes.
- Orthographic cameras are great for making 3D user interfaces
- If you are experiencing depth artifacts (surfaces close to each other flickering), try setting Near Plane to as large as possible.
- Cameras cannot render to the Game Screen and a Render Texture at the same time, only one or the other.
- Pro license holders have the option of rendering a Camera's view to a texture, called Render-to-Texture, for even more unique effects.
- Unity comes with pre-installed Camera scripts, found in . Experiment with them to get a taste of what's possible.
Terrains
This section will explain how to use the Terrain Engine. It will cover creation, technical details, and other considerations. It is broken into the following sections:
Using Terrains
This section covers the most basic information about using Terrains. This includes creating Terrains and how to use the new Terrain tools & brushes.
Height
This section explains how to use the different tools and brushes that alter the Height of the Terrain.
Terrain Textures
This section explains how to add, paint and blend Terrain Textures using different brushes.
Trees
This section contains important information for creating your own tree assets. It also covers adding and painting trees on your Terrain.
Grass
This section explains how grass works, and how to use it.
Detail Meshes
This section explains practical usage for detail meshes like rocks, haystacks, vegetation, etc.
Lightmaps
You can lightmap terrains just like any other objects using Unity's built-in lightmapper. See Lightmapping Quickstart for help.
Other Settings
This section covers all the other settings associated with Terrains.
iOS
Due to performance hit, Terrain Engine usage is discouraged on pre-ipad2 devices.
Android
Due to performance hit, Terrain Engine usage is discouraged on non high-end devices.
Asset Import and Creation
A large part of making a game is utilizing your asset source files in your GameObjects. This goes for textures, models, sound effects and behaviour scripts. Using the Project View inside Unity, you have quick access to all the files that make up your game:

The Project View displays all source files and created Prefabs
This view shows the organization of files in your project's Assets folder. Whenever you update one of your asset files, the changes are immediately reflected in your game!
To import an asset file into your project, move the file into in the Finder, and it will automatically be imported into Unity. To apply your assets, simply drag the asset file from the Project View window into the Hierarchy or Scene View. If the asset is meant to be applied to another object, drag the asset over the object.
Hints
- It is always a good idea to add labels to your assets when you are working with big projects or when you want to keep organized all your assets, with this you can search for the labels associated to each asset in the search field in the project view.
- When backing up a project folder always back up Assets, ProjectSettings and Library folders. The Library folder contains all meta data and all the connections between objects, thus if the Library folder gets lost, you will lose references from scenes to assets. Easiest is just to back up the whole project folder containing the Assets, ProjectSettings and Library folders.
- Rename and move files to your heart's content inside Project View; nothing will break.
- Never rename or move anything from the Finder or another program; everything will break. In short, Unity stores lots of metadata for each asset (things like import settings, cached versions of compressed textures, etc.) and if you move a file externally, Unity can no longer associate metadata with the moved file.
Continue reading for more information:
- Importing Assets
- Meshes
- Animations
- Materials and Shaders
- Texture 2D
- Procedural Materials
- Movie Texture
- Audio Files
- Using Scripts
- Asset Store
- Asset Server (Pro Only)
- Behind the Scenes
Importing Assets
Unity will automatically detect files as they are added to your Project folder's Assets folder. When you put any asset into your Assets folder, you will see the asset appear in your Project View.

The Project View is your window into the Assets folder, normally accessible from the file manager
When you are organizing your Project View, there is one very important thing to remember:
Never move any assets or organize this folder from the Explorer (Windows) or Finder (OS X). Always use the Project View!
There is a lot of meta data stored about relationships between asset files within Unity. This data is all dependent on where Unity expects to find these assets. If you move an asset from within the Project View, these relationships are maintained. If you move them outside of Unity, these relationships are broken. You'll then have to manually re-link lots of dependencies, which is something you probably don't want to do.
So just remember to only save assets to the Assets folder from other applications, and never rename or move files outside of Unity. Always use Project View. You can safely open files for editing from anywhere, of course.
Creating and Updating Assets
When you are building a game and you want to add a new asset of any type, all you have to do is create the asset and save it somewhere in the Assets folder. When you return to Unity or launch it, the added file(s) will be detected and imported.
Additionally, as you update and save your assets, the changes will be detected and the asset will be re-imported in Unity. This allows you to focus on refining your assets without struggling to make them compatible with Unity. Updating and saving your assets normally from its native application provides optimum, hassle-free workflow that feels natural.
Asset Types
There are a handful of basic asset types that will go into your game. The types are:
- Mesh Files & Animations
- Texture Files
- Sound Files
We'll discuss the details of importing each of these file types and how they are used.
Meshes & Animations
Whichever 3D package you are using, Unity will import the meshes and animations from each file. For a list of applications that are supported by Unity, please see this page.
Your mesh file does not need to have an animation to be imported. If you do use animations, you have your choice of importing all animations from a single file, or importing separate files, each with one animation. For more information about importing animations, please see page about Animation Import.
Once your mesh is imported into Unity, you can drag it to the Scene or Hierarchy to create an instance of it. You can also add Components to the instance, which will not be attached to mesh file itself.
Meshes will be imported with UVs and a number of default Materials (one material per UV). You can then assign the appropriate texture files to the materials and complete the look of your mesh in Unity's game engine.
Textures
Unity supports all image formats. Even when working with layered Photoshop files, they are imported without disturbing the Photoshop format. This allows you to work with a single texture file for a very care-free and streamlined experience.
You should make your textures in dimensions that are to the power of two (e.g. 32x32, 64x64, 128x128, 256x256, etc.) Simply placing them in your project's Assets folder is sufficient, and they will appear in the Project View.
Once your texture has been imported, you should assign it to a Material. The material can then be applied to a mesh, Particle System, or GUI Texture. Using the Import Settings, it can also be converted to a Cubemap or Normalmap for different types of applications in the game. For more information about importing textures, please read the Texture Component page.
Sounds
Desktop
Unity features support for two types of audio: Uncompressed Audio or Ogg Vorbis. Any type of audio file you import into your project will be converted to one of these formats.
File Type Conversion
| .AIFF | Converted to uncompressed audio on import, best for short sound effects. |
| .WAV | Converted to uncompressed audio on import, best for short sound effects. |
| .MP3 | Converted to Ogg Vorbis on import, best for longer music tracks. |
| .OGG | Compressed audio format, best for longer music tracks. |
Import Settings
If you are importing a file that is not already compressed as Ogg Vorbis, you have a number of options in the Import Settings of the Audio Clip. Select the Audio Clip in the Project View and edit the options in the Audio Importer section of the Inspector. Here, you can compress the Clip into Ogg Vorbis format, force it into Mono or Stereo playback, and tweak other options. There are positives and negatives for both Ogg Vorbis and uncompressed audio. Each has its own ideal usage scenarios, and you generally should not use either one exclusively.
Read more about using Ogg Vorbis or Uncompressed audio on the Audio Clip Component Reference page.
iOS
Unity features support for two types of audio: Uncompressed Audio or MP3 Compressed audio. Any type of audio file you import into your project will be converted to one of these formats.
File Type Conversion
| .AIFF | Imports as uncompressed audio for short sound effects. Can be compressed in Editor on demand. |
| .WAV | Imports as uncompressed audio for short sound effects. Can be compressed in Editor on demand. |
| .MP3 | Imports as Apple Native compressed format for longer music tracks. Can be played on device hardware. |
| .OGG | OGG compressed audio format, incompatible with the iPhone device. Please use MP3 compressed sounds on the iPhone. |
Import Settings
When you are importing an audio file, you can select its final format and choose to force it to stereo or mono channels. To access the Import Settings, select the Audio Clip in the Project View and find the Audio Importer in the Inspector. Here, you can compress the Clip into Ogg Vorbis format, force it into Mono or Stereo playback, and tweak other options, such as the very important Decompress On Load setting.
Read more about using MP3 Compressed or Uncompressed audio on the Audio Clip Component Reference page.
Android
Unity features support for two types of audio: Uncompressed Audio or MP3 Compressed audio. Any type of audio file you import into your project will be converted to one of these formats.
File Type Conversion
| .AIFF | Imports as uncompressed audio for short sound effects. Can be compressed in Editor on demand. |
| .WAV | Imports as uncompressed audio for short sound effects. Can be compressed in Editor on demand. |
| .MP3 | Imports as MP3 compressed format for longer music tracks. |
| .OGG | Note: the OGG compressed audio format is incompatible with some Android devices, so Unity does not support it for the Android platform. Please use MP3 compressed sounds instead. |
Import Settings
When you are importing an audio file, you can select its final format and choose to force it to stereo or mono channels. To access the Import Settings, select the Audio Clip in the Project View and find the Audio Importer in the Inspector. Here, you can compress the Clip into Ogg Vorbis format, force it into Mono or Stereo playback, and tweak other options, such as the very important Decompress On Load setting.
Read more about using MP3 Compressed or Uncompressed audio on the Audio Clip Component Reference page.
Once sound files are imported, they can be attached to any GameObject. The Audio file will create an Audio Source Component automatically when you drag it onto a GameObject.
Page last updated: 2011-11-10Meshes
At the core of any 3D game are Meshes - objects consisting of triangles, with textures applied.
Meshes in Unity are rendered with renderer components. Although there may be many variations, a Mesh Renderer is the most commonly used.
- The renderer displays the mesh at the GameObject's position.
- The appearance of the mesh is controlled through the renderer's Materials.
Meshes
Meshes make up a large part of your 3D worlds. Unity doesn't have its own tools for mesh creation but has good interactivity with popular 3D modelling software. Importing meshes is mostly straightforward but the following pages note things that you need to watch out for with particular applications.
Other applications
Unity can read .FBX, .dae (Collada), .3DS, .dxf and .obj files, so any software that that can export any of these formats should work fine with Unity. FBX exporters for popular 3D packages can be found here. Many packages also have a Collada exporter available.
Textures
Unity will attempt to find the textures used by a mesh automatically on import by following a specific search plan. First, the importer will look for a sub-folder called Textures within the same folder as the mesh or in any parent folder. If this fails, an exhaustive search of all textures in the project will be carried out. Although slightly slower, the main disadvantage of the exhaustive search is that there could be two or more textures in the project with the same name. In this case, it is not guaranteed that the right one will be found.

Place your textures in a folder at or above the asset's level
Import settings.
The Import Settings for a mesh file will be displayed in the inspector when the mesh is selected.

The Mesh Import Settings dialog
| Meshes | |
| Scale Factor | Unity's physics system expects 1 meter in the game world to be 1 unit in the imported file. If you prefer to model at a different scale then you can compensate for it here. |
| Use File Units | This option is available only for 3dsMax files. If enabled it imports 3dsMax file with one Max unit equal to one Unity unit, otherwise it imports with 1 cm equal to 1 Unity unit. |
| Mesh Compression | Increasing this value will reduce the file size of the mesh, but might introduce irregularities. It's best to turn it up as high as possible without the mesh looking too different from the uncompressed version. This is useful for optimizing game size. |
| Mesh Optimization | This option determines the order in which triangles will be listed in the mesh. |
| Generate Colliders | If this is enabled, your meshes will be imported with Mesh Colliders automatically attached. This is useful for quickly generating a collision mesh for environment geometry, but should be avoided for geometry you will be moving. For more info see Colliders below. |
| Swap UVs | Use this if lightmapped objects pick up the wrong UV channels. This will swap your primary and secondary UV channels. |
| Generate Lightmap UVs | Use this to create the second UV channel to be used for Lightmapping. |
| Advanced Options | See Lightmapping UVs document. |
| Normals & Tangents | |
| Normals | Defines if and how normals should be calculated. This is useful for optimizing game size. |
| Import | Default option. Imports normals from the file. |
| Calculate | Calculates normals based on Smoothing angle. If selected, the Smoothing Angle becomes enabled. |
| None | Disables normals. Use this option if the mesh is neither normal mapped nor affected by realtime lighting. |
| Tangents | Defines if and how tangents and binormals should be calculated. This is useful for optimizing game size. |
| Import | Imports tangents and binormals from the file. This option is available only for FBX, Maya and 3dsMax files and only when normals are imported from the file. |
| Calculate | Default option. Calculates tangents and binormals. This option is available only when normals are either imported or calculated. |
| None | Disables tangents and binormals. The mesh will have no Tangents, so won't work with normal-mapped shaders. |
| Smoothing Angle | Sets how sharp an edge has to be in order to be treated as a hard edge. It is also used to split normal map tangents. |
| Split Tangents | Enable this if normal map lighting is broken by seams on your mesh. This usually only applies to characters. |
| Materials | |
| Import Materials | Disable this if you don't want materials to be generated. Default-Diffuse material will be used instead. |
| Material Naming | Controls how Unity materials are named: |
| <textureName>.mat | The name of the diffuse texture of the imported material that will be used to name the material in Unity. When a diffuse texture is not assigned to the material, Unity will use the name of the imported material. |
| <materialName>.mat | The name of the imported material will be used for naming the Unity material. |
| <modelFileName>-<materialName>.mat | The name of the model file in combination with the name of the imported material will be used for naming the Unity material. |
| <textureName>.mat or <modelFileName>-<materialName>.mat (OBSOLETE) | The name of the diffuse texture of the imported material will be used for naming the Unity material. When a diffuse texture is not assigned or it cannot be located in one of the Textures folders, then the material will be named <modelFileName>-<materialName>.mat instead. This option is backwards compatible with the behavior of Unity 3.4 (and earlier versions). We recommend using <textureName>.mat, because it is less complicated and has more consistent behavior. |
| Material Search | Controls where Unity will try to locate existing materials using the name defined by the Material Naming option: |
| Local | Unity will try to find existing materials only in the "local" Materials folder, ie, the Materials subfolder which is the same folder as the model file. |
| Recursive-Up | Unity will try to find existing materials in all Materials subfolders in all parent folders up to the Assets folder. |
| Everywhere | Unity will try to find existing materials in all Unity project folders. |
| Animations | |
| Generation | Controls how animations are imported: |
| Don't Import | No animation or skinning is imported. |
| Store in Original Roots | Animations are stored in the root objects of your animation package (these might be different from the root objects in Unity). |
| Store in Nodes | Animations are stored together with the objects they animate. Use this when you have a complex animation setup and want full scripting control. |
| Store in Root | Animations are stored in the scene's transform root objects. Use this when animating anything that has a hierarchy. |
| Bake Animations | Enable this when using IK or simulation in your animation package. Unity will convert to forward kinematics on import. This option is available only for Maya, 3dsMax and Cinema4D files. |
| Animation Wrap mode | The default Wrap Mode for the animation in the mesh being imported |
| Default | The animation plays as specified in the animation splitting options below. |
| Once | The animation plays through to the end once and then stops. |
| Loop | The animation plays through and then restarts when the end is reached. |
| PingPong | The animation plays through and then plays in reverse from the end to the start, and so on. |
| ClampForever | The animation plays through but the last frame is repeated indefinitely. This is not the same as Once mode because playback does not technically stop at the last frame (which is useful when blending animations). |
| Split Animations | If you have multiple animations in a single file, you can split it into multiple clips. |
| Name | The name of the split animation clip |
| Start | The first frame of this clip in the model file |
| End | The last frame of this clip in the model file |
| WrapMode | What the split clip does when the end of the animation is reached (this is identical to the wrap mode option described above). |
| Loop | Depending on how the animation was created, one extra frame of animation may be required for the split clip to loop properly. If your looping animation doesn't look correct, try enabling this option. |
| Animation Compression | |
| Anim. Compression | The type of compression that will be applied to this mesh's animation(s) |
| Off | Disables animation compression. This means that Unity doesn't reduce keyframe count on import, which leads to the highest precision animations, but slower performance and bigger file and runtime memory size. It is generally not advisable to use this option - if you need higher precision animation, you should enable keyframe reduction and lower allowed Animation Compression Error values instead. |
| Keyframe Reduction | Reduces keyframes on import. If selected, the Animation Compression Errors options are displayed. |
| Keyframe Reduction and Compression | Reduces keyframes on import and compresses keyframes when storing animations in files. This affects only file size - the runtime memory size is the same as Keyframe Reduction. If selected, the Animation Compression Errors options are displayed. |
| Animation Compression Errors | These options are available only when keyframe reduction is enabled. |
| Rotation Error | Defines how much rotation curves should be reduced. The smaller value you use - the higher precision you get. |
| Position Error | Defines how much position curves should be reduced. The smaller value you use - the higher precision you get. |
| Scale Error | Defines how much scale curves should be reduced. The smaller value you use - the higher precision you get. |
Material Generation and Assignment
For each imported material Unity will apply the following rules:-
If material generation is disabled (i.e. Import Materials is unchecked), then it will assign the Default-Diffuse material. If it is enabled then it will do the following:
- Unity will pick a name for the Unity material based on the Material Naming setting
- Unity will try to find an existing material with that name. The scope of the Material search is defined by the Material Search setting.
- If Unity succeeds in finding an existing material then it will use it for the imported scene, otherwise it will generate a new material
Colliders
Unity uses two main types of colliders: Mesh Colliders and Primitive Colliders. Mesh colliders are components that use imported mesh data and can be used for environment collision. When you enable Generate Colliders in the Import Settings, a Mesh collider is automatically added when the mesh is added to the Scene. It will be considered solid as far as the physics system is concerned.
If you are moving the object around (a car for example), you can not use Mesh colliders. Instead, you will have to use Primitive colliders. In this case you should disable the Generate Colliders setting.
Animations
Animations are automatically imported from the scene. For more details about animation import options see the Animation Import chapter.
Normal mapping and characters
If you have a character with a normal map that was generated from a high-polygon version of the model, you should import the game-quality version with a Smoothing angle of 180 degrees. This will prevent odd-looking seams in lighting due to tangent splitting. If the seams are still present with these settings, enable Split tangents across UV seams.
If you are converting a greyscale image into a normal map, you don't need to worry about this.
Hints
- Merge your meshes together as much as possible. Make them share materials and textures. This has a huge performance benefit.
- If you need to set up your objects further in Unity (adding physics, scripts or other coolness), save yourself a world of pain and name your objects properly in your 3D application. Working with lots of pCube17 or Box42-like objects is not fun.
- Make your meshes be centered on the world origin in your 3D app. This will make them easier to place in Unity.
The Unity Editor shows too many triangles (compared to what my 3D app says)
This is correct. What you are looking at is the number of triangles actually being sent to OpenGLES for rendering. In addition to the case where the material requires them to be sent twice, other things like hard-normals and non-contiguous UVs increase vertex/triangle counts significantly compared to what a modeling app or Unity tells you. Triangles need to be contiguous in both 3D and UV space to form a strip, so when you have UV seams, degenerate triangles have to be made to form strips - this bumps up the count. Previously Unity would report triangle counts incorrectly. This was fixed first in the run-time, and recently in the Editor. Now both will report the correct number of triangles actually being sent to OpenGLES for rendering.
See Also
- Modeling Optimized Characters
- How do I use normal maps?
- How do I fix the rotation of an imported model?
Animations
Unity's Animation System allows you to create beautifully animated skinned characters. The Animation System supports animation blending, mixing, additive animations, walk cycle time synchronization, animation layers, control over all aspects of the animation playback (time, speed, blend-weights), mesh skinning with 1, 2 or 4 bones per vertex and finally physically based ragdolls.
There are some best practices for creating a rigged character with optimal performance in Unity. It is recommended that you read about these techniques on the Modeling Optimized Characters page.
The following topics are covered on this page:-
You can download an example demo showing pre-setup animated characters here.
Importing The Animations
First of all we have to import the character. Unity natively imports Maya (.mb or .ma) files, Cinema 4D (.c4d) files, and fbx files which can be exported from most animation packages. Click here to learn how to export from your modelling/animation package.
Importing Animations using Animation Splitting
The most convenient way for animators to work is to have a single model containing all animations. When importing the animated model, you can define which frames make up each part of the animation. Unity will automatically split the animation into the individual parts, called Animation Clips.
For example:
- walk animation during frames 1 - 33
- run animation during frames 41 - 57
- kick animation during frames 81 - 97
To import the animations you simply place the model in the Assets folder of your project. Unity will now automatically import it. Highlight it in the Project View and edit the Import Settings in the Inspector.

The Import Settings Dialog for a mesh
In the Import Settings, the Split Animations table is where you tell Unity which frames in your asset file make up which Animation Clip. The names you specify here are used to activate them in your game.
| name | Defines the Animation Clip's name within Unity. |
| start frame | The first frame of the animation. The frame number refers to the same frame as in the 3D program used to create the animation. |
| stop frame | The last frame of the animation. |
| WrapMode | Defines how should time beyond the playback range of the clip be treated (Once, Loop, PingPong, ClampForever). |
| loop frame | If enabled, an extra loop frame is inserted at the end of the animation. This frame matches the first frame in the clip. Use this if you want to make a looping animation and the first & last frames don't match up exactly. |
Importing Animations using multiple model files
The other way to import animations is to follow the @ animation naming scheme. You create separate model files and use this naming convention: 'model name'@'animation name'.fbx

An example of four animation files for an animated character
Unity automatically imports all four files and collects all animations to the file without the @ sign in. In the example above, the goober.mb file will be set up to reference idle, jump, walk and wallJump automatically.
For FBX simply export a model file with no animation ticked e.g. goober.fbx and the 4 clips as goober@animname.fbx by exporting the desired keyframes for each (animation enable in the fbx dialogue)
Importing Inverse Kinematics
When importing animated characters from Maya that are created using IK, you have to check the Bake IK & simulation box in the Import Settings. Otherwise, your character will not animate correctly.
Bringing the character into the Scene
When you have imported your model you drag the object from the Project view into the Scene View or Hierarchy.

The animated character is added by dragging it into the scene
The character above has three animations in the animation list and no default animation. You can add more animations to the character by dragging animation clips from the Project View on to the character (in either the Hierarchy or Scene View). This will also set the default animation. When you hit Play, the default animation will be played.
Materials
There is a close relationship between Materials and Shaders in Unity. Shaders contain code that defines what kind of properties and assets to use. Materials allow you to adjust properties and assign assets.

A Shader is implemented through a Material
To create a new Material, use from the main menu or the Project View context menu. Once the Material has been created, you can apply it to an object and tweak all of its properties in the Inspector. To apply it to an object, just drag it from the Project View to any object in the Scene or Hierarchy.
Setting Material Properties
You can select which Shader you want any particular Material to use. Simply expand the drop-down in the Inspector, and choose your new Shader. The Shader you choose will dictate the available properties to change. The properties can be colors, sliders, textures, numbers, or vectors. If you have applied the Material to an active object in the Scene, you will see your property changes applied to the object in real-time.
There are two ways to apply a Texture to a property.
- Drag it from the Project View on top of the Texture square
- Click the button, and choose the texture from the drop-down list that appears
Two placement options are available for each Texture:
| Tiling | Scales the texture along the different. |
| Offset | Slides the texture around. |
Built-in Shaders
There is a library of built-in Shaders that come standard with every installation of Unity. There are over 30 of these built-in Shaders, and six basic families.
- Normal: For opaque textured objects.
- Transparent: For partly transparent objects. The texture's alpha channel defines the level of transparency.
- TransparentCutOut: For objects that have only fully opaque and fully transparent areas, like fences.
- Self-Illuminated: For objects that have light emitting parts.
- Reflective: For opaque textured objects that reflect an environment Cubemap.
In each group, built-in shaders range by complexity, from the simple VertexLit to the complex Parallax Bumped with Specular. For more information about performance of Shaders, please read the built-in Shader performance page
This grid displays a thumbnail of all built-in Shaders:

The builtin Unity shaders matrix
Shader technical details
Unity has an extensive Shader system, allowing you to tweak the look of all in-game graphics. It works like this:
A Shader basically defines a formula for how the in-game shading should look. Within any given Shader is a number of properties (typically textures). Shaders are implemented through Materials, which are attached directly to individual GameObjects. Within a Material, you will choose a Shader, then define the properties (usually textures and colors, but properties can vary) that are used by the Shader.
This is rather complex, so let's look at a workflow diagram:

On the left side of the graph is the Carbody Shader. 2 different Materials are created from this: Blue car Material and Red car Material. Each of these Materials have 2 textures assigned; the Car Texture defines the main texture of the car, and a Color FX texture. These properties are used by the shader to make the car finish look like 2-tone paint. This can be seen on the front of the red car: it is yellow where it faces the camera and then fades towards purple as the angle increases. The car materials are attached to the 2 cars. The car wheels, lights and windows don't have the color change effect, and must hence use a different Material. At the bottom of the graph there is a Simple Metal Shader. The Wheel Material is using this Shader. Note that even though the same Car Texture is reused here, the end result is quite different from the car body, as the Shader used in the Material is different.
To be more specific, a Shader defines:
- The method to render an object. This includes using different methods depending on the graphics card of the end user.
- Any vertex and fragment programs used to render.
- Some texture properties that are assignable within Materials.
- Color and number settings that are assignable within Materials.
A Material defines:
- Which textures to use for rendering.
- Which colors to use for rendering.
- Any other assets, such as a Cubemap that is required by the shader for rendering.
Shaders are meant to be written by graphics programmers. They are created using the ShaderLab language, which is quite simple. However, getting a shader to work well on a variety graphics cards is an involved job and requires a fairly comprehensive knowledge of how graphics cards work.
A number of shaders are built into Unity directly, and some more come in the Standard Assets Library. If you like, there is plenty more shader information in the Built-in Shader Guide.
Page last updated: 2010-09-16Textures
Textures bring your Meshes, Particles, and interfaces to life! They are image or movie files that you lay over or wrap around your objects. As they are so important, they have a lot of properties. If you are reading this for the first time, jump down to Details, and return to the actual settings when you need a reference.
The shaders you use for your objects put specific requirements on which textures you need, but the basic principle is that you can put any image file inside your project. If it meets the size requirements (specified below), it will get imported and optimized for game use. This extends to multi-layer Photoshop or TIFF files - they are flattened on import, so there is no size penalty for your game.
Properties
The Texture Inspector looks a bit different from most others:
The top section contains a few settings, and the bottom part contains the Texture Importer and the texture preview.
| Aniso Level | Increases texture quality when viewing the texture at a steep angle. Good for floor and ground textures, see below. |
| Filter Mode | Selects how the Texture is filtered when it gets stretched by 3D transformations: |
| Point | The Texture becomes blocky up close |
| Bilinear | The Texture becomes blurry up close |
| Trilinear | Like Bilinear, but the Texture also blurs between the different mip levels |
| Wrap Mode | Selects how the Texture behaves when tiled: |
| Repeat | The Texture repeats (tiles) itself |
| Clamp | The Texture's edges get stretched |
Texture Importer
Textures all come from image files in your Project Folder. How they are imported is specified by the Texture Importer. You change these by selecting the file texture in the Project View and modifying the Texture Importer in the Inspector.
In Unity 3 we simplified for you all the settings, now you just need to select what are you going to use the texture for and Unity will set default parameters for the type of texture you have selected. Of course if you want to have total control of your texture and do specific tweaks, you can set the to . This will present the full set of options that you have available.
| Texture Type | Select this to set basic parameters depending on the purpose of your texture. |
| Texture | This is the most common setting used for all the textures in general. |
| Normal Map | Select this to turn the color channels into a format suitable for real-time normal mapping. For more info, see Normal Maps |
| GUI | Use this if your texture is going to be used on any HUD/GUI Controls. |
| Reflection | Also known as Cube Maps, used to create reflections on textures. check Cubemap Textures for more info. |
| Cookie | This sets up your texture with the basic parameters used for the Cookies of your lights |
| Advanced | Select this when you want to have specific parameters on your texture and you want to have total control over your texture. |

Basic Texture Settings Selected
| Generate Alpha From Grayscale | If enabled, an alpha transparency channel will be generated by the image's existing values of light & dark. |

Normal Map Settings in the Texture Importer
| Generate from Greyscale | |
| Bumpiness | Control the amount of bumpiness. |
| Filtering | Determine how the bumpiness is calculated: |
| Smooth | This generates normal maps that are quite smooth. |
| Sharp | Also known as a Sobel filter. this generates normal maps that are sharper than Standard. |

GUI Settings for the Texture Importer
You dont need to set any values in this case, Unity will set all the values for you.

Reflection Settings in the Texture Importer
| Mapping | This determines how the texture will be mapped to a cubemap. |
| Sphere Mapped | Maps the texture to a "sphere like" cubemap. |
| Cylindrical | Maps the texture to a cylinder, use this when you want to use reflections on objects that are like cylinders. |
| Simple Sphere | Maps the texture to a simple sphere, deforming the reflection when you rotate it. |
| Nice Sphere | Maps the texture to a sphere, deforming it when you rotate but you still can see the texture's wrap |
An interesting way to add a lot of visual detail to your scenes is to use Cookies - greyscale textures you use to control the precise look of in-game lighting. This is fantastic for making moving clouds and giving an impression of dense foliage. The Light page has more info on all this, but the main thing is that for textures to be usable for cookies you just need to set the to Cookie.

Cookie Settings in the Texture Importer
| Light Type | Type of light that the texture will be applied to. (This can be Spotlight, Point or Directional lights). For Directional Lights this texture will tile, so in the texture inspector, you must set the Edge Mode to Repeat; for SpotLights You should keep the edges of your cookie texture solid black in order to get the proper effect. In the Texture Inspector, set the Edge Mode to Clamp. |
| Generate Alpha from Greyscale | If enabled, an alpha transparency channel will be generated by the image's existing values of light & dark. |

The Advanced Texture Importer Settings dialog
| Non Power of 2 | If texture has non-power-of-two size, this will define a scaling behavior at import time (for more info see the Texture Sizes section below): |
| None | Texture will be padded to the next larger power-of-two size for use with GUITexture component. |
| To nearest | Texture will be scaled to the nearest power-of-two size at import time. For instance 257x511 texture will become 256x512. Note that PVRTC formats require textures to be square (width equal to height), therefore final size will be upscaled to 512x512. |
| To larger | Texture will be scaled to the next larger power-of-two size at import time. For instance 257x511 texture will become 512x512. |
| To smaller | Texture will be scaled to the next smaller power-of-two size at import time. For instance 257x511 texture will become 256x256. |
| Generate Cube Map | Generates a cubemap from the texture using different generation methods. |
| Read/Write Enabled | Select this to enable access to the texture data from scripts (GetPixels, SetPixels and other Texture2D functions). Note however that a copy of the texture data will be made, doubling the amount of memory required for texture asset. Use only if absolutely necessary. This is only valid for uncompressed and DTX compressed textures, other types of compressed textures cannot be read from. Disabled by default. |
| Generate Mip Maps | Select this to enable mip-map generation. Mip maps are smaller versions of the texture that get used when the texture is very small on screen. For more info, see Mip Maps below. |
| Correct Gamma | Select this to enable per-mip-level gamma correction. |
| Border Mip Maps | Select this to avoid colors seeping out to the edge of the lower Mip levels. Used for light cookies (see below). |
| Mip Map Filtering | Two ways of mip map filtering are available to optimize image quality: |
| Box | The simplest way to fade out the mipmaps - the mip levels become smoother and smoother as they go down in size. |
| Kaiser | A sharpening Kaiser algorithm is run on the mip maps as they go down in size. If your textures are too blurry in the distance, try this option. |
| Fade Out Mips | Enable this to make the mipmaps fade to gray as the mip levels progress. This is used for detail maps. The left most scroll is the first mip level to begin fading out at. The rightmost scroll defines the mip level where the texture is completely grayed out |
| Generate Normal Map | Enable this to turn the color channels into a format suitable for real-time normal mapping. For more info, see Normal Maps, below. |
| Bumpiness | Control the amount of bumpiness. |
| Filtering | Determine how the bumpiness is calculated: |
| Smooth | This generates normal maps that are quite smooth. |
| Sharp | Also known as a Sobel filter. this generates normal maps that are sharper than Standard. |
| Normal Map | Select this if you want to see how the normal map will be applied to your texture. |
| Lightmap | Select this if you want to use the texture as a lightmap. |
Per-Platform Overrides
When you are building for different platforms, you have to think on the resolution of your textures for the target platform, the size and the quality. With Unity 3 you can override these options and assign specific values depending on the platform you are deploying to. Note that if you don't select any value to override, the Editor will pick the default values when building your project.

Default settings for all platforms.
| Max Texture Size | The maximum imported texture size. Artists often prefer to work with huge textures - scale the texture down to a suitable size with this. |
| Texture Format | What internal representation is used for the texture. This is a tradeoff between size and quality. In the examples below we show the final size of a in-game texture of 256 by 256 pixels: |
| Compressed | Compressed RGB texture. This is the most common format for diffuse textures. 4 bits per pixel (32 KB for a 256x256 texture). |
| 16 bit | Low-quality truecolor. Has 16 levels of red, green, blue and alpha. |
| Truecolor | Truecolor, this is the highest quality. At 256 KB for a 256x256 texture. |
If you have set the to then the has different values.
Desktop
| Texture Format | What internal representation is used for the texture. This is a tradeoff between size and quality. In the examples below we show the final size of an in-game texture of 256 by 256 pixels: |
| RGB Compressed DXT1 | Compressed RGB texture. This is the most common format for diffuse textures. 4 bits per pixel (32 KB for a 256x256 texture). |
| RGBA Compressed DXT5 | Compressed RGBA texture. This is the main format used for diffuse & specular control textures. 1 byte/pixel (64 KB for a 256x256 texture). |
| RGB 16 bit | 65 thousand colors with no alpha. Compressed DXT formats use less memory and usually look better. 128 KB for a 256x256 texture. |
| RGB 24 bit | Truecolor but without alpha. 192 KB for a 256x256 texture. |
| Alpha 8 bit | High quality alpha channel but without any color. 64 KB for a 256x256 texture. |
| RGBA 16 bit | Low-quality truecolor. Has 16 levels of red, green, blue and alpha. Compressed DXT5 format uses less memory and usually looks better. 128 KB for a 256x256 texture. |
| RGBA 32 bit | Truecolor with alpha - this is the highest quality. At 256 KB for a 256x256 texture, this one is expensive. Most of the time, DXT5 offers sufficient quality at a much smaller size. The main way this is used is for normal maps, as DXT compression there often carries a visible quality loss. |
iOS
| Texture Format | What internal representation is used for the texture. This is a tradeoff between size and quality. In the examples below we show the final size of a in-game texture of 256 by 256 pixels: |
| RGB Compressed PVRTC 4 bits | Compressed RGB texture. This is the most common format for diffuse textures. 4 bits per pixel (32 KB for a 256x256 texture) |
| RGBA Compressed PVRTC 4 bits | Compressed RGBA texture. This is the main format used for diffuse & specular control textures or diffuse textures with transparency. 4 bits per pixel (32 KB for a 256x256 texture) |
| RGB Compressed PVRTC 2 bits | Compressed RGB texture. Lower quality format suitable for diffuse textures. 2 bits per pixel (16 KB for a 256x256 texture) |
| RGBA Compressed PVRTC 2 bits | Compressed RGBA texture. Lower quality format suitable for diffuse & specular control textures. 2 bits per pixel (16 KB for a 256x256 texture) |
| RGB Compressed DXT1 | Compressed RGB texture. This format is not supported on iOS, but kept for backwards compatibility with desktop projects. |
| RGBA Compressed DXT5 | Compressed RGBA texture. This format is not supported on iOS, but kept for backwards compatibility with desktop projects. |
| RGB 16 bit | 65 thousand colors with no alpha. Uses more memory than PVRTC formats, but could be more suitable for UI or crisp textures without gradients. 128 KB for a 256x256 texture. |
| RGB 24 bit | Truecolor but without alpha. 192 KB for a 256x256 texture. |
| Alpha 8 bit | High quality alpha channel but without any color. 64 KB for a 256x256 texture. |
| RGBA 16 bit | Low-quality truecolor. Has 16 levels of red, green, blue and alpha. Uses more memory than PVRTC formats, but can be handy if you need exact alpha channel. 128 KB for a 256x256 texture. |
| RGBA 32 bit | Truecolor with alpha - this is the highest quality. At 256 KB for a 256x256 texture, this one is expensive. Most of the time, PVRTC formats offers sufficient quality at a much smaller size. |
Android
| Texture Format | What internal representation is used for the texture. This is a tradeoff between size and quality. In the examples below we show the final size of a in-game texture of 256 by 256 pixels: |
| RGB Compressed DXT1 | Compressed RGB texture. Supported by Nvidia Tegra. 4 bits per pixel (32 KB for a 256x256 texture). |
| RGBA Compressed DXT5 | Compressed RGBA texture. Supported by Nvidia Tegra. 6 bits per pixel (64 KB for a 256x256 texture). |
| RGB Compressed ETC 4 bits | Compressed RGB texture. This is the default texture format for Android projects. ETC1 is part of OpenGL ES 2.0 and is supported by all OpenGL ES 2.0 GPUs. It does not support alpha. 4 bits per pixel (32 KB for a 256x256 texture) |
| RGB Compressed PVRTC 2 bits | Compressed RGB texture. Supported by Imagination PowerVR GPUs. 2 bits per pixel (16 KB for a 256x256 texture) |
| RGBA Compressed PVRTC 2 bits | Compressed RGBA texture. Supported by Imagination PowerVR GPUs. 2 bits per pixel (16 KB for a 256x256 texture) |
| RGB Compressed PVRTC 4 bits | Compressed RGB texture. Supported by Imagination PowerVR GPUs. 4 bits per pixel (32 KB for a 256x256 texture) |
| RGBA Compressed PVRTC 4 bits | Compressed RGBA texture. Supported by Imagination PowerVR GPUs. 4 bits per pixel (32 KB for a 256x256 texture) |
| RGB Compressed ATC 4 bits | Compressed RGB texture. Supported by Qualcomm Snapdragon. 4 bits per pixel (32 KB for a 256x256 texture). |
| RGBA Compressed ATC 8 bits | Compressed RGBA texture. Supported by Qualcomm Snapdragon. 6 bits per pixel (64 KB for a 256x256 texture). |
| RGB 16 bit | 65 thousand colors with no alpha. Uses more memory than the compressed formats, but could be more suitable for UI or crisp textures without gradients. 128 KB for a 256x256 texture. |
| RGB 24 bit | Truecolor but without alpha. 192 KB for a 256x256 texture. |
| Alpha 8 bit | High quality alpha channel but without any color. 64 KB for a 256x256 texture. |
| RGBA 16 bit | Low-quality truecolor. The default compression for the textures with alpha channel. 128 KB for a 256x256 texture. |
| RGBA 32 bit | Truecolor with alpha - this is the highest quality compression for the textures with alpha. 256 KB for a 256x256 texture. |
Unless you're targeting a specific hardware, like Tegra, we'd recommend using ETC1 compression. If needed you could store an external alpha channel and still benefit from lower texture footprint. If you absolutely want to store an alpha channel in a texture, RGBA16 bit is the compression supported by all hardware vendors.
If your app utilizes an unsupported texture compression, the textures will be uncompressed to RGBA 32 and stored in memory along with the compressed ones. So in this case you lose time decompressing textures and lose memory storing them twice. It may also have a very negative impact on rendering performance.
Details
Supported Formats
Unity can read the following file formats: PSD, TIFF, JPG, TGA, PNG, GIF, BMP, IFF, PICT. It should be noted that Unity can import multi-layer PSD & TIFF files just fine. They are flattened automatically on import but the layers are maintained in the assets themselves, so you don't lose any of your work when using these file types natively. This is important as it allows you to just have one copy of your textures that you can use from Photoshop, through your 3D modelling app and into Unity.
Texture Sizes
Ideally texture sizes should be powers of two on the sides. These sizes are as follows: 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 or 2048 pixels. The textures do not have to be square, i.e. width can be different from height.
It is possible to use other (non power of two) texture sizes with Unity. Non power of two texture sizes work best when used on GUI Textures, however if used on anything else they will be converted to an uncompressed RGBA 32 bit format. That means they will take up more video memory (compared to PVRT(iOS)/DXT(Desktop) compressed textures), will be slower to load and slower to render (if you are on iOS mode). In general you'll use non power of two sizes only for GUI purposes.
Non power of two texture assets can be scaled up at import time using the Non Power of 2 option in the advanced texture type in the import settings. Unity will scale texture contents as requested, and in the game they will behave just like any other texture, so they can still be compressed and very fast to load.
UV Mapping
When mapping a 2D texture onto a 3D model, some sort of wrapping is done. This is called UV mapping and is done in your 3D modelling app. Inside Unity, you can scale and move the texture using Materials. Scaling normal & detail maps is especially useful.
Mip Maps
Mip Maps are a list of progressively smaller versions of an image, used to optimise performance on real-time 3D engines. Objects that are far away from the camera use the smaller texture versions. Using mip maps uses 33% more memory, but not using them can be a huge performance loss. You should always use mipmaps for in-game textures; the only exceptions are textures that will never be minified (e.g. GUI textures).
Normal Maps
Normal maps are used by normal map shaders to make low-polygon models look as if they contain more detail. Unity uses normal maps encoded as RGB images. You also have the option to generate a normal map from a grayscale height map image.
Detail Maps
If you want to make a terrain, you normally use your main texture to show where there are areas of grass, rocks sand, etc... If your terrain has a decent size, it will end up very blurry. Detail textures hide this fact by fading in small details as your main texture gets up close.
When drawing detail textures, a neutral gray is invisible, white makes the main texture twice as bright and black makes the main texture completely black.
Reflections (Cube Maps)
If you want to use texture for reflection maps (e.g. use the Reflective builtin shaders), you need to use Cubemap Textures.
Anisotropic filtering
Anisotropic filtering increases texture quality when viewed from a grazing angle, at some expense of rendering cost (the cost is entirely on the graphics card). Increasing anisotropy level is usually a good idea for ground and floor textures. In Quality Settings anisotropic filtering can be forced for all textures or disabled completely.
No anisotropy (left) / Maximum anisotropy (right) used on the ground texture
Procedural Materials
Unity incorporates a new asset type known as Procedural Materials. These are essentially the same as standard Materials except that the textures they use can be generated at runtime rather than being predefined and stored.
The script code that generates a texture procedurally will typically take up much less space in storage and transmission than a bitmap image and so Procedural Materials can help reduce download times. Additionally, the generation script can be equipped with parameters that can be changed in order to vary the visual properties of the material at runtime. These properties can be anything from color variations to the size of bricks in a wall. Not only does this mean that many variations can be generated from a single Procedural Material but also that the material can be animated on a frame-by-frame basis. Many interesting visual effects are possible - imagine a character gradually turning to stone or acid damaging a surface as it touches.
Unity's Procedural Material system is based around an industry standard product called Substance, developed by Allegorithmic
Supported Platforms
In Unity, Procedural Materials are fully supported for standalone and webplayer build targets only (Windows and Mac OS X). For all other platforms, Unity will pre-render or bake them into ordinary Materials during the build. Although this clearly negates the runtime benefits of procedural generation, it is still useful to be able to create variations on a basic material in the editor.
Adding Procedural Materials to a Project
A Procedural Material is supplied as a Substance Archive file (SBSAR) which you can import like any other asset (drag and drop directly onto the Assets folder or use ). A Substance Archive asset contains one or more Procedural Materials and contains all the scripts and images required by these. Uncompiled SBS files are not supported.
Although they are implemented differently, Unity handles a Procedural Material just like any other Material. To assign a Procedural Material to a mesh, for example, you just drag and drop it onto the mesh exactly as you would with any other Material.
Procedural Properties
Each Procedural Material is a custom script which generates a particular type of material. These scripts are similar to Unity scripts in that they can have variables exposed for assignment in the inspector. For example, a "Brick Wall" Procedural Material could expose properties that let you set the number of courses of bricks, the colors of the bricks and the color of the mortar. This potentially offers infinite material variations from a single asset. These properties can also be set from a script at runtime in much the same way as the public variables of a MonoBehaviour script.
Procedural Materials can also incorporate complex texture animation. For example, you could animate the hands of the clock or cockroaches running across a floor.

Creating Procedural Materials From Scratch
Procedural Materials can work with any combination of procedurally generated textures and stored bitmaps. Additionally, included bitmap images can be filtered and modified before use. Unlike a standard Material, a Procedural Material can use vector images in the form of SVG files which allows for resolution-independent textures.
The design tools available for creating Procedural Materials from scratch use visual, node-based editing similar to the kind found in artistic tools. This makes creation accessible to artists who may have little or no coding experience. As an example, here is a screenshot from Allegorithmic's Substance Designer which shows a "brick wall" Procedural Material under construction:

Obtaining Procedural Materials
Since Unity's Procedural Materials are based on the industry standard Substance product, Procedural Material assets are readily available from internet sources, including Unity's own Asset Store. Allegorithmic's Substance Designer can be used to create Procedural Materials, but there are other applications (3D modelling apps, for example) that incorporate the Substance technology and work just as well with Unity.
Performance and Optimization
Procedural Materials inherently tend to use less storage than bitmap images. However, the trade-off is that they are based around scripts and running those scripts to generate materials requires some CPU and GPU resources. The more complex your Procedural Materials are, the greater their runtime overhead.
Procedural Materials support a form of caching whereby the material is only updated if its parameters have changed since it was last generated. Further to this, some materials may have many properties that could theoretically be changed and yet only a few will ever need to change at runtime. In such cases, you can inform Unity about the variables that will not change to help it cache as much data as possible from the previous generation of the material. This will often improve performance significantly.
Procedural Materials can also be used purely as a convenience in the editor (ie, you can generate a standard Material by setting the parameters of a Procedural Material and then "baking" it). This will remove the runtime overhead of material generation but naturally, the baked materials can't be changed or animated during gameplay.
Using the Substance Player to Analyze Performance
Since the complexity of a Procedural Material can affect runtime performance, Allegorithmic incorporates profiling features in its Substance Player tool. This tool is available to download for free from Allegorithmic’s website.
Substance Player uses the same optimized rendering engine as the one integrated into Unity, so its rendering measurement is more representative of performance in Unity than that of Substance Designer.
Page last updated: 2011-11-23Video Files
Note: This is a Pro/Advanced feature only.
Desktop
Movie Textures are animated Textures that are created from a video file. By placing a video file in your project's , you can import the video to be used exactly as you would use a regular Texture.
Video files are imported via Apple QuickTime. Supported file types are what your QuickTime installation can play (usually .mov, .mpg, .mpeg, .mp4, .avi, .asf). On Windows movie importing requires Quicktime to be installed (download here).
Properties
The Movie Texture Inspector is very similar to the regular Texture Inspector.

Video files are Movie Textures in Unity
| Aniso Level | Increases Texture quality when viewing the texture at a steep angle. Good for floor and ground textures |
| Filtering Mode | Selects how the Texture is filtered when it gets stretched by 3D transformations |
| Loop | If enabled, the movie will loop when it finishes playing |
| Quality | Compression of the Ogg Theora video file. A higher value means higher quality, but larger file size |
Details
When a video file is added to your Project, it will automatically be imported and converted to Ogg Theora format. Once your Movie Texture has been imported, you can attach it to any GameObject or Material, just like a regular Texture.
Playing the Movie
Your Movie Texture will not play automatically when the game begins running. You must use a short script to tell it when to play.
// this line of code will make the Movie Texture begin playing renderer.material.mainTexture.Play();
Attach the following script to toggle Movie playback when the space bar is pressed:
function Update () {
if (Input.GetButtonDown ("Jump")) {
if (renderer.material.mainTexture.isPlaying) {
renderer.material.mainTexture.Pause();
}
else {
renderer.material.mainTexture.Play();
}
}
}
For more information about playing Movie Textures, see the Movie Texture Script Reference page
Movie Audio
When a Movie Texture is imported, the audio track accompanying the visuals are imported as well. This audio appears as an AudioClip child of the Movie Texture.

The video's audio track appears as a child of the Movie Texture in the Project View
To play this audio, the Audio Clip must be attached to a GameObject, like any other Audio Clip. Drag the Audio Clip from the Project View onto any GameObject in the Scene or Hierarchy View. Usually, this will be the same GameObject that is showing the Movie. Then use audio.Play() to make the the movie's audio track play along with its video.
iOS
Movie Textures are not supported on iOS. Instead, full-screen streaming playback is provided using iPhoneUtils.PlayMovie and iPhoneUtils.PlayMovieURL.
You can import your video file just like a regular asset or alternatively you can specify a network-based URL to play a movie located on a remote server.
You need to keep your videos inside the StreamingAssets folder located in your Project directory.
Unity iOS supports any movie file types that play correctly on an iOS device, implying files with the extensions .mov, .mp4, .mpv, and .3gp and using one of the following compression standards:
- H.264 Baseline Profile Level 3.0 video
- MPEG-4 Part 2 video
For more information about supported compression standards, consult the iPhone SDK MPMoviePlayerController Class Reference.
As soon as you call iPhoneUtils.PlayMovie or iPhoneUtils.PlayMovieURL, the screen will fade from your current content to the designated background color. It might take some time before the movie is ready to play but in the meantime, the player will continue displaying the background color and may also display a progress indicator to let the user know the movie is loading. When playback finishes, the screen will fade back to your content.
The video player does not respect switching to mute while playing videos
As written above, video files are played using Apple's embedded player (as of SDK 3.2 and iPhone OS 3.1.2 and earlier). This contains a bug that prevents Unity switching to mute.
The video player does not respect the device's orientation
The Apple video player and iPhone SDK do not provide a way to adjust the orientation of the video. A common approach is to manually create two copies of each movie in landscape and portrait orientations. Then, the orientation of the device can be determined before playback so the right version of the movie can be chosen.
Android
Movie Textures are not supported on Android. Instead, full-screen streaming playback is provided using iPhoneUtils.PlayMovie and iPhoneUtils.PlayMovieURL.
You can import your video file just like a regular asset or alternatively you can specify a network-based URL to play a movie located on a remote server.
You need to keep your videos inside of the StreamingAssets folder located in your Project directory.
Unity Android supports any movie file type supported by Android, (ie, files with the extensions .mp4 and .3gp) and using one of the following compression standards:
- H.263
- H.264 AVC
- MPEG-4 SP
However, device vendors are keen on expanding this list, so some Android devices are able to play formats other than those listed, such as HD videos.
For more information about the supported compression standards, consult the Android SDK Core Media Formats documentation.
As soon as you call iPhoneUtils.PlayMovie or iPhoneUtils.PlayMovieURL, the screen will fade from your current content to the designated background color. It might take some time before the movie is ready to play. In the meantime, the player will continue displaying the background color and may also display a progress indicator to let the user know the movie is loading. When playback finishes, the screen will fade back to your content.
Audio Files
As with Meshes or Textures, the workflow for Audio File assets is designed to smooth and trouble free. Unity can import almost every common file format but there are a few details that are useful to be aware of when working with Audio Files.
Audio in Unity is either Native or Compressed. Unity supports most common formats (see the list below) and will import an audio file when it is added to the project. The default mode is Native, where the audio data from the original file is imported unchanged. However, Unity can also compress the audio data on import, simply by enabling the Compressed option in the importer. (iOS projects can make use of the hardware decoder - see the iOS documentation for further details). The difference between Native and Compressed modes are as follows:-
- Native: Use Native (WAV, AIFF) audio for short sound effects. The audio data will be larger but sounds won't need to be decoded at runtime.
- Compressed: The audio data will be small but will need to be decompressed at runtime, which entails a processing overhead. Depending on the target, Unity will encode the audio to either Ogg Vorbis(Mac/PC/Consoles) or MP3 (Mobile platforms). For the best sound quality, supply the audio in an uncompressed format such as WAV or AIFF (containing PCM data) and let Unity do the encoding. If you are targeting Mac and PC platforms only (including both standalones and webplayers) then importing an Ogg Vorbis file will not degrade the quality. However, on mobile platforms, Ogg Vorbis and MP3 files will be re-encoded to MP3 on import, which will introduce a slight quality degradation.
Any Audio File imported into Unity is available from scripts as an Audio Clip instance, which is effectively just a container for the audio data. The clips must be used in conjunction with Audio Sources and an Audio Listener in order to actually generate sound. When you attach your clip to an object in the game, it adds an Audio Source component to the object, which has Volume, Pitch and a numerous other properties. While a Source is playing, an Audio Listener can "hear" all sources within range, and the combination of those sources gives the sound that will actually be heard through the speakers. There can be only one Audio Listener in your scene, and this is usually attached to the Main Camera.
Supported Formats
| Format | Compressed as (Mac/PC) | Compressed as (Mobile) |
|---|---|---|
| MPEG(1/2/3) | Ogg Vorbis | MP3 |
| Ogg Vorbis | Ogg Vorbis | MP3 |
| WAV | Ogg Vorbis | MP3 |
| AIFF | Ogg Vorbis | MP3 |
| MOD | - | - |
| IT | - | - |
| S3M | - | - |
| XM | - | - |
See the Sound chapter in the Creating Gameplay section of this manual for more information on using sound in Unity.
Audio Clip
Audio Clips contain the audio data used by Audio Sources. Unity supports mono, stereo and multichannel audio assets (up to eight channels). The audio file formats that Unity can import are .aif, .wav, .mp3, and .ogg. Unity can also import tracker modules in the .xm, .mod, .it, and .s3m formats. The tracker module assets behave the same way as any other audio assets in Unity although no waveform preview is available in the asset import inspector.

The Audio Clip Inspector
Properties
| Audio Format | The specific format that will be used for the sound at runtime. |
| Native | This option offers higher quality at the expense of larger file size and is best for very short sound effects. |
| Compressed | The compression results in smaller files but with somewhat lower quality compared to native audio. This format is best for medium length sound effects and music. |
| 3D Sound | If enabled, the sound will play back in 3D space. Both Mono and Stereo sounds can be played in 3D. |
| Force to mono | If enabled, the audio clip will be down-mixed to a single channel sound. |
| Load Type | The method Unity uses to load audio assets at runtime. |
| Decompress on load | Audio files will be decompressed as soon as they are loaded. Use this option for smaller compressed sounds to avoid the performance overhead of decompressing on the fly. Be aware that decompressing sounds on load will use about ten times more memory than keeping them compressed, so don't use this option for large files. |
| Compressed in memory | Keep sounds compressed in memory and decompress while playing. This option has a slight performance overhead (especially for Ogg/Vorbis compressed files) so only use it for bigger files where decompression on load would use a prohibitive amount of memory. |
| Stream from disc | Stream audio data directly from disc. The memory used by this option is typically a small fraction of the file size, so it is very useful for music or other very long tracks. For performance reasons, it is usually advisable to stream only one or two files from disc at a time but the of streams that can comfortably be handled depends on the hardware. |
| Compression | Amount of Compression to be applied to a Compressed clip. Statistics about the file size can be seen under the slider. A good approach to tuning this value is to drag the slider to a place that leaves the playback "good enough" while keeping the file small enough for your distribution requirements. |
| Hardware Decoding | (iOS only) On iOS devices, Apple's hardware decoder can be used resulting in lower CPU overhead during decompression. Check out platform specific details for more info. |
| Gapless looping | (Android/iOS only) Use this when compressing a seamless looping audio source file (in a non-compressed PCM format) to ensure perfect continuity is preserved at the seam. Standard MPEG encoders introduce a short silence at the loop point, which will be audible as a brief "click" or "pop". |
Importing Audio Assets
Unity supports both Compressed and Native Audio. Any type of file (except MP3/Ogg Vorbis) will be initially imported as Native. Compressed audio files must be decompressed by the CPU while the game is running, but have smaller file size. If Stream is checked the audio is decompressed on the fly, otherwise it is decompressed completely as soon as it loads. Native PCM formats (WAV, AIFF) have the benefit of giving higher fidelity without increasing the CPU overhead, but files in these formats are typically much larger than compressed files. Module files (.mod,.it,.s3m..xm) can deliver very high quality with an extremely low footprint.
As a general rule of thumb, Compressed audio (or modules) are best for long files like background music or dialog, while Native is better for short sound effects. You should tweak the amount of Compression using the compression slider. Start with high compression and gradually reduce the setting to the point where the loss of sound quality is perceptible. Then, increase it again slightly until the perceived loss of quality disappears.
Using 3D Audio
If an audio clip is marked as a 3D Sound then it will be played back so as to simulate its position in the game world's 3D space. 3D sounds emulate the distance and location of sounds by attenuating volume and panning across speakers. Both mono and multiple channel sounds can be positioned in 3D. For multiple channel audio, use the spread option on the Audio Source to spread and split out the discrete channels in speaker space. Unity offers a variety of options to control and fine-tune the audio behavior in 3D space - see the Audio Source component reference for further details.
Platform specific details
iOS
On mobile platforms compressed audio is encoded as MP3 to take advantage of hardware decompression.
To improve performance, audio clips can be played back using the Apple hardware codec. To enable this option, check the "Hardware Decoding" checkbox in the Audio Importer. Note that only one hardware audio stream can be decompressed at a time, including the background iPod audio.
If the hardware decoder is not available, the decompression will fall back on the software decoder (on iPhone 3GS or later, Apple's software decoder is used in preference to Unity's own decoder (FMOD)).
Android
On mobile platforms compressed audio is encoded as MP3 to take advantage of hardware decompression.
TrackerModules
Tracker Modules are essentially just packages of audio samples that have been modeled, arranged and sequenced programatically. The concept was introduced in the 1980's (mainly in conjunction with the Amiga computer) and has been popular since the early days of game development and demo culture.
Tracker Module files are similar to MIDI files in many ways. The tracks are scores that contain information about when to play the instruments, and at what pitch and volume and from this, the melody and rhythm of the original tune can be recreated. However, MIDI has a disadvantage in that the sounds are dependent on the sound bank available in the audio hardware, so MIDI music can sound different on different computers. In contrast, tracker modules include high quality PCM samples that ensure a similar experience regardless of the audio hardware in use.
Supported formats
Unity supports the four most common module file formats, namely Impulse Tracker (.it), Scream Tracker (.s3m), Extended Module File Format (.xm), and the original Module File Format (.mod).
Benefits of Using Tracker Modules
Tracker module files differ from mainstream PCM formats (.aif, .wav, .mp3, and .ogg) in that they can be very small without a corresponding loss of sound quality. A single sound sample can be modified in pitch and volume (and can have other effects applied), so it essentially acts as an "instrument" which can play a tune without the overhead of recording the whole tune as a sample. As a result, tracker modules lend themselves to games, where music is required but where a large file download would be a problem.
Third Party Tools and Further References
Currently, the most popular tools to create and edit Tracker Modules are MilkyTracker for OSX and OpenMPT for Windows. For more information and discussion, please see the blog post .mod in Unity from June 2010.
Page last updated: 2011-11-15Scripting
This is a short introduction on how to create and utilize scripts in a project. For detailed information about the Scripting API, please view the Scripting Reference. For detailed information about creating game play through scripting, please view the Creating Gameplay page of this manual.
Scripting inside Unity is done by writing simple behaviour scripts in JavaScript, C#, or Boo. You can use one or all scripting languages in a single project, there is no penalty for using more than one. Unless stated otherwise, all the scripting examples are in JavaScript.
Creating New Scripts
Unlike other assets like Meshes or Textures, Script files can be created from within Unity. To create a new script, open the (or or ) from the main menu. This will create a new script called NewBehaviourScript and place it in the selected folder in Project View. If no folder is selected in Project View, the script will be created at the root level.

You can edit the script by double-clicking on it in the Project View. This will launch your default selected editor in Unity's preferences. You do all your scripting in an external text editor, and not in Unity directly. To set the default script editor, change the drop-down item in .
These are the contents of a new, empty behaviour script:
function Update () {
}
A new, empty script does not do a lot on its own, so let's add some functionality. Change the script to read the following:
function Update () {
print("Hello World");
}
When executed, this code will print "Hello World" to the console. But there is nothing that causes the code to be executed yet. We have to attach the script to an active GameObject in the Scene before it will be executed.
Attaching scripts to objects
Save the above script and create a new object in the Scene by selecting . This will create a new GameObject called "Cube" in the current Scene.

Now drag the script from the Project View to the Cube (in the Scene or Hierarchy View, it doesn't matter). You can also select the Cube and choose . Either of these methods will attach the script to the Cube. Every script you create will appear in the menu. If you have changed the name of your script, you will that name instead.

If you select the Cube and look at the Inspector, you will see that the script is now visible. This means it has been attached.

Press Play to test your creation. You should see the text "Hello World" appear beside the Play/Pause/Step buttons. Exit play mode when you see it.

Manipulating the GameObject
A print() statement can be very handy when debugging your script, but it does not manipulate the GameObject it is attached to. Let's change the script to add some functionality:
function Update () {
transform.Rotate(0, 5*Time.deltaTime, 0);
}
If you're new to scripting, it's okay if this looks confusing. These are the important concepts to understand:
- function Update () {} is a container for code that Unity executes multiple times per second (once per frame).
- transform is a reference to the GameObject's Transform Component.
- Rotate() is a function contained in the Transform Component.
- The numbers in-between the commas represent the degrees of rotation around each axis of 3D space: X, Y, and Z.
- Time.deltaTime is a member of the Time class that evens out movement over one second, so the cube will rotate at the same speed no matter how many frames per second your machine is rendering. Therefore, 5 * Time.deltaTime means 5 degrees per second.
With all this in mind, we can read this code as "every frame, rotate this GameObject's Transform component a small amount so that it will equal five degrees around the Y axis each second."
You can access lots of different Components the same way as we accessed transform already. You have to add Components to the GameObject using the menu. All the Components you can easily access are listed under Variables on the GameObject Scripting Reference Page.
For more information about the relationship between GameObjects, Scripts, and Components, please jump ahead to the GameObjects page or Using Components page of this manual.
The Power of Variables
Our script so far will always rotate the Cube 5 degrees each second. We might want it to rotate a different number of degrees per second. We could change the number and save, but then we have to wait for the script to be recompiled and we have to enter Play mode before we see the results. There is a much faster way to do it. We can experiment with the speed of rotation in real-time during Play mode, and it's easy to do.
Instead of typing 5 into the Rotate() function, we will declare a speed variable and use that in the function. Change the script to the following code and save it:
var speed = 5.0;
function Update () {
transform.Rotate(0, speed*Time.deltaTime, 0);
}
Note that this is an example in Javascript. C# users should replace the keyword var with the type int. Now select the Cube and look at the Inspector. Notice how our speed variable appears.

This variable can now be modified directly in the Inspector, just like renaming a file in the file explorer. Select it, press and change the value. You can also right- or option-click on the value and drag the mouse up or down. You can change the variable at any time, even while the game is running.
Hit Play and try modifying the speed value. The Cube's rotation speed will change instantly. When you exit Play mode, you'll see that your changes are reverted back to their value before entering Play mode. This way you can play, adjust, and experiment to find the best value, then apply that value permanently.
Using this method of changing a variable's value in the Inspector means that you can re-use one script on many objects, each with a different variable value. If you attach the script to multiple Cubes, and change the speed of each cube, they will all rotate at different speeds even though they use the same script.
Accessing Other Components
When writing a script Component, you can access other components on the GameObject from within that script.
Using the GameObject members
You can directly access any member of the GameObject class. You can see a list of all the GameObject class members here. If any of the indicated classes are attached to the GameObject as a Component, you can access that Component directly through the script by simply typing the member name. For example, typing transform is equivalent to gameObject.transform. The gameObject is assumed by the compiler, unless you specifically reference a different GameObject.
Typing this will be accessing the script Component that you are writing. Typing this.gameObject is referring to the GameObject that the script is attached to. You can access the same GameObject by simply typing gameObject. Logically, typing this.transform is the same as typing transform. If you want to access a Component that is not included as a GameObject member, you have to use gameObject.GetComponent() which is explained on the next page.
There are many Components that can be directly accessed in any script. For example, if you want to access the Translate function of the Transform component, you can just write transform.Translate() or gameObject.transform.Translate(). This works because all scripts are attached to a GameObject. So when you write transform you are implicitly accessing the Transform Component of the GameObject that is being scripted. To be explicit, you write gameObject.transform. There is no advantage in one method over the other, it's all a matter of preference for the scripter.
To see a list of all the Components you can access implicitly, take a look at the GameObject page in the Scripting Reference.
Using GetComponent()
There are many Components which are not referenced directly as members of the GameObject class. So you cannot access them implicitly, you have to access them explicitly. You do this by calling the GetComponent("component name") and storing a reference to the result. This is most common when you want to make a reference to another script attached to the GameObject.
Pretend you are writing Script B and you want to make a reference to Script A, which is attached to the same GameObject. You would have to use GetComponent() to make this reference. In Script B, you would simply write:
scriptA = GetComponent("ScriptA");
For more help with using GetComponent(), take a look at the GetComponent() Script Reference page.
Accessing variables in other script Components
All scripts attached to your GameObjects are Components. Therefore to get access to a public variable (and methods) in a script you make use of the GetComponent method. For example:
function Start () {
// Print the position of the transform component, for the gameObject this script is attached to
Debug.Log(gameObject.GetComponent<Transform>.().position);
}
In the previous example the GetComponent<T>. function is used to access the position property of the Transform component. The same technique can be used to access a variable in a custom script Component:
(MyClass.js)
public var speed : float = 3.14159;
(MyOtherClass.js)
function Start () {
// Print the speed variable from the MyClass script Component attached to the gameObject
Debug.Log(gameObject.GetComponent<MyClass>.().speed);
}
Accessing a variable defined in C# from Javascript
To access variables defined in C# scripts the compiled Assembly containing the C# code must exist when the Javascript code is compiled. Unity performs the compilation in different stages as described in the Script Compilation section in the Scripting Reference. If you want to create a Javascript that uses classes or variables from a C# script just place the C# script in the "Standard Assets", "Pro Standard Assets" or "Plugins" folder and the Javascript outside of these folders. The code inside the "Standard Assets", "Pro Standard Assets" or "Plugins" is compiled first and the code outside is compiled in a later step making the Types defined in the compilation step (your C# script) available to later compilation steps (your Javascript script).
In general the code inside the "Standard Assets", "Pro Standard Assets" or "Plugins" folders, regardless of the language (C#, Javascript or Boo), will be compiled first and available to scripts in subsequent compilation steps.
Optimizing variable access
In some circumstances you may be using GetComponent multiple times in your code, or multiple times per frame. Every call to GetComponent does a few extra steps internally to get the reference to the component you require. A more efficient approach is to store the reference to the component for example in your Start() function. As you will be storing the reference and not retrieving directly it is always good practice to check for null references:
(MyClass.js)
public var speed : float = 3.14159;
(MyOtherClass.js)
private var myClass : MyClass;
function Start () {
// Get a reference to the MyClass script Component attached to the gameObject
myClass = gameObject.GetComponent<MyClass>.();
}
function Update () {
// Verify that the reference is still valid and print the speed variable
if(myClass != null)
Debug.Log (myClass.speed);
}
Static Variables
It is also possible to declare variables in your classes as static. There will exist one and only one instance of a static variable for a specific class and it can be modified without the need of an instance of a class object:
(MyClass.js)
static public var speed : float = 3.14159;
(MyOtherClass.js)
function Start () {
Debug.Log (MyClass.speed);
}
It is recommended to not use static variables for object references to make sure unused objects are removed from memory.
Where to go from here
This was just a short introduction on how to use scripts inside the Editor. For more examples, check out the Tutorials that come with Unity. You should also read through Scripting Overview inside the Script Reference, which contains a more thorough introduction into scripting with Unity plus pointers into the reference itself for in-depth information. If you're really stuck, be sure to visit the Unity Answers or Unity Forums and ask questions there. Someone is always willing to help.
Page last updated: 2011-10-20Asset Store
Unity's Asset Store is home to a growing library of free and commercial assets created both by Unity Technologies and also members of the community. A wide variety of assets is available, covering everything from textures, models and animations to whole project examples, tutorials and Editor extensions. The assets are accessed from a simple interface built into the Unity Editor and are downloaded and imported directly into your project.
Access and Navigation
You can open the Asset Store window by selecting from the main menu. On your first visit, you will be prompted to create a free user account which you will use to access the Store subsequently.

The Asset Store front page.
The Store provides a browser-like interface which allows you to navigate either by free text search or by browsing packages and categories. To the left of the main tool bar are the familiar browsing buttons for navigating through the history of viewed items:-

To the right of these are buttons for viewing the Download Manager and for viewing the current contents of your shopping cart.

The Download Manager allows you to view the packages you have already bought and also to find and install any updates. Additionally, the standard packages supplied with Unity can be viewed and added to your project with the same interface.

The Download Manager.
Location of Downloaded Asset Files
You will rarely, if ever, need to access the files downloaded from the Asset Store directly. However, if you do need to, you can find them in
~/Library/Unity/Asset Store
...on the Mac and in
C:\Users\accountName\AppData\Roaming\Unity\Asset Store
...on Windows. These folders contain subfolders that correspond to particular Asset Store vendors - the actual asset files are contained in the appropriate subfolders.
Page last updated: 2011-12-09Asset Server
Unity Asset Server Overview
The Unity Asset Server is an asset and version control system with a graphical user interface integrated into Unity. It is meant to be used by team members working together on a project on different computers either in-person or remotely. The Asset Server is highly optimized for handling large binary assets in order to cope with large multi gigabyte project folders. When uploading assets, Import Settings and other meta data about each asset is uploaded to the asset server as well. Renaming and moving files is at the core of the system and well supported.
It is available only for Unity Pro, and is an additional license per client. To purchase an Asset Server Client License, please visit the Unity store at http://unity3d.com/store
New to Source Control?
If you have never used Source Control before, it can be a little unfriendly to get started with any versioning system. Source Control works by storing an entire collection of all your assets - meshes, textures, materials, scripts, and everything else - in a database on some kind of server. That server might be your home computer, the same one that you use to run Unity. It might be a different computer in your local network. It might be a remote machine colocated in a different part of the world. It could even be a virtual machine. There are a lot of options, but the location of the server doesn't matter at all. The important thing is that you can access it somehow over your network, and that it stores your game data.
In a way, the Asset Server functions as a backup of your Project Folder. You do not directly manipulate the contents of the Asset Server while you are developing. You make changes to your Project locally, then when you are done, you to the Project on the Server. This makes your local Project and the Asset Server Project identical.
Now, when your fellow developers make a change, the Asset Server is identical to their Project, but not yours. To synchronize your local Project, you request to . Now, whatever changes your team members have made will be downloaded from the server to your local Project.
This is the basic workflow for using the Asset Server. In addition to this basic functionality, the Asset Server allows for rollback to previous versions of assets, detailed file comparison, merging two different scripts, resolving conflicts, and recovering deleted assets.
Setting up the Asset Server
The Asset Server requires a one time server setup and a client configuration for each user. You can read about how to do that in the Asset Server Setup page.
The rest of this guide explains how to deploy, administrate, and regularly use the Asset Server.
Daily use of the Asset Server
This section explains the common tasks, workflow and best practices for using the Asset Server on a day-to-day basis.
Getting Started
If you are joining a team that has a lot of work stored on the Asset Server already, this is the quickest way to get up and running correctly. If you are starting your own project from scratch, you can skip down to the Workflow Fundamentals section.
- Create a new empty Project with no packages imported
- Go to and select as the version control mode
- From the menubar, select
- Click the button
- Enter your user name and password (provided by your Asset Server administrator)
- Click and select the desired project
- Click
- Click the tab
- Click the button
- If a conflict occurs, discard all local versions
- Wait for the update to complete
- You are ready to go
Continue reading for detailed information on how to use the Asset Server effectively every day.
Workflow Fundamentals
When using the Asset Server with a multi-person team, it is generally good practice to Update all changed assets from the server when you begin working, and Commit your changes at the end of the day, or whenever you're done working. You should also commit changes when you have made significant progress on something, even if it is in the middle of the day. Committing your changes regularly and frequently is recommended.
Understanding the Server View
The Server View is your window into the Asset Server you're connected to. You can open the Server View by selecting .

The Overview tab
The Server View is broken into tabs: Overview Update, and Commit. Overview will show you any differences between your local project and the latest version on the server with options to quickly commit local changes or download the latest updates. Update will show you the latest remote changes on the server and allow you to download them to your local project. Commit allows you to create a Changeset and commit it to the server for others to download.
Connecting to the server
Before you can use the asset server, you must connect to it. To do this you click the button, which takes you to the connection screen:

The Asset Server connection screen
Here you need to fill in:
- Server address
- Username
- Password
By clicking you can now see the available projects on the asset server, and choose which one to connect to by clicking . Note that the username and password you use can be obtain from your system administrator. Your system administrator created accounts when they installed Asset Server.
Updating from the Server
To download all updates from the server, select the tab from the Overview tab and you will see a list of the latest committed Changesets. By selecting one of these you can see what was changed in the project as well as the provided commit message. Click and you will begin downloading all Changeset updates.

The Update Tab
Committing Changes to the Server
When you have made a change to your local project and you want to store those changes on the server, you use the top tab.

The Commit tab
Now you will be able to see all the local changes made to the project since your last update, and will be able to select which changes you wish to upload to the server. You can add changes to the changeset either by manually dragging them into the changeset field, or by using the buttons placed below the commit message field. Remember to type in a commit message which will help you when you compare versions or revert to an earlier version later on, both of which are discussed below.
Resolving conflicts
With multiple people working on the same collection of data, conflicts will inevitably arise. Remember, there is no need to panic! If a conflict exists, you will be presented with the Conflict Resolution dialog when updating your project.

The Conflict Resolution screen
Here, you will be informed of each individual conflict, and be presented with different options to resolve each individual conflict. For any single conflict, you can select (which will not download that asset from the server), (which will completely overwrite your local version of the asset) or (which will ignore the changes others made to the asset and after this update you will be able to commit your local changes over server ones) for each individual conflict. Additionally, you can select for text assets like scripts to merge the server version with the local version.
Note: If you choose to discard your changes, the asset will be updated to the latest version from the server (i.e., it will incorporate other users' changes that have been made while you were working). If you want to get the asset back as it was when you started working, you should revert to the specific version that you checked out. (See Browsing revision history and reverting assets below.)
If you run into a conflict while you are committing your local changes, Unity will refuse to commit your changes and inform you that a conflict exists. To resolve the conflicts, select . Your local changes will not automatically be overwritten. At this point you will see the Conflict Resolution dialog, and can follow the instructions in the above paragraph.
Browsing revision history and reverting assets
The Asset Server retains all uploaded versions of an asset in its database, so you can revert your local version to an earlier version at any time. You can either select to restore the entire project or single files. To revert to an older version of an asset or a project, select the Overview tab then click Show History listed under Asset Server Actions. You will now see a list of all commits and be able to select and restore any file or all project to an older version.

The History dialog
Here, you can see the version number and added comments with each version of the asset or project. This is one reason why descriptive comments are helpful. Select any asset to see its history or for all changes made in project. Find revision you need. You can either select whole revision or particular asset in revision. Then click to get your local asset replaced with a copy of the selected revision. will revert entire project to selected revision.
Prior to reverting, if there are any differences between your local version and the selected server version, those changes will be lost when the local version is reverted.
If you only want to abandon the changes made to the local copy, you don't have to revert. You can discard those local modifications by selecting in the main asset server window. This will immediately download the current version of the project from the server to your local Project.
Comparing asset versions
If you're curious to see the differences between two particular versions you can explicitly compare them. To do this, open window, select revision and asset you want to compare and press . If you need to compare two different revisions of an asset - right click on it, in the context menu select then find revision you want to compare to and select it.
Note: this feature requires that you have one of supported file diff/merge tools installed. Supported tools are:
- On Windows:
- TortoiseMerge: part of TortoiseSVN or a separate download from the project site.
- WinMerge.
- SourceGear Diff/Merge.
- Perforce Merge (p4merge): part of Perforce's visual client suite (P4V).
- TkDiff.
- On Mac OS X:
- SourceGear Diff/Merge.
- FileMerge: part of Apple's XCode development tools.
- TkDiff.
- Perforce Merge (p4merge): part of Perforce's visual client suite (P4V).
Recovering deleted assets
Deleting a local asset and committing the delete to the server will in fact not delete an asset permanently. Just as any previous version of an asset can be restored through window from the Overview tab.

The History dialog
Expand item, find and select assets from the list and hit , the selected assets will be downloaded and re-added to the local project. If the folder that the asset was located in before the deletion still exists, the asset will be restored to the original location, otherwise it will be added to the root of the Assets folder in the local project.
Asset Server training complete
You should now be equipped with the knowledge you need to start using the Asset Server effectively. Get to it, and don't forget the good workflow fundamentals. Commit changes often, and don't be afraid of losing anything.
Page last updated: 2011-10-31Asset Cache Server
Unity has a completely automatic asset pipeline. Whenever a source asset like a .psd or an .fbx file is modified, Unity will detect the change and automatically reimport it. The best parts about the asset pipeline are the "hot reloading" functionality and the guarantee that all your source assets are always in sync with what you see. This feature also comes at a cost. Any asset that is modified has to be reimported right away. When working in large teams, after getting latest from Source Control, you often have to wait for a long time to re-import all the assets modified or created by other team members. Also, switching your project platform back and forth between desktop and mobile, will trigger a re-import of most assets.
The time it takes to import assets can be drastically reduced by caching the imported assets on the Cache Server.
Each asset import is cached based on
- The asset file itself
- The import settings
- Asset importer version
- The current platform.
If any of the above change, the asset gets reimported, otherwise it gets downloaded from the Cache Server.
When you enable the cache server in the preferences, you can even share asset imports across multiple projects.
Note that once the cache server is set up, this process is completely automatic, which means there are no additional workflow requirements. It will simply reduce the time it takes to import projects without getting in your way.
How to set up a Cache Server (user)
Setting up the Cache Server couldn't be easier. All you need to do is click Use Cache Server in the preferences and tell the local machine's Unity Editor where the Cache Server is.
This can be found in on the Mac or on the PC.
If you are hosting the Cache Server on your local machine, specify localhost for the server address. However, due to hard drive size limitations, it is recommended you host the Cache Server on separate machine.
How to set up a Cache Server (admin)
Admins need to set up the Cache Server machine that will host the cached assets.
You need to:
- Download the Cache Server here
- Unzip the file, after which you should see something like this:
- Depending on your operating system, run the appropriate command script.
- You will see a terminal window, indicating that the Cache Server is running in the background
The Cache Server needs to be on a reliable machine with very large storage (much larger than the size of the project itself, as there will likely be multiple versions of imported resources stored).
Installing the Cache Server as a service
The provided .sh and .cmd scripts should be set-up as a service on the server.
The cache server can be safely killed and restarted at any time, since it uses atomic file operations.
Cache Server Configuration
If you simply start the Cache Server by double clicking the script, it will create a "cache" directory next to the script, and keep it's data in there. The cache directory is allowed to grow to up to 50 GB. You can configure the size and the location of the data using command line options, like this:
./RunOSX.command --path ~/mycachePath --size 2000000000
--path lets you specify a cache location, and --size lets you specify the maximum cache size in bytes.
Recommendations for the machine hosting the Cache Server
We recommend equipping the machine with a lot of RAM. For best performance there is enough RAM to hold an entire imported project folder. In addition, it is best to have a machine with a fast hard drive and fast Ethernet connection. On the other hand, the Cache Server has very low CPU usage.
One of the main distinctions between the Cache Server and version control is that its cached data can always be rebuilt locally. It is simply a tool for improving performance. For this reason it doesn't make sense to use a Cache Server over the internet. If you have a distributed team, we recommend that you place a seperate cache server in each location.
Page last updated: 2012-02-03Behind the Scenes
Unity automatically imports assets and manages various kinds of additional data about them for you. Below is a description of how this process works.
When you place an Asset such as a texture in the Assets folder, Unity will first detect that a new file has been added (the editor frequently checks the contents of the Assets folder against the list of assets it already knows about). Once a unique ID value has been assigned to the asset to enable it to be accessed internally, it will be imported and processed. The asset that you actually see in the Project panel is the result of that processing and its data contents will typically be different to those of the original asset. For example, a texture may be present in the Assets folder as a PNG file but will be converted to an internal format after import and processing.
Using an internal format for assets allows Unity to keep additional data known as metadata which enables the asset data to be handled in a much more flexible way. For example, the Photoshop file format is convenient to work with, but you wouldn't expect it to support game engine features such as mip maps. Unity's internal format, however, can add extra functionality like this to any asset type. All metadata for assets is stored in the Library folder. As as user, you should never have to alter the Library folder manually and attempting to do so may corrupt the project.
Unity allows you to create folders in the Project view to help you organize assets, and those folders will be mirrored in the actual filesystem. However, you must move the files within Unity by dragging and dropping in the Project view. If you attempt to use the filesystem/desktop to move the files then Unity will misinterpret the change (it will appear that the old asset has been deleted and a new one created in its place). This will lose information, such as links between assets and scripts in the project.
When backing up a project, you should always back up the main Unity project folder, containing both the Assets and Library folders. All the information in the subfolders is crucial to the way Unity works.
Page last updated: 2011-11-15Creating Gameplay
Unity empowers game designers to make games. What's really special about Unity is that you don't need years of experience with code or a degree in art to make fun games. There are a handful of basic workflow concepts needed to learn Unity. Once understood, you will find yourself making games in no time. With the time you will save getting your games up and running, you will have that much more time to refine, balance, and tweak your game to perfection.
This section will explain the core concepts you need to know for creating unique, amazing, and fun gameplay. The majority of these concepts require you to write Scripts. For an overview of creating and working with Scripts, please read the Scripting page.
- Instantiating Prefabs at runtime
- Input
- Transforms
- Physics
- Adding Random Gameplay Elements
- Particle Systems
- Animation View Guide
- Animation Scripting
- Navmesh and Pathfinding (Pro only)
- Sound
- Game Interface Elements
- Networked Multiplayer
Instantiating Prefabs
By this point you should understand the concept of Prefabs at a fundamental level. They are a collection of predefined GameObjects & Components that are re-usable throughout your game. If you don't know what a Prefab is, we recommend you read the Prefabs page for a more basic introduction.
Prefabs come in very handy when you want to instantiate complicated GameObjects at runtime. The alternative to instantiating Prefabs is to create GameObjects from scratch using code. Instantiating Prefabs has many advantages over the alternative approach:
- You can instantiate a Prefab from one line of code, with complete functionality. Creating equivalent GameObjects from code takes an average of five lines of code, but likely more.
- You can set up, test, and modify the Prefab quickly and easily in the Scene and Inspector.
- You can change the Prefab being instanced without changing the code that instantiates it. A simple rocket might be altered into a super-charged rocket, and no code changes are required.
Common Scenarios
To illustrate the strength of Prefabs, let's consider some basic situations where they would come in handy:
- Building a wall out of a single "brick" Prefab by creating it several times in different positions.
- A rocket launcher instantiates a flying rocket Prefab when fired. The Prefab contains a Mesh, Rigidbody, Collider, and a child GameObject with its own trail Particle System.
- A robot exploding to many pieces. The complete, operational robot is destroyed and replaced with a wrecked robot Prefab. This Prefab would consist of the robot split into many parts, all set up with Rigidbodies and Particle Systems of their own. This technique allows you to blow up a robot into many pieces, with just one line of code, replacing one object with a Prefab.
Building a wall
This explanation will illustrate the advantages of using a Prefab vs creating objects from code.
First, lets build a brick wall from code:
function Start () {
for (var y = 0; y < 5; y++) {
for (var x = 0; x < 5; x++) {
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.AddComponent(Rigidbody);
cube.transform.position = Vector3 (x, y, 0);
}
}
}
- To use the above script we simply save the script and drag it onto an empty GameObject.
- Create an empty GameObject with .
If you execute that code, you will see an entire brick wall is created when you enter Play Mode. There are two lines relevant to the functionality of each individual brick: the CreatePrimitive() line, and the AddComponent() line. Not so bad right now, but each of our bricks is un-textured. Every additional action to want to perform on the brick, like changing the texture, the friction, or the Rigidbody mass, is an extra line.
If you create a Prefab and perform all your setup before-hand, you use one line of code to perform the creation and setup of each brick. This relieves you from maintaining and changing a lot of code when you decide you want to make changes. With a Prefab, you just make your changes and Play. No code alterations required.
If you're using a Prefab for each individual brick, this is the code you need to create the wall.
var cube : Transform;
function Start () {
for (var y = 0; y < 5; y++) {
for (var x = 0; x < 5; x++) {
var cube = Instantiate(cube, Vector3 (x, y, 0), Quaternion.identity);
}
}
}
This is not only very clean but also very reusable. There is nothing saying we are instantiating a cube or that it must contain a rigidbody. All of this is defined in the Prefab and can be quickly created in the Editor.
Now we only need to create the Prefab, which we do in the Editor. Here's how:
- Choose
- Choose
- Choose
- In the Project View, change the name of your new Prefab to "Brick"
- Drag the cube you created in the Hierarchy onto the "Brick" Prefab in the Project View
- With the Prefab created, you can safely delete the Cube from the Hierarchy ( on Windows, on Mac)
We've created our Brick Prefab, so now we have to attach it to the cube variable in our script. Select the empty GameObject that contains the script. Notice that a new variable has appeared in the Inspector, called "cube".

This variable can accept any GameObject or Prefab
Now drag the "Brick" Prefab from the Project View onto the cube variable in the Inspector. Press Play and you'll see the wall built using the Prefab.
This is a workflow pattern that can be used over and over again in Unity. In the beginning you might wonder why this is so much better, because the script creating the cube from code is only 2 lines longer.
But because you are using a Prefab now, you can adjust the Prefab in seconds. Want to change the mass of all those instances? Adjust the Rigidbody in the Prefab only once. Want to use a different Material for all the instances? Drag the Material onto the Prefab only once. Want to change friction? Use a different Physic Material in the Prefab's collider. Want to add a Particle System to all those boxes? Add a child to the Prefab only once.
Instantiating rockets & explosions
Here's how Prefabs fit into this scenario:
- A rocket launcher instantiates a rocket Prefab when the user presses fire. The Prefab contains a mesh, Rigidbody, Collider, and a child GameObject that contains a trail particle system.
- The rocket impacts and instantiates an explosion Prefab. The explosion Prefab contains a Particle System, a light that fades out over time, and a script that applies damage to surrounding GameObjects.
While it would be possible to build a rocket GameObject completely from code, adding Components manually and setting properties, it is far easier to instantiate a Prefab. You can instantiate the rocket in just one line of code, no matter how complex the rocket's Prefab is. After instantiating the Prefab you can also modify any properties of the instantiated object (e.g. you can set the velocity of the rocket's Rigidbody).
Aside from being easier to use, you can update the prefab later on. So if you are building a rocket, you don't immediately have to add a Particle trail to it. You can do that later. As soon as you add the trail as a child GameObject to the Prefab, all your instantiated rockets will have particle trails. And lastly, you can quickly tweak the properties of the rocket Prefab in the Inspector, making it far easier to fine-tune your game.
This script shows how to launch a rocket using the Instantiate() function.
// Require the rocket to be a rigidbody.
// This way we the user can not assign a prefab without rigidbody
var rocket : Rigidbody;
var speed = 10.0;
function FireRocket () {
var rocketClone : Rigidbody = Instantiate(rocket, transform.position, transform.rotation);
rocketClone.velocity = transform.forward * speed;
// You can also acccess other components / scripts of the clone
rocketClone.GetComponent(MyRocketScript).DoSomething();
}
// Calls the fire method when holding down ctrl or mouse
function Update () {
if (Input.GetButtonDown("Fire1")) {
FireRocket();
}
}
Replacing a character with a ragdoll or wreck
Let's say you have a fully rigged enemy character and he dies. You could simply play a death animation on the character and disable all scripts that usually handle the enemy logic. You probably have to take care of removing several scripts, adding some custom logic to make sure that no one will continue attacking the dead enemy anymore, and other cleanup tasks.
A far better approach is to immediately delete the entire character and replace it with an instantiated wrecked prefab. This gives you a lot of flexibility. You could use a different material for the dead character, attach completely different scripts, spawn a Prefab containing the object broken into many pieces to simulate a shattered enemy, or simply instantiate a Prefab containing a version of the character.
Any of these options can be achieved with a single call to Instantiate(), you just have to hook it up to the right prefab and you're set!
The important part to remember is that the wreck which you Instantiate() can be made of completely different objects than the original. For example, if you have an airplane, you would model two versions. One where the plane consists of a single GameObject with Mesh Renderer and scripts for airplane physics. By keeping the model in just one GameObject, your game will run faster since you will be able to make the model with less triangles and since it consists of fewer objects it will render faster than using many small parts. Also while your plane is happily flying around there is no reason to have it in separate parts.
To build a wrecked airplane Prefab, the typical steps are:
- Model your airplane with lots of different parts in your favorite modeler
- Create an empty Scene
- Drag the model into the empty Scene
- Add Rigidbodies to all parts, by selecting all the parts and choosing
- Add Box Colliders to all parts by selecting all the parts and choosing
- For an extra special effect, add a smoke-like Particle System as a child GameObject to each of the parts
- Now you have an airplane with multiple exploded parts, they fall to the ground by physics and will create a Particle trail due to the attached particle system. Hit Play to preview how your model reacts and do any necessary tweaks.
- Choose
- Drag the root GameObject containing all the airplane parts into the Prefab
var wreck : GameObject;
// As an example, we turn the game object into a wreck after 3 seconds automatically
function Start () {
yield WaitForSeconds(3);
KillSelf();
}
// Calls the fire method when holding down ctrl or mouse
function KillSelf () {
// Instantiate the wreck game object at the same position we are at
var wreckClone = Instantiate(wreck, transform.position, transform.rotation);
// Sometimes we need to carry over some variables from this object
// to the wreck
wreckClone.GetComponent(MyScript).someVariable = GetComponent(MyScript).someVariable;
// Kill ourselves
Destroy(gameObject);
}
The First Person Shooter tutorial explains how to replace a character with a ragdoll version and also synchronize limbs with the last state of the animation. You can find that tutorial on the Tutorials page.
Placing a bunch of objects in a specific pattern
Lets say you want to place a bunch of objects in a grid or circle pattern. Traditionally this would be done by either:
- Building an object completely from code. This is tedious! Entering values from a script is both slow, unintuitive and not worth the hassle.
- Make the fully rigged object, duplicate it and place it multiple times in the scene. This is tedious, and placing objects accurately in a grid is hard.
So use Instantiate() with a Prefab instead! We think you get the idea of why Prefabs are so useful in these scenarios. Here's the code necessary for these scenarios:
// Instantiates a prefab in a circle
var prefab : GameObject;
var numberOfObjects = 20;
var radius = 5;
function Start () {
for (var i = 0; i < numberOfObjects; i++) {
var angle = i * Mathf.PI * 2 / numberOfObjects;
var pos = Vector3 (Mathf.Cos(angle), 0, Mathf.Sin(angle)) * radius;
Instantiate(prefab, pos, Quaternion.identity);
}
}
// Instantiates a prefab in a grid
var prefab : GameObject;
var gridX = 5;
var gridY = 5;
var spacing = 2.0;
function Start () {
for (var y = 0; y < gridY; y++) {
for (var x=0;x<gridX;x++) {
var pos = Vector3 (x, 0, y) * spacing;
Instantiate(prefab, pos, Quaternion.identity);
}
}
}
Page last updated: 2010-06-30
Input
Desktop
Note: Keyboard, joystick and gamepad input works only on the desktop version of Unity.
Unity supports keyboard, joystick and gamepad input.
Virtual axes and buttons can be created in the Input Manager, and end users can configure Keyboard input in a nice screen configuration dialog.

You can setup joysticks, gamepads, keyboard, and mouse, then access them all through one simple scripting interface.
From scripts, all virtual axes are accessed by their name.
Every project has the following default input axes when it's created:
- Horizontal and Vertical are mapped to w, a, s, d and the arrow keys.
- Fire1, Fire2, Fire3 are mapped to Control, Option (Alt), and Command, respectively.
- Mouse X and Mouse Y are mapped to the delta of mouse movement.
- Window Shake X and Window Shake Y is mapped to the movement of the window.
Adding new Input Axes
If you want to add new virtual axes go to the menu. Here you can also change the settings of each axis.

You map each axis to two buttons on a joystick, mouse, or keyboard keys.
| Name | The name of the string used to check this axis from a script. |
| Descriptive Name | Positive value name displayed in the input tab of the configuration dialog for standalone builds. |
| Descriptive Negative Name | Negative value name displayed in the Input tab of the Configuration dialog for standalone builds. |
| Negative Button | The button used to push the axis in the negative direction. |
| Positive Button | The button used to push the axis in the positive direction. |
| Alt Negative Button | Alternative button used to push the axis in the negative direction. |
| Alt Positive Button | Alternative button used to push the axis in the positive direction. |
| Gravity | Speed in units per second that the axis falls toward neutral when no buttons are pressed. |
| Dead | Size of the analog dead zone. All analog device values within this range result map to neutral. |
| Sensitivity | Speed in units per second that the the axis will move toward the target value. This is for digital devices only. |
| Snap | If enabled, the axis value will reset to zero when pressing a button of the opposite direction. |
| Invert | If enabled, the Negative Buttons provide a positive value, and vice-versa. |
| Type | The type of inputs that will control this axis. |
| Axis | The axis of a connected device that will control this axis. |
| Joy Num | The connected Joystick that will control this axis. |
Use these settings to fine tune the look and feel of input. They are all documented with tooltips in the Editor as well.
Using Input Axes from Scripts
You can query the current state from a script like this:
value = Input.GetAxis ("Horizontal");
An axis has a value between -1 and 1. The neutral position is 0. This is the case for joystick input and keyboard input.
However, Mouse Delta and Window Shake Delta are how much the mouse or window moved during the last frame. This means it can be larger than 1 or smaller than -1 when the user moves the mouse quickly.
It is possible to create multiple axes with the same name. When getting the input axis, the axis with the largest absolute value will be returned. This makes it possible to assign more than one input device to one axis name. For example, create one axis for keyboard input and one axis for joystick input with the same name. If the user is using the joystick, input will come from the joystick, otherwise input will come from the keyboard. This way you don't have to consider where the input comes from when writing scripts.
Button Names
To map a key to an axis, you have to enter the key's name in the Positive Button or Negative Button property in the Inspector.
The names of keys follow this convention:
- Normal keys: "a", "b", "c" ...
- Number keys: "1", "2", "3", ...
- Arrow keys: "up", "down", "left", "right"
- Keypad keys: "[1]", "[2]", "[3]", "[+]", "[equals]"
- Modifier keys: "right shift", "left shift", "right ctrl", "left ctrl", "right alt", "left alt", "right cmd", "left cmd"
- Mouse Buttons: "mouse 0", "mouse 1", "mouse 2", ...
- Joystick Buttons (from any joystick): "joystick button 0", "joystick button 1", "joystick button 2", ...
- Joystick Buttons (from a specific joystick): "joystick 1 button 0", "joystick 1 button 1", "joystick 2 button 0", ...
- Special keys: "backspace", "tab", "return", "escape", "space", "delete", "enter", "insert", "home", "end", "page up", "page down"
- Function keys: "f1", "f2", "f3", ...
The names used to identify the keys are the same in the scripting interface and the Inspector.
value = Input.GetKey ("a");
Mobile Input
Unity iOS/Android offers you access to the iPhone, iPad and Android input systems via Input and iOS Input scripting interfaces.
Input provides access to the multi-touch screen, accelerometer and device orientation. iOS Input provides access to geographical location.
Access to keyboard on mobile devices is provided via the iOS keyboard.
Multi-Touch Screen
The iPhone and iPod Touch devices are capable of tracking up to five fingers touching the screen simultaneously. You can retrieve the status of each finger touching the screen during the last frame by accessing the Input.touches property array.
Android devices don't have a unified limit on how many fingers they track. Instead, it varies from device to device and can be anything from two-touch on older devices to five fingers on some newer devices.
Each finger touch is represented by an Input.Touch data structure:
| fingerId | The unique index for a touch. |
| position | The screen position of the touch. |
| deltaPosition | The screen position change since the last frame. |
| deltaTime | Amount of time that has passed since the last state change. |
| tapCount | The iPhone/iPad screen is able to distinguish quick finger taps by the user. This counter will let you know how many times the user has tapped the screen without moving a finger to the sides. Android devices do not count number of taps, this field is always 1. |
| phase | Describes so called "phase" or the state of the touch. It can help you determine if the touch just began, if user moved the finger or if he just lifted the finger. |
Phase can be one of the following:
| Began | A finger just touched the screen. |
| Moved | A finger moved on the screen. |
| Stationary | A finger is touching the screen but hasn't moved since the last frame. |
| Ended | A finger was lifted from the screen. This is the final phase of a touch. |
| Canceled | The system cancelled tracking for the touch, as when (for example) the user puts the device to her face or more than five touches happened simultaneously. This is the final phase of a touch. |
Following is an example script which will shoot a ray whenever the user taps on the screen:
var particle : GameObject;
function Update () {
for (var touch : Touch in Input.touches) {
if (touch.phase == TouchPhase.Began) {
// Construct a ray from the current touch coordinates
var ray = Camera.main.ScreenPointToRay (touch.position);
if (Physics.Raycast (ray)) {
// Create a particle if hit
Instantiate (particle, transform.position, transform.rotation);
}
}
}
}
Mouse Simulation
On top of native touch support Unity iOS/Android provides a mouse simulation. You can use mouse functionality from the standard Input class.
Device Orientation
Unity iOS/Android allows you to get discrete description of the device physical orientation in three-dimensional space. Detecting a change in orientation can be useful if you want to create game behaviors depending on how the user is holding the device.
You can retrieve device orientation by accessing the Input.deviceOrientation property. Orientation can be one of the following:
| Unknown | The orientation of the device cannot be determined. For example when device is rotate diagonally. |
| Portrait | The device is in portrait mode, with the device held upright and the home button at the bottom. |
| PortraitUpsideDown | The device is in portrait mode but upside down, with the device held upright and the home button at the top. |
| LandscapeLeft | The device is in landscape mode, with the device held upright and the home button on the right side. |
| LandscapeRight | The device is in landscape mode, with the device held upright and the home button on the left side. |
| FaceUp | The device is held parallel to the ground with the screen facing upwards. |
| FaceDown | The device is held parallel to the ground with the screen facing downwards. |
Accelerometer
As the mobile device moves, a built-in accelerometer reports linear acceleration changes along the three primary axes in three-dimensional space. Acceleration along each axis is reported directly by the hardware as G-force values. A value of 1.0 represents a load of about +1g along a given axis while a value of -1.0 represents -1g. If you hold the device upright (with the home button at the bottom) in front of you, the X axis is positive along the right, the Y axis is positive directly up, and the Z axis is positive pointing toward you.
You can retrieve the accelerometer value by accessing the Input.acceleration property.
The following is an example script which will move an object using the accelerometer:
var speed = 10.0;
function Update () {
var dir : Vector3 = Vector3.zero;
// we assume that the device is held parallel to the ground
// and the Home button is in the right hand
// remap the device acceleration axis to game coordinates:
// 1) XY plane of the device is mapped onto XZ plane
// 2) rotated 90 degrees around Y axis
dir.x = -Input.acceleration.y;
dir.z = Input.acceleration.x;
// clamp acceleration vector to the unit sphere
if (dir.sqrMagnitude > 1)
dir.Normalize();
// Make it move 10 meters per second instead of 10 meters per frame...
dir *= Time.deltaTime;
// Move object
transform.Translate (dir * speed);
}
Low-Pass Filter
Accelerometer readings can be jerky and noisy. Applying low-pass filtering on the signal allows you to smooth it and get rid of high frequency noise.
The following script shows you how to apply low-pass filtering to accelerometer readings:
var AccelerometerUpdateInterval : float = 1.0 / 60.0;
var LowPassKernelWidthInSeconds : float = 1.0;
private var LowPassFilterFactor : float = AccelerometerUpdateInterval / LowPassKernelWidthInSeconds; // tweakable
private var lowPassValue : Vector3 = Vector3.zero;
function Start () {
lowPassValue = Input.acceleration;
}
function LowPassFilterAccelerometer() : Vector3 {
lowPassValue = Mathf.Lerp(lowPassValue, Input.acceleration, LowPassFilterFactor);
return lowPassValue;
}
The greater the value of LowPassKernelWidthInSeconds, the slower the filtered value will converge towards the current input sample (and vice versa). You should be able to use the LowPassFilter() function instead of avgSamples().
I'd like as much precision as possible when reading the accelerometer. What should I do?
Reading the Input.acceleration variable does not equal sampling the hardware. Put simply, Unity samples the hardware at a frequency of 60Hz and stores the result into the variable. In reality, things are a little bit more complicated -- accelerometer sampling doesn't occur at consistent time intervals, if under significant CPU loads. As a result, the system might report 2 samples during one frame, then 1 sample during the next frame.
You can access all measurements executed by accelerometer during the frame. The following code will illustrate a simple average of all the accelerometer events that were collected within the last frame:
var period : float = 0.0;
var acc : Vector3 = Vector3.zero;
for (var evnt : iPhoneAccelerationEvent in iPhoneInput.accelerationEvents) {
acc += evnt.acceleration * evnt.deltaTime;
period += evnt.deltaTime;
}
if (period > 0)
acc *= 1.0/period;
return acc;
Further Reading
The Unity mobile input API is originally based on Apple's API. It may help to learn more about the native API to better understand Unity's Input API. You can find the Apple input API documentation here:
- Programming Guide: Event Handling (Apple iPhone SDK documentation)
- UITouch Class Reference (Apple iOS SDK documentation)
Note: The above links reference your locally installed iPhone SDK Reference Documentation and will contain native ObjectiveC code. It is not necessary to understand these documents for using Unity on mobile devices, but may be helpful to some!
iOS
Device geographical location
Device geographical location can be obtained via the iPhoneInput.lastLocation property. Before calling this property you should start location service updates using iPhoneSettings.StartLocationServiceUpdates() and check the service status via iPhoneSettings.locationServiceStatus. See the scripting reference for details.
Transforms
Transforms are a key Component in every GameObject. They dictate where the GameObject is positioned, how it is rotated, and its scale. It is impossible to have a GameObject without a Transform. You can adjust the Transform of any GameObject from the Scene View, the Inspector, or through Scripting.
The remainder of this page's text is from the Transform Component Reference page.
Transform
The Transform Component determines the Position, Rotation, and Scale of each object in the scene. Every object has a Transform.

The Transform Component is editable in the Scene View and in the Inspector
Properties
| Position | Position of the Transform in X, Y, and Z coordinates. |
| Rotation | Rotation of the Transform around the X, Y, and Z axes, measured in degrees. |
| Scale | Scale of the Transform along X, Y, and Z axes. Value "1" is the original size (size at which the object was imported). |
All properties of a Transform are measured relative to the Transform's parent (see below for further details). If the Transform has no parent, the properties are measured relative to World Space.
Using Transforms
Transforms are always manipulated in 3D space in the X, Y, and Z axes. In Unity, these axes are represented by the colors red, green, and blue respectively. Remember: XYZ = RGB.

Color-coded relationship between the three axes and Transform properties
Transforms can be directly manipulated in the Scene View or by editing properties in the Inspector. In the scene, you can modify Transforms using the Move, Rotate and Scale tools. These tools are located in the upper left-hand corner of the Unity Editor.

The View, Translate, Rotate, and Scale tools
The tools can be used on any object in the scene. When you click on an object, you will see the tool gizmo appear within it. The appearance of the gizmo depends on which tool is selected.

All three Gizmos can be directly edited in the Scene View.
When you click and drag on one of the three gizmo axes, you will notice that its color changes. As you drag the mouse, you will see the object translate, rotate, or scale along the selected axis. When you release the mouse button, the axis remains selected. You can click the middle mouse button and drag the mouse to manipulate the Transform along the selected axis.

Any individual axis will become selected when you click on it
Around the centre of the Transform gizmo are three coloured squares. These allow you to drag the Transform in a single plane (ie, the object will move in two axes but be held still in the third axis).

Dragging in the XZ plane
Parenting
Parenting is one of the most important concepts to understand when using Unity. When a GameObject is a Parent of another GameObject, the Child GameObject will move, rotate, and scale exactly as its Parent does. Just like your arms are attached to your body, when you turn your body, your arms move because they're attached. Any object can have multiple children, but only one parent.
You can create a Parent by dragging any GameObject in the Hierarchy View onto another. This will create a Parent-Child relationship between the two GameObjects.

Example of a Parent-Child hierarchy. GameObjects with foldout arrows to the left of their names are parents.
In the above example, we say that the arms are parented to the body and the hands are parented to the arms. The scenes you make in Unity will contain collections of these Transform hierarchies. The topmost parent object is called the Root object. When you move, scale or rotate a parent, all the changes in its Transform are applied to its children as well.
It is worth pointing out that the Transform values in the Inspector of any Child GameObject are displayed relative to the Parent's Transform values. These are also called the Local Coordinates. Through scripting, you can access the Global Coordinates as well as the local coordinates.
You can build compound objects by parenting several separate objects together, for example, the skeletal structure of a human ragdoll. You can also achieve useful effects with simple hierarchies. For example, if you have a horror game that takes place at night, you can create an effective atmosphere with a flashlight. To create this object, you would parent a spotlight Transform to the flashlight Transform. Then, any alteration of the flashlight Transform will affect the spotlight, creating a convincing flashlight effect.
Performance Issues and Limitations with Non-Uniform Scaling
Non-uniform scaling is when the Scale in a Transform has different values for x, y, and z; for example (2, 4, 2). In contrast, uniform scaling has the same value for x, y, and z; for example (3, 3, 3). Non-uniform scaling can be useful in a few select cases but should be avoided whenever possible.
Non-uniform scaling has a negative impact on rendering performance. In order to transform vertex normals correctly, we transform the mesh on the CPU and create an extra copy of the data. Normally we can keep the mesh shared between instances in graphics memory, but in this case you pay both a CPU and memory cost per instance.
There are also certain limitations in how Unity handles non-uniform scaling:
- Certain components do not fully support non-uniform scaling. For example, for components with a radius property or similar, such as a Sphere Collider, Capsule Collider, Light, Audio Source etc., the shape will never become elliptical but remain circular/spherical regardless of non-uniform scaling.
- A child object that has a non-uniformly scaled parent and is rotated relative to that parent may have a non-orthogonal matrix, meaning that it may appear skewed. Some components that do support simple non-uniform scaling still do not support non-orthogonal matrices. For example, a Box Collider cannot be skewed so if its transform is non-orthogonal, the Box Collider will not match the shape of the rendered mesh accurately.
- For performance reasons, a child object that has a non-uniformly scaled parent will not have its scale/matrix automatically updated while rotating. This may result in popping of the scale once the scale is updated, for example if the object is detached from its parent.
Importance of Scale
The scale of the Transform determines the difference between the size of your mesh in your modeling application and the size of your mesh in Unity. The mesh's size in Unity (and therefore the Transform's scale) is very important, especially during physics simulation. There are three factors that can affect the scale of your object:
- The size of your mesh in your 3D modeling application.
- The Mesh Scale Factor setting in the object's Import Settings.
- The Scale values of your Transform Component.
Ideally, you should not adjust the Scale of your object in the Transform Component. The best option is to create your models at real-life scale so you won't have to change your Transform's scale. The next best option is to adjust the scale at which your mesh is imported in the Import Settings for your individual mesh. Certain optimizations occur based on the import size, and instantiating an object that has an adjusted scale value can decrease performance. For more information, see the section about optimizing scale on the Rigidbody component reference page.
Hints
- When parenting Transforms, set the parent's location to <0,0,0> before adding the child. This will save you many headaches later.
- Particle Systems are not affected by the Transform's Scale. In order to scale a Particle System, you need to modify the properties in the System's Particle Emitter, Animator and Renderer.
- If you are using Rigidbodies for physics simulation, there is some important information about the Scale property on the Rigidbody component reference page.
- You can change the colors of the Transform axes (and other UI elements) from the preferences ( and then select the panel).
- It is best to avoid scaling within Unity if possible. Try to have the scales of your object finalized in your 3D modeling application, or in the Import Settings of your mesh.
Physics
Unity has NVIDIA PhysX physics engine built-in. This allows for unique emergent behaviour and is generally very cool.
Basics
To put an object under physics control, simply add a Rigidbody to it. When you do this, the object will be affected by gravity, and can collide with other objects in the world.
Rigidbodies
Rigidbodies are physically simulated objects. You use Rigidbodies for things that the player can push around, eg. crates or loose objects, or you can move Rigidbodies around directly by adding forces to it by scripting.
If you move the Transform of a non-Kinematic Rigidbody directly it may not collide correctly with other objects. Instead you should move a Rigidbody by applying forces and torque to it. You can also add Joints to rigidbodies to make the behavior more complex. For example, you could make a physical door or a crane with a swinging chain.
You also use Rigidbodies to bring vehicles to life, for example you can make cars using a Rigidbody, 4 Wheel Colliders and a script applying wheel forces based on the user's Input.
You can make airplanes by applying forces to the Rigidbody from a script. Or you can create special vehicles or robots by adding various Joints and applying forces via scripting.
Rigidbodies are most often used in combination with primitive colliders.
Tips:
- You should never have a parent and child rigidbody together
- You should never scale the parent of a rigidbody
Kinematic Rigidbodies
A Kinematic Rigidbody is a Rigidbody that has the isKinematic option enabled. Kinematic Rigidbodies are not affected by forces, gravity or collisions. They are driven explicitly by setting the position and rotation of the Transform or animating them, yet they can interact with other non-Kinematic Rigidbodies.
Kinematic Rigidbodies correctly wake up other Rigidbodies when they collide with them, and they apply friction to Rigidbodies placed on top of them.
These are a few example uses for Kinematic Rigidbodies:
- Sometimes you want an object to be under physics control but in another situation to be controlled explicitly from a script or animation. For example you could make an animated character whose bones have Rigidbodies attached that are connected with joints for use as a Ragdoll. Most of the time the character is under animation control, thus you make the Rigidbody Kinematic. But when he gets hit you want him to turn into a Ragdoll and be affected by physics. To accomplish this, you simply disable the isKinematic property.
- Sometimes you want a moving object that can push other objects yet not be pushed itself. For example if you have an animated platform and you want to place some Rigidbody boxes on top, you should make the platform a Kinematic Rigidbody instead of just a Collider without a Rigidbody.
- You might want to have a Kinematic Rigidbody that is animated and have a real Rigidbody follow it using one of the available Joints.
Static Colliders
A Static Collider is a GameObject that has a Collider but not a Rigidbody. Static Colliders are used for level geometry which always stays at the same place and never moves around. You can add a Mesh Collider to your already existing graphical meshes (even better use the Generate Colliders check box), or you can use one of the other Collider types.
You should never move a Static Collider on a frame by frame basis. Moving Static Colliders will cause an internal recomputation in PhysX that is quite expensive and which will result in a big drop in performance. On top of that the behaviour of waking up other Rigidbodies based on a Static Collider is undefined, and moving Static Colliders will not apply friction to Rigidbodies that touch it. Instead, Colliders that move should always be Kinematic Rigidbodies.
Character Controllers
You use Character Controllers if you want to make a humanoid character. This could be the main character in a third person platformer, FPS shooter or any enemy characters.
These Controllers don't follow the rules of physics since it will not feel right (in Doom you run 90 miles per hour, come to halt in one frame and turn on a dime). Instead, a Character Controller performs collision detection to make sure your characters can slide along walls, walk up and down stairs, etc.
Character Controllers are not affected by forces but they can push Rigidbodies by applying forces to them from a script. Usually, all humanoid characters are implemented using Character Controllers.
Character Controllers are inherently unphysical, thus if you want to apply real physics - Swing on ropes, get pushed by big rocks - to your character you have to use a Rigidbody, this will let you use joints and forces on your character. Character Controllers are always aligned along the Y axis, so you also need to use a Rigidbody if your character needs to be able to change orientation in space (for example under a changing gravity). However, be aware that tuning a Rigidbody to feel right for a character is hard due to the unphysical way in which game characters are expected to behave. Another difference is that Character Controllers can slide smoothly over steps of a specified height, while Rigidbodies will not.
If you parent a Character Controller with a Rigidbody you will get a "Joint" like behavior.
Rigidbody
Rigidbodies enable your GameObjects to act under the control of physics. The Rigidbody can receive forces and torque to make your objects move in a realistic way. Any GameObject must contain a Rigidbody to be influenced by gravity, act under added forces via scripting, or interact with other objects through the NVIDIA PhysX physics engine.

Rigidbodies allow GameObjects to act under physical influence
Properties
| Mass | The mass of the object (arbitrary units). It is recommended to make masses not more or less than 100 times that of other Rigidbodies. |
| Drag | How much air resistance affects the object when moving from forces. 0 means no air resistance, and infinity makes the object stop moving immediately. |
| Angular Drag | How much air resistance affects the object when rotating from torque. 0 means no air resistance, and infinity makes the object stop rotating immediately. |
| Use Gravity | If enabled, the object is affected by gravity. |
| Is Kinematic | If enabled, the object will not be driven by the physics engine, and can only be manipulated by its Transform. This is useful for moving platforms or if you want to animate a Rigidbody that has a HingeJoint attached. |
| Interpolate | Try one of the options only if you are seeing jerkiness in your Rigidbody's movement. |
| None | No Interpolation is applied. |
| Interpolate | Transform is smoothed based on the Transform of the previous frame. |
| Extrapolate | Transform is smoothed based on the estimated Transform of the next frame. |
| Freeze Rotation | If enabled, this GameObject will never rotate based on collisions or forces added via script -- it will only rotate when using transform.Rotate(). |
| Collision Detection | Used to prevent fast moving objects from passing through other objects without detecting collisions. |
| Discrete | Use Discreet collision detection against all other colliders in the scene. Other colliders will use Discreet collision detection when testing for collision against it. Used for normal collisions (This is the default value). |
| Continuous | Use Discrete collision detection against dynamic colliders (with a rigidbody) and continuous collision detection against static MeshColliders (without a rigidbody). Rigidbodies set to Continuous Dynamic will use continuous collision detection when testing for collision against this rigidbody. Other rigidbodies will use Discreet Collision detection. Used for objects which the Continuous Dynamic detection needs to collide with. (This has a big impact on physics performance, leave it set to Discrete, if you don't have issues with collisions of fast objects) |
| Continuous Dynamic | Use continuous collision detection against objects set to Continuous and Continuous Dynamic Collision. It will also use continuous collision detection against static MeshColliders (without a rigidbody). For all other colliders it uses discreet collision detection. Used for fast moving objects. |
| Constraints | Restrictions on the Rigidbody's motion:- |
| Freeze Position | Stops the Rigidbody moving in the world X, Y and Z axes selectively. |
| Freeze Rotation | Stops the Rigidbody rotating around the world X, Y and Z axes selectively. |
Details
Rigidbodies allow your GameObjects to act under control of the physics engine. This opens the gateway to realistic collisions, varied types of joints, and other very cool behaviors. Manipulating your GameObjects by adding forces to a Rigidbody creates a very different feel and look than adjusting the Transform Component directly. Generally, you shouldn't manipulate the Rigidbody and the Transform of the same GameObject - only one or the other.
The biggest difference between manipulating the Transform versus the Rigidbody is the use of forces. Rigidbodies can receive forces and torque, but Transforms cannot. Transforms can be translated and rotated, but this is not the same as using physics. You'll notice the distinct difference when you try it for yourself. Adding forces/torque to the Rigidbody will actually change the object's position and rotation of the Transform component. This is why you should only be using one or the other. Changing the Transform while using physics could cause problems with collisions and other calculations.
Rigidbodies must be explicitly added to your GameObject before they will be affected by the physics engine. You can add a Rigidbody to your selected object from Components->Physics->Rigidbody in the menubar. Now your object is physics-ready; it will fall under gravity and can receive forces via scripting, but you may need to add a Collider or a Joint to get it to behave exactly how you want.
Parenting
When an object is under physics control, it moves semi-independently of the way its transform parents move. If you move any parents, they will pull the Rigidbody child along with them. However, the Rigidbodies will still fall down due to gravity and react to collision events.
Scripting
To control your Rigidbodies, you will primarily use scripts to add forces or torque. You do this by calling AddForce() and AddTorque() on the object's Rigidbody. Remember that you shouldn't be directly altering the object's Transform when you are using physics.
Animation
For some situations, mainly creating ragdoll effects, it is neccessary to switch control of the object between animations and physics. For this purpose Rigidbodies can be marked isKinematic. While the Rigidbody is marked isKinematic, it will not be affected by collisions, forces, or any other part of physX. This means that you will have to control the object by manipulating the Transform component directly. Kinematic Rigidbodies will affect other objects, but they themselves will not be affected by physics. For example, Joints which are attached to Kinematic objects will constrain any other Rigidbodies attached to them and Kinematic Rigidbodies will affect other Rigidbodies through collisions.
Colliders
Colliders are another kind of component that must be added alongside the Rigidbody in order to allow collisions to occur. If two Rigidbodies bump into each other, the physics engine will not calculate a collision unless both objects also have a Collider attached. Collider-less Rigidbodies will simply pass through each other during physics simulation.

Colliders define the physical boundaries of a Rigidbody
Add a Collider with the Component->Physics menu. View the Component Reference page of any individual Collider for more specific information:
- Box Collider - primitive shape of a cube
- Sphere Collider - primitive shape of a sphere
- Capsule Collider - primitive shape of a capsule
- Mesh Collider - creates a collider from the object's mesh, cannot collide with another Mesh Collider
- Wheel Collider - specifically for creating cars or other moving vehicles
Compound Colliders
Compound Colliders are combinations of primitive Colliders, collectively acting as a single Collider. They come in handy when you have a complex mesh to use in collisions but cannot use a Mesh Collider. To create a Compound Collider, create child objects of your colliding object, then add a primitive Collider to each child object. This allows you to position, rotate, and scale each Collider easily and independently of one another.

A real-world Compound Collider setup
In the above picture, the environment has a Mesh Collider attached. Mesh Colliders work the best for terrain or environments made from irregular shapes. The GameObject has a Rigidbody attached, and multiple primitive Colliders as child GameObjects. When the Rigidbody parent is moved around by forces, the child Colliders move along with it. The primitive Colliders will collide with the environment's Mesh Collider, and the parent Rigidbody will alter the way it moves based on forces being applied to it and how its child Colliders interact with other Colliders in the Scene.
Mesh Colliders can't normally collide with each other. If a Mesh Collider is marked as Convex, then it can collide with another Mesh Collider. The typical solution is to use primitive Colliders for any objects that move, and Mesh Colliders for static background objects.
Continuous Collision Detection
Continuous collision detection is a feature to prevent fast-moving colliders from passing each other. This may happen when using normal (Discrete) collision detection, when an object is one side of a collider in one frame, and already passed the collider in the next frame. To solve this, you can enable continuous collision detection on the rigidbody of the fast-moving object. Set the collision detection mode to Continuous to prevent the rigidbody from passing through any static (ie, non-rigidbody) MeshColliders. Set it to Continuous Dynamic to also prevent the rigidbody from passing through any other supported rigidbodies with collision detection mode set to Continuous or Continuous Dynamic. Continuous collision detection is supported for Box-, Sphere- and CapsuleColliders.
Use the right size
The size of the your GameObject's mesh is much more important than the mass of the Rigidbody. If you find that your Rigidbody is not behaving exactly how you expect - it moves slowly, floats, or doesn't collide correctly - consider adjusting the scale of your mesh asset. Unity's default unit scale is 1 unit = 1 meter, so the scale of your imported mesh is maintained, and applied to physics calculations. For example, a crumbling skyscraper is going to fall apart very differently than a tower made of toy blocks, so objects of different sizes should be modeled to accurate scale.
If you are modeling a human make sure he is around 2 meters tall in Unity. To check if your object has the right size compare it to the default cube. You can create a cube using . The cube's height will be exactly 1 meter, so your human should be twice as tall.
If you aren't able to adjust the mesh itself, you can change the uniform scale of a particular mesh asset by selecting it in Project View and choosing from the menubar. Here, you can change the scale and re-import your mesh.
If your game requires that your GameObject needs to be instantiated at different scales, it is okay to adjust the values of your Transform's scale axes. The downside is that the physics simulation must do more work at the time the object is instantiated, and could cause a performance drop in your game. This isn't a terrible loss, but it is not as efficient as finalizing your scale with the other two options. Also keep in mind that non-uniform scales can create undesirable behaviors when Parenting is used. For these reasons it is always optimal to create your object at the correct scale in your modeling application.
Hints
- The relative Mass of two Rigidbodies determines how they react when they collide with each other.
- Making one Rigidbody have greater Mass than another does not make it fall faster in free fall. Use Drag for that.
- A low Drag value makes an object seem heavy. A high one makes it seem light. Typical values for Drag are between .001 (solid block of metal) and 10 (feather).
- If you are directly manipulating the Transform component of your object but still want physics, attach a Rigidbody and make it Kinematic.
- If you are moving a GameObject through its Transform component but you want to receive Collision/Trigger messages, you must attach a Rigidbody to the object that is moving.
Constant Force
Constant Force is a quick utility for adding constant forces to a Rigidbody. This works great for one shot objects like rockets, if you don't want it to start with a large velocity but instead accelerate.

A rocket propelled forward by a Constant Force
Properties
| Force | The vector of a force to be applied in world space. |
| Relative Force | The vector of a force to be applied in the object's local space. |
| Torque | The vector of a torque, applied in world space. The object will begin spinning around this vector. The longer the vector is, the faster the rotation. |
| Relative Torque | The vector of a torque, applied in local space. The object will begin spinning around this vector. The longer the vector is, the faster the rotation. |
Details
To make a rocket that accelerates forward set the Relative Force to be along the positive z-axis. Then use the Rigidbody's Drag property to make it not exceed some maximum velocity (the higher the drag the lower the maximum velocity will be). In the Rigidbody, also make sure to turn off gravity so that the rocket will always stay on its path.
Hints
- To make an object flow upwards, add a Constant Force with the Force property having a positive Y value.
- To make an object fly forwards, add a Constant Force with the Relative Force property having a positive Z value.
Sphere Collider
The Sphere Collider is a basic sphere-shaped collision primitive.

A pile of Sphere Colliders
Properties
| Material | Reference to the Physic Material that determines how this Collider interacts with others. |
| Is Trigger | If enabled, this Collider is used for triggering events, and is ignored by the physics engine. |
| Radius | The size of the Collider. |
| Center | The position of the Collider in the object's local space. |
Details
The Sphere Collider can be resized to uniform scale, but not along individual axes. It works great for falling boulders, ping pong balls, marbles, etc.

A standard Sphere Collider
Colliders work with Rigidbodies to bring physics in Unity to life. Whereas Rigidbodies allow objects to be controlled by physics, Colliders allow objects to collide with each other. Colliders must be added to objects independently of Rigidbodies. A Collider does not necessarily need a Rigidbody attached, but a Rigidbody must be attached in order for the object to move as a result of collisions.
When a collision between two Colliders occurs and if at least one of them has a Rigidbody attached, three collision messages are sent out to the objects attached to them. These events can be handled in scripting, and allow you to create unique behaviors with or without making use of the built-in NVIDIA PhysX engine.
Triggers
An alternative way of using Colliders is to mark them as a Trigger, just check the IsTrigger property checkbox in the Inspector. Triggers are effectively ignored by the physics engine, and have a unique set of three trigger messages that are sent out when a collision with a Trigger occurs. Triggers are useful for triggering other events in your game, like cutscenes, automatic door opening, displaying tutorial messages, etc. Use your imagination!
Be aware that in order for two Triggers to send out trigger events when they collide, one of them must include a Rigidbody as well. For a Trigger to collide with a normal Collider, one of them must have a Rigidbody attached. For a detailed chart of different types of collisions, see the collision action matrix in the Advanced section below.
Friction and bouncyness
Friction, bouncyness and softness are defined in the Physic Material. The Standard Assets contain the most common physics materials. To use one of them click on the Physic Material drop-down and select one, eg. Ice. You can also create your own physics materials and tweak all friction values.
Compound Colliders
Compound Colliders are combinations of primitive Colliders, collectively acting as a single Collider. They come in handy when you have a complex mesh to use in collisions but cannot use a Mesh Collider. To create a Compound Collider, create child objects of your colliding object, then add a primitive Collider to each child object. This allows you to position, rotate, and scale each Collider easily and independently of one another.

A real-world Compound Collider setup
In the above picture, the environment has a Mesh Collider attached. Mesh Colliders work the best for terrain or environments made from irregular shapes. The GameObject has a Rigidbody attached, and multiple primitive Colliders as child GameObjects. When the Rigidbody parent is moved around by forces, the child Colliders move along with it. The primitive Colliders will collide with the environment's Mesh Collider, and the parent Rigidbody will alter the way it moves based on forces being applied to it and how its child Colliders interact with other Colliders in the Scene.
Mesh Colliders can't normally collide with each other. If a Mesh Collider is marked as Convex, then it can collide with another Mesh Collider. The typical solution is to use primitive Colliders for any objects that move, and Mesh Colliders for static background objects.
Hints
- To add multiple Colliders for an object, create child GameObjects and attach a Collider to each one. This allows each Collider to be manipulated independently.
- You can look at the gizmos in the Scene View to see how the Collider is being calculated on your object.
- Colliders do their best to match the scale of an object. If you have a non-uniform scale (a scale which is different in each direction), only the Mesh Collider can match completely.
- If you are moving an object through its Transform component but you want to receive Collision/Trigger messages, you must attach a Rigidbody to the object that is moving.
- If you make an explosion, it can be very effective to add a rigidbody with lots of drag and a sphere collider to it in order to push it out a bit from the wall it hits.
Advanced
Collider combinations
There are numerous different combinations of collisions that can happen in Unity. Each game is unique, and different combinations may work better for different types of games. If you're using physics in your game, it will be very helpful to understand the different basic Collider types, their common uses, and how they interact with other types of objects.
Static Collider
These are GameObjects that do not have a Rigidbody attached, but do have a Collider attached. These objects should remain still, or move very little. These work great for your environment geometry. They will not move if a Rigidbody collides with them.
Rigidbody Collider
These GameObjects contain both a Rigidbody and a Collider. They are completely affected by the physics engine through scripted forces and collisions. They might collide with a GameObject that only contains a Collider. These will likely be your primary type of Collider in games that use physics.
Kinematic Rigidbody Collider
This GameObject contains a Collider and a Rigidbody which is marked IsKinematic. To move this GameObject, you modify its Transform Component, rather than applying forces. They're similar to Static Colliders but will work better when you want to move the Collider around frequently. There are some other specialized scenarios for using this GameObject.
This object can be used for circumstances in which you would normally want a Static Collider to send a trigger event. Since a Trigger must have a Rigidbody attached, you should add a Rigidbody, then enable IsKinematic. This will prevent your Object from moving from physics influence, and allow you to receive trigger events when you want to.
Kinematic Rigidbodies can easily be turned on and off. This is great for creating ragdolls, when you normally want a character to follow an animation, then turn into a ragdoll when a collision occurs, prompted by an explosion or anything else you choose. When this happens, simply turn all your Kinematic Rigidbodies into normal Rigidbodies through scripting.
If you have Rigidbodies come to rest so they are not moving for some time, they will "fall asleep". That is, they will not be calculated during the physics update since they are not going anywhere. If you move a Kinematic Rigidbody out from underneath normal Rigidbodies that are at rest on top of it, the sleeping Rigidbodies will "wake up" and be correctly calculated again in the physics update. So if you have a lot of Static Colliders that you want to move around and have different object fall on them correctly, use Kinematic Rigidbody Colliders.
Collision action matrix
Depending on the configurations of the two colliding Objects, a number of different actions can occur. The chart below outlines what you can expect from two colliding Objects, based on the components that are attached to them. Some of the combinations only cause one of the two Objects to be affected by the collision, so keep the standard rule in mind - physics will not be applied to objects that do not have Rigidbodies attached.
| Collision detection occurs and messages are sent upon collision | ||||||
| Static Collider | Rigidbody Collider | Kinematic Rigidbody Collider | Static Trigger Collider | Rigidbody Trigger Collider | Kinematic Rigidbody Trigger Collider | |
| Static Collider | Y | |||||
| Rigidbody Collider | Y | Y | Y | |||
| Kinematic Rigidbody Collider | Y | |||||
| Static Trigger Collider | ||||||
| Rigidbody Trigger Collider | ||||||
| Kinematic Rigidbody Trigger Collider | ||||||
| Trigger messages are sent upon collision | ||||||
| Static Collider | Rigidbody Collider | Kinematic Rigidbody Collider | Static Trigger Collider | Rigidbody Trigger Collider | Kinematic Rigidbody Trigger Collider | |
| Static Collider | Y | Y | ||||
| Rigidbody Collider | Y | Y | Y | |||
| Kinematic Rigidbody Collider | Y | Y | Y | |||
| Static Trigger Collider | Y | Y | Y | Y | ||
| Rigidbody Trigger Collider | Y | Y | Y | Y | Y | Y |
| Kinematic Rigidbody Trigger Collider | Y | Y | Y | Y | Y | Y |
Layer-Based Collision Detection
In Unity 3.x we introduce something called Layer-Based Collision Detection, and is that you can now selectively tell Unity GameObjects to collide with specific layers they are attached to. For more info, you can click here
Box Collider
The Box Collider is a basic cube-shaped collision primitive.

A pile of Box Colliders
Properties
| Material | Reference to the Physic Material that determines how this Collider interacts with others. |
| Is Trigger | If enabled, this Collider is used for triggering events, and is ignored by the physics engine. |
| Size | The size of the Collider in the X, Y, Z directions. |
| Center | The position of the Collider in the object's local space. |
Details
The Box Collider can be resized into different shapes of rectangular prisms. It works great for doors, walls, platforms, etc. It is also effective as a human torso in a ragdoll or as a car hull in a vehicle. Of course, it works perfectly for just boxes and crates as well!

A standard Box Collider
Colliders work with Rigidbodies to bring physics in Unity to life. Whereas Rigidbodies allow objects to be controlled by physics, Colliders allow objects to collide with each other. Colliders must be added to objects independently of Rigidbodies. A Collider does not necessarily need a Rigidbody attached, but a Rigidbody must be attached in order for the object to move as a result of collisions.
When a collision between two Colliders occurs and if at least one of them has a Rigidbody attached, three collision messages are sent out to the objects attached to them. These events can be handled in scripting, and allow you to create unique behaviors with or without making use of the built-in NVIDIA PhysX engine.
Triggers
An alternative way of using Colliders is to mark them as a Trigger, just check the IsTrigger property checkbox in the Inspector. Triggers are effectively ignored by the physics engine, and have a unique set of three trigger messages that are sent out when a collision with a Trigger occurs. Triggers are useful for triggering other events in your game, like cutscenes, automatic door opening, displaying tutorial messages, etc. Use your imagination!
Be aware that in order for two Triggers to send out trigger events when they collide, one of them must include a Rigidbody as well. For a Trigger to collide with a normal Collider, one of them must have a Rigidbody attached. For a detailed chart of different types of collisions, see the collision action matrix in the Advanced section below.
Friction and bouncyness
Friction, bouncyness and softness are defined in the Physic Material. The Standard Assets contain the most common physics materials. To use one of them click on the Physic Material drop-down and select one, eg. Ice. You can also create your own physics materials and tweak all friction values.
Mesh Collider
The Mesh Collider takes a Mesh Asset and builds its Collider based on that mesh. It is far more accurate for collision detection than using primitives for complicated meshes. Mesh Colliders that are marked as Convex can collide with other Mesh Colliders.

A Mesh Collider used on level geometry
Properties
| Material | Reference to the Physic Material that determines how this Collider interacts with others. |
| Is Trigger | If enabled, this Collider is used for triggering events, and is ignored by the physics engine. |
| Mesh | Reference to the Mesh to use for collisions. |
| Smooth Sphere Collisions | When this is enabled, collision mesh normals are smoothed. You should enable this on smooth surfaces eg. rolling terrain without hard edges to make sphere rolling smoother. |
| Convex | If enabled, this Mesh Collider will collide with other Mesh Colliders. Convex Mesh Colliders are limited to 255 triangles. |
Details
The Mesh Collider builds its collision representation from the Mesh attached to the GameObject, and reads the properties of the attached Transform to set its position and scale correctly.
Collision meshes use backface culling. If an object collides with a mesh that will be backface culled graphically it will also not collide with it physically.
There are some limitations when using the Mesh Collider. Usually, two Mesh Colliders cannot collide with each other. All Mesh Colliders can collide with any primitive Collider. If your mesh is marked as Convex, then it can collide with other Mesh Colliders.
Colliders work with Rigidbodies to bring physics in Unity to life. Whereas Rigidbodies allow objects to be controlled by physics, Colliders allow objects to collide with each other. Colliders must be added to objects independently of Rigidbodies. A Collider does not necessarily need a Rigidbody attached, but a Rigidbody must be attached in order for the object to move as a result of collisions.
When a collision between two Colliders occurs and if at least one of them has a Rigidbody attached, three collision messages are sent out to the objects attached to them. These events can be handled in scripting, and allow you to create unique behaviors with or without making use of the built-in NVIDIA PhysX engine.
Triggers
An alternative way of using Colliders is to mark them as a Trigger, just check the IsTrigger property checkbox in the Inspector. Triggers are effectively ignored by the physics engine, and have a unique set of three trigger messages that are sent out when a collision with a Trigger occurs. Triggers are useful for triggering other events in your game, like cutscenes, automatic door opening, displaying tutorial messages, etc. Use your imagination!
Be aware that in order for two Triggers to send out trigger events when they collide, one of them must include a Rigidbody as well. For a Trigger to collide with a normal Collider, one of them must have a Rigidbody attached. For a detailed chart of different types of collisions, see the collision action matrix in the Advanced section below.
Friction and bouncyness
Friction, bouncyness and softness are defined in the Physic Material. The Standard Assets contain the most common physics materials. To use one of them click on the Physic Material drop-down and select one, eg. Ice. You can also create your own physics materials and tweak all friction values.
Hints
- Mesh Colliders cannot collide with each other unless they are marked as Convex. Therefore, they are most useful for background objects like environment geometry.
- Convex Mesh Colliders must be fewer than 255 triangles.
- Primitive Colliders are less costly for objects under physics control.
- When you attach a Mesh Collider to a GameObject, its Mesh property will default to the mesh being rendered. You can change that by assigning a different Mesh.
- To add multiple Colliders for an object, create child GameObjects and attach a Collider to each one. This allows each Collider to be manipulated independently.
- You can look at the gizmos in the Scene View to see how the Collider is being calculated on your object.
- Colliders do their best to match the scale of an object. If you have a non-uniform scale (a scale which is different in each direction), only the Mesh Collider can match completely.
- If you are moving an object through its Transform component but you want to receive Collision/Trigger messages, you must attach a Rigidbody to the object that is moving.
Physic Material
The Physic Material is used to adjust friction and bouncing effects of colliding objects.
To create a Physic Material select from the menu bar. Then drag the Physic Material from the Project View onto a Collider in the scene.

The Physic Material Inspector
Properties
| Dynamic Friction | The friction used when already moving. Usually a value from 0 to 1. A value of zero feels like ice, a value of 1 will make it come to rest very quickly unless a lot of force or gravity pushes the object. |
| Static Friction | The friction used when an object is laying still on a surface. Usually a value from 0 to 1. A value of zero feels like ice, a value of 1 will make it very hard to get the object moving. |
| Bouncyness | How bouncy is the surface? A value of 0 will not bounce. A value of 1 will bounce without any loss of energy. |
| Friction Combine Mode | How the friction of two colliding objects is combined. |
| Average | The two friction values are averaged. |
| Min | The smallest of the two values is used. |
| Max | The largest of the two values is used. |
| Multiply | The friction values are multiplied with each other. |
| Bounce Combine | How the bouncyness of two colliding objects is combined. It has the same modes as Friction Combine Mode |
| Friction Direction 2 | The direction of anisotropy. Anisotropic friction is enabled if this direction is not zero. Dynamic Friction 2 and Static Friction 2 will be applied along Friction Direction 2. |
| Dynamic Friction 2 | If anisotropic friction is enabled, DynamicFriction2 will be applied along Friction Direction 2. |
| Static Friction 2 | If anisotropic friction is enabled, StaticFriction2 will be applied along Friction Direction 2. |
Details
Friction is the quantity which prevents surfaces from sliding off each other. This value is critical when trying to stack objects. Friction comes in two forms, dynamic and static. Static friction is used when the object is lying still. It will prevent the object from starting to move. If a large enough force is applied to the object it will start moving. At this point Dynamic Friction will come into play. Dynamic Friction will now attempt to slow down the object while in contact with another.
Hints
- Don't try to use a standard physic material for the main character. Make a customized one and get it perfect.
Hinge Joint
The Hinge Joint groups together two Rigidbodies, constraining them to move like they are connected by a hinge. It is perfect for doors, but can also be used to model chains, pendulums, etc.

The Hinge Joint Inspector
Properties
| Connected Body | Optional reference to the Rigidbody that the joint is dependent upon. If not set, the joint connects to the world. |
| Anchor | The position of the axis around which the body swings. The position is defined in local space. |
| Axis | The direction of the axis around which the body swings. The direction is defined in local space. |
| Use Spring | Spring makes the Rigidbody reach for a specific angle compared to its connected body. |
| Spring | Properties of the Spring that are used if Use Spring is enabled. |
| Spring | The force the object asserts to move into the position. |
| Damper | The higher this value, the more the object will slow down. |
| Target Position | Target angle of the spring. The spring pulls towards this angle measured in degrees. |
| Use Motor | The motor makes the object spin around. |
| Motor | Properties of the Motor that are used if Use Motor is enabled. |
| Target Velocity | The speed the object tries to attain. |
| Force | The force applied in order to attain the speed. |
| Free Spin | If enabled, the motor is never used to brake the spinning, only accelerate it. |
| Use Limits | If enabled, the angle of the hinge will be restricted within the Min & Max values. |
| Limits | Properties of the Limits that are used if Use Limits is enabled. |
| Min | The lowest angle the rotation can go. |
| Max | The highest angle the rotation can go. |
| Min Bounce | How much the object bounces when it hits the minimum stop. |
| Max Bounce | How much the object bounces when it hits the maximum stop. |
| Break Force | The force that needs to be applied for this joint to break. |
| Break Torque | The torque that needs to be applied for this joint to break. |
Details
A single Hinge Joint should be applied to a GameObject. The hinge will rotate at the point specified by the Anchor property, moving around the specified Axis property. You do not need to assign a GameObject to the joint's Connected Body property. You should only assign a GameObject to the Connected Body property if you want the joint's Transform to be dependent on the attached object's Transform.
Think about how the hinge of a door works. The Axis in this case is up, positive along the Y axis. The Anchor is placed somewhere at the intersection between door and wall. You would not need to assign the wall to the Connected Body, because the joint will be connected to the world by default.
Now think about a doggy door hinge. The doggy door's Axis would be sideways, positive along the relative X axis. The main door should be assigned as the Connected Body, so the doggy door's hinge is dependent on the main door's Rigidbody.
Chains
Multiple Hinge Joints can also be strung together to create a chain. Add a joint to each link in the chain, and attach the next link as the Connected Body.
Hints
- You do not need to assign a Connected Body to your joint for it to work.
- Use Break Force in order to make dynamic damage systems. This is really cool as it allows the player to break a door off its hinge by blasting it with a rocket launcher or running into it with a car.
- The Spring, Motor, and Limits properties allow you to fine-tune your joint's behaviors.
Spring Joint
The Spring Joint groups together two Rigidbodies, constraining them to move like they are connected by a spring.

The Spring Joint Inspector
Properties
| Connected Body | Optional reference to the Rigidbody that the joint is dependent upon. |
| Anchor | Position in the object's local space (at rest) that defines the center of the joint. This is not the point that the object will be drawn toward. |
| X | Position of the joint's local center along the X axis. |
| Y | Position of the joint's local center along the Y axis. |
| Z | Position of the joint's local center along the Z axis. |
| Spring | Strength of the spring. |
| Damper | Amount that the spring is reduced when active. |
| Min Distance | Distances greater than this will not cause the Spring to activate. |
| Max Distance | Distances less than this will not cause the Spring to activate. |
| Break Force | The force that needs to be applied for this joint to break. |
| Break Torque | The torque that needs to be applied for this joint to break. |
Details
Spring Joints allows a Rigidbodied GameObject to be pulled toward a particular "target" position. This position will either be another Rigidbodied GameObject or the world. As the GameObject travels further away from this "target" position, the Spring Joint applies forces that will pull it back to its original "target" position. This creates an effect very similar to a rubber band or a slingshot.
The "target" position of the Spring is determined by the relative position from the Anchor to the Connected Body (or the world) when the Spring Joint is created, or when Play mode is entered. This makes the Spring Joint very effective at setting up Jointed characters or objects in the Editor, but is harder to create push/pull spring behaviors in runtime through scripting. If you want to primarily control a GameObject's position using a Spring Joint, it is best to create an empty GameObject with a Rigidbody, and set that to be the Connected Rigidbody of the Jointed object. Then in scripting you can change the position of the Connected Rigidbody and see your Spring move in the ways you expect.
Connected Rigidbody
You do not need to use a Connected Rigidbody for your joint to work. Generally, you should only use one if your object's position and/or rotation is dependent on it. If there is no Connected Rigidbody, your Spring will connect to the world.
Spring & Damper
Spring is the strength of the force that draws the object back toward its "target" position. If this is 0, then there is no force that will pull on the object, and it will behave as if no Spring Joint is attached at all.
Damper is the resistance encountered by the Spring force. The lower this is, the springier the object will be. As the Damper is increased, the amount of bounciness caused by the Joint will be reduced.
Min & Max Distance
If the position of your object falls in-between the Min & Max Distances, then the Joint will not be applied to your object. The position must be moved outside of these values for the Joint to activate.
Hints
- You do not need to assign a Connected Body to your Joint for it to work.
- Set the ideal positions of your Jointed objects in the Editor prior to entering Play mode.
- Spring Joints require your object to have a Rigidbody attached.
iOS
iOS physics optimization hints can be found here.
RandomNumbers
Randomly chosen items or values are important in many games. This sections shows how you can use Unity's built-in random functions to implement some common game mechanics.
Choosing a Random Item from an Array
Picking an array element at random boils down to choosing a random integer between zero and the array's maximum index value (which is equal to the length of the array minus one). This is easily done using the built-in Random.Range function:-
var element = myArray[Random.Range(0, myArray.Length)];
Note that Random.Range returns a value from a range that includes the first parameter but excludes the second, so using myArray.Length here gives the correct result.
Choosing Items with Different Probabilities
Sometimes, you need to choose items at random but with some items more likely to be chosen than others. For example, an NPC may react in several different ways when it encounters a player:-
- 50% chance of friendly greeting
- 25% chance of running away
- 20% chance of immediate attack
- 5% chance of offering money as a gift
You can visualise these different outcomes as a paper strip divided into sections each of which occupies a fraction of the strip's total length. The fraction occupied is equal to the probability of that outcome being chosen. Making the choice is equivalent to picking a random point along the strip's length (say by throwing a dart) and then seeing which section it is in.

In the script, the paper strip is actually an array of floats that contain the different probabilities for the items in order. The random point is obtained by multiplying Random.value by the total of all the floats in the array (they need not add up to 1; the significant thing is the relative size of the different values). To find which array element the point is "in", firstly check to see if it is less than the value in the first element. If so, then the first element is the one selected. Otherwise, subtract the first element's value from the point value and compare that to the second element and so on until the correct element is found. In code, this would look something like the following:-
function Choose(probs: float[]) {
var total = 0;
for (elem in probs) {
total += elem;
}
var randomPoint = Random.value * total;
for (i = 0; i < probs.Length; i++) {
if (randomPoint < probs[i])
return i;
else
randomPoint -= probs[i];
}
return probs.Length - 1;
}
Note that the final return statement is necessary because Random.value can return a result of 1. In this case, the search will not find the random point anywhere. Changing the line
if (randomPoint < probs[i])
...to a less-than-or-equal test would avoid the extra return statement but would also allow an item to be chosen occasionally even when its probability is zero.
Shuffling a List
A common game mechanic is to choose from a known set of items but have them arrive in random order. For example, a deck of cards is typically shuffled so they are not drawn in a predictable sequence. You can shuffle the items in an array by visiting each element and swapping it with another element at a random index in the array:-
function Shuffle(deck: int[]) {
for (i = 0; i < deck.Length; i++) {
var temp = deck[i];
var randomIndex = Random.Range(0, deck.Length);
deck[i] = deck[randomIndex];
deck[randomIndex] = temp;
}
}
Choosing from a Set of Items Without Repetition
A common task is to pick a number of items randomly from a set without picking the same one more than once. For example, you may want to generate a number of NPCs at random spawn points but be sure that only one NPC gets generated at each point. This can be done by iterating through the items in sequence, making a random decision for each as to whether or not it gets added to the chosen set. As each item is visited, the probability of its being chosen is equal to the number of items still needed divided by the number still left to choose from.
As an example, suppose that ten spawn points are available but only five must be chosen. The probability of the first item being chosen will be 5 / 10 or 0.5. If it is chosen then the probability for the second item will be 4 / 9 or 0.44 (ie, four items still needed, nine left to choose from). However, if the first was not chosen then the probability for the second will be 5 / 9 or 0.56 (ie, five still needed, nine left to choose from). This continues until the set contains the five items required. You could accomplish this in code as follows:-
var spawnPoints: Transform[];
function ChooseSet(numRequired: int) {
var result = new Transform[numRequired];
var numToChoose = numRequired;
for (numLeft = spawnPoints.Length; numLeft > 0; numLeft--) {
// Adding 0.0 is simply to cast the integers to float for the division.
var prob = numToChoose + 0.0 / numLeft + 0.0;
if (Random.value <= prob) {
numToChoose--;
result[numToChoose] = spawnPoints[numLeft - 1];
if (numToChoose == 0)
break;
}
}
return result;
}
Note that although the selection is random, items in the chosen set will be in the same order they had in the original array. If the items are to be used one at a time in sequence then the ordering can make them partly predictable, so it may be necessary to shuffle the array before use.
Random Points in Space
A random point in a cubic volume can be chosen by setting each component of a Vector3 to a value returned by Random.value:-
var randVec = Vector3(Random.value, Random.value, Random.value);
This gives a point inside a cube with sides one unit long. The cube can be scaled simply by multiplying the X, Y and Z components of the vector by the desired side lengths. If one of the axes is set to zero, the point will always lie within a single plane. For example, picking a random point on the "ground" is usually a matter of setting the X and Z components randomly and setting the Y component to zero.
When the volume is a sphere (ie, when you want a random point within a given radius from a point of origin), you can use Random.insideUnitSphere multiplied by the desired radius:-
var randWithinRadius = Random.insideUnitSphere * radius;
Note that if you set one of the resulting vector's components to zero, you will *not* get a correct random point within a circle. Although the point is indeed random and lies within the right radius, the probability is heavily biased toward the edge of the circle and so points will be spread very unevenly. You should use Random.insideUnitCircle for this task instead:-
var randWithinCircle = Random.insideUnitCircle * radius;
Particle Systems
Particle System (Shuriken)
Particle Systems in Unity are used to make clouds of smoke, steam, fire and other atmospheric effects.

You can create a new particle system by creating a Particle System GameObject (menu -> -> ) or by creating an empty GameObject and adding the ParticleSystem component to it (in ->)
The Particle System Inspector (Shuriken)
The shows one particle system at a time (the currently selected one), and it looks like this:

Individual particle systems can take on various complex behaviors by using Modules.
They can also be extended by being grouped together into Particle Effects.
If you press the button , this will open up the Extended , that shows all of the particle systems under the same root in the scene tree. For more information on particle system grouping, please see the section on Particle Effects.
Scene View Editing
When creating and editing Particle Systems, you either work with the or the extended , and your changes are reflected in the . The scene view has a , where playback of the currently selected can be controlled in Edit Mode, with actions like , , and

Scrubbing play back time can be performed by dragging on the label Playback Time. All Playback controls have shortcut keys which can be customized in the Preferences window
Particle System Curve Editor
MinMax curves
Many of the properties in the particle system modules describe a change of a value with time. That change is described via MinMax Curves. These time-animated properties (for example size and speed), will have a pull down menu on the right hand side, where you can choose between:

Constant: The value of the property will not change with time, and will not be displayed in the Curve Editor
Random between constants: The value of the property will be selected at random between the two constants
Curve: The value of the property will change with time based on the curve specified in the Curve Editor

Random between curves: A curve will be generated at random between the min and the max curve, and the value of the property will change in time based on the generated curve

A property animated as Random Between Two Curves
In the Curve Editor, the x-axis spans time between 0 and the value specified by the Duration property, and the y-axis represents the value of the animated property at each point in time. The range of the y-axis can be adjusted in the number field in the upper right corner of the Curve Editor. The Curve Editor currently displays all of the curves for a particle system in the same window.
Note that the "-" in the bottom-right corner will remove the currently selected curve, while the "+" will optimize it (that is make it into a parametrized curve with at most 3 keys).
For animating properties that describe vectors in 3D space, we use the TripleMinMax Curves, which are simply curves for the x-,y-, and z- dimensions side by side, and it looks like this:

Managing many curves in the curve editor
To avoid cluttering in the Curve Editor, it is possible to toggle curves on and off, by clicking on them in the inspector. The Particle System Curve Editor can also be detached from the Inspector by right-clicking on the Particle System Curves title bar, after which you should see something like this:
A detached Curve Editor that can be docked like any other window
For more information on working with curves, take a look at the Curve Editor documentation
Colors and Gradients in the Particle System (Shuriken)

For properties that deal with color, the Particle System makes use of the Color and Gradient Editor. It works in a similar way to the Curve Editor.
The color-based properties will have a pull down menu on the right hand side, where you can choose between:

Color: The color will be the same throughout time (see Color Picker)
Gradient: The gradient (RGBA) will vary throughout time, edited in the Gradient Editor
Random Between Two Colors: The color varies with time and is chosen at random between two values specified in the Color Picker
Random Between Two Gradients: The gradient (RGBA) varies with time and is chosen at random between two values specified Gradient Editor
- Particle System Curve Editor
- Colors and Gradients in the Particle System (Shuriken)
- Gradient Editor
- Particle System Inspector
- Introduction to Particle System Modules (Shuriken)
- Particle System Modules (Shuriken)
- Particle Effects (Shuriken)
Particle System Curve Editor
MinMax curves
Many of the properties in the particle system modules describe a change of a value with time. That change is described via MinMax Curves. These time-animated properties (for example size and speed), will have a pull down menu on the right hand side, where you can choose between:

Constant: The value of the property will not change with time, and will not be displayed in the Curve Editor
Random between constants: The value of the property will be selected at random between the two constants
Curve: The value of the property will change with time based on the curve specified in the Curve Editor

Random between curves: A curve will be generated at random between the min and the max curve, and the value of the property will change in time based on the generated curve

A property animated as Random Between Two Curves
In the Curve Editor, the x-axis spans time between 0 and the value specified by the Duration property, and the y-axis represents the value of the animated property at each point in time. The range of the y-axis can be adjusted in the number field in the upper right corner of the Curve Editor. The Curve Editor currently displays all of the curves for a particle system in the same window.
Note that the "-" in the bottom-right corner will remove the currently selected curve, while the "+" will optimize it (that is make it into a parametrized curve with at most 3 keys).
For animating properties that describe vectors in 3D space, we use the TripleMinMax Curves, which are simply curves for the x-,y-, and z- dimensions side by side, and it looks like this:

Managing many curves in the curve editor
To avoid cluttering in the Curve Editor, it is possible to toggle curves on and off, by clicking on them in the inspector. The Particle System Curve Editor can also be detached from the Inspector by right-clicking on the Particle System Curves title bar, after which you should see something like this:
A detached Curve Editor that can be docked like any other window
For more information on working with curves, take a look at the Curve Editor documentation
Page last updated: 2012-01-16Particle System Color Editor

For properties that deal with color, the Particle System makes use of the Color and Gradient Editor. It works in a similar way to the Curve Editor.
The color-based properties will have a pull down menu on the right hand side, where you can choose between:

Color: The color will be the same throughout time (see Color Picker)
Gradient: The gradient (RGBA) will vary throughout time, edited in the Gradient Editor
Random Between Two Colors: The color varies with time and is chosen at random between two values specified in the Color Picker
Random Between Two Gradients: The gradient (RGBA) varies with time and is chosen at random between two values specified Gradient Editor
Page last updated: 2012-01-13Particle System Gradient Editor

The Gradient Editor is used for describing change of gradient with time. It animates the color (RGB-space, described by the markers at the bottom), and Alpha (described by the markersat the top).
You can add new markers for Alpha values by clicking at near the top of the rectangle, and new ticks for Color by clicking near the bottom. The markers can be intuitively dragged along the timeline.
If an Alpha tick is selected, you can edit the value for that tick by dragging the alpha value.
If a Color tick is selected, the color can be modified by double clicking on the tick or clicking on the color bar.
To remove a marker, just drag it off the screen.
Page last updated: 2011-11-09Particle System Inspector
The Particle System Inspector (Shuriken)
The shows one particle system at a time (the currently selected one), and it looks like this:

Individual particle systems can take on various complex behaviors by using Modules.
They can also be extended by being grouped together into Particle Effects.
If you press the button , this will open up the Extended , that shows all of the particle systems under the same root in the scene tree. For more information on particle system grouping, please see the section on Particle Effects.
Page last updated: 2012-01-16Particle System Modules Intro
A Particle System consists of a predefined set of modules that can be enabled and disabled. These modules describe the behavior of particles in an individual particle system.
Initially only a few modules are enabled. Addding or removing modules changes the behavior of the particle system. You can add new modules by pressing the (+) sign in the top-right corner of the Particle System Inspector. This pops up a selection menu, where you can choose the module you want to enable.
An alternative way to work with modules is to select "Show All Modules", at which point all of the modules will show up in the inspector.
Then you can enable / disable modules directly from the inspector by clicking the checkbox to the left.

Most of the properties are controllable by curves (see Curve Editor). Color properties are controlled via gradients which define an animation for color (see Color Editor).
For details on individual modules and their properties, see Particle System Modules
Page last updated: 2012-01-13Particle System Modules
This page is dedicated to individual modules and their properties. For introduction to modules see this page
Initial Module

This module is always present, cannot be removed or disabled.
| Duration | The duration the Particle System will be emitting particles. |
| Looping | Is the Particle System looping. |
| Prewarm | Only looping systems can be prewarmed which means that the Particle System will have emitted particles at start as if it had already emitted particles one cycle. |
| Start Delay | Delay in seconds that this Particle System will wait before emitting particles. Note prewarmed looping systems cannot use a start delay |
| Start Lifetime | The lifetime of particles in seconds (see MinMaxCurve) |
| Start Speed | The speed of particles when emitted.(see MinMaxCurve) |
| Start Size | The size of particles when emitted. (see MinMaxCurve) |
| Start Rotation | The rotation of particles when emitted. (see MinMaxCurve) |
| Start Color | The color of particles when emitted. (see MinMaxGradient) |
| Gravity Modifier | The amount of gravity that will affect particles during their lifetime |
| Inherit Velocity | Factor for controlling the amount of velocity the particles should inherit of the transform of the Particle System (for moving Particle Systems) |
| Simulation Space | Simulate the Particle System in local space or world space |
| Play On Awake | If enabled the Particle System will automatically start when it's created. |
| Max Particles | Max number of particles the Particle System will emit |
Emission Module

Controls the rate of particles being emitted and allows spawning large groups of particles at certain moments (over Particle System duration time). Useful for explosions when a bunch of particles need to be created at once.
| Rate | Amount of particles emitted over Time (per second) or Distance (per meter). (see MinMaxCurve) |
| Bursts (Time option only) | Add bursts of particles that occur within the duration of the Particle System |
| Time and Number of Particles | Specify time (in seconds within duration) that a specified amount of particles should be emitted. Use the + and - for adjusting number of bursts. |
Shape Module

Defines the shape of the emitter: Sphere, Hemishpere, Cone, Box and Mesh. Can apply initial force along the surface normal or random direction.
| Sphere | |
| Radius | Radius of the sphere (can also be manipulated by handles in the Scene View) |
| Emit from Shell | Emit from shell of the sphere. If disabled, particles will be emitted from the volume of the sphere. |
| Random Direction | Should particles have have a random direction when emitted or a direction along the surface normal of the sphere |
| Hemisphere | |
| Radius | Radius of the hemisphere (can also be manipulated by handles in the Scene View) |
| Emit from Shell | Emit from shell of the hemisphere. If disabled particles will be emitted from the volume of the hemisphere. |
| Random Direction | Should particles have have a random direction when emitted or a direction along the surface normal of the hemisphere. |
| Cone | |
| Angle | Angle of the cone. If angle is 0 then particles will be emitted in one direction. (can also be manipulated by handles in the Scene View) |
| Radius | A value larger than 0 when basically create a capped cone, using this will change emission from a point to a disc.(can also be manipulated by handles in the Scene View) |
| Box | |
| Box X | Scale of box in X (can also be manipulated by handles in the Scene View) |
| Box Y | Scale of box in Y (can also be manipulated by handles in the Scene View) |
| Box Z | Scale of box in Z (can also be manipulated by handles in the Scene View) |
| Random Direction | Should particles have have a random direction when emitted or a direction along the Z-axis of the box |
| Mesh | |
| Type | Particles can be emitted from either Vertex, Edge or Triangle |
| Mesh | Select Mesh that should be used as emission shape |
| Random Direction | Should particles have have a random direction when emitted or a direction along the surface of the mesh |
Velocity Over Lifetime Module

Directly animates velocity of the particle. Mostly useful for particles which has complex physical, but simple visual behavior (like smoke with turbulence and temperature loss) and has little interaction with physical world.
| XYZ | Use either constant values for curves or random between curves for controlling the movement of the particles. See MinMaxCurve. |
| Space | Local / World: Are the velocity values in local space or world space |
Limit Velocity Over Lifetime Module

Basically can be used to simulate drag. Dampens or clamps velocity, if it is over certain threshold. Can be configured per axis or per vector length.
| Separate Axis | Use for setting per axis control. |
| Speed | Specify magnitude as constant or by curve that will limit all axes of velocity. |
| XYZ | Control each axis seperately. See MinMaxCurve. |
| Dampen | (0-1) value that controls how much the exceeding velocity should be dampened. For example, a value of 0.5 will dampen exceeding velocity by 50% |
Force Over Lifetime Module

| XYZ | Use either constant values for curves or random between curves for controlling the force applied to the particles. See MinMaxCurve. |
| Randomize | Randomize the force applied to the particles every frame |
Color Over Lifetime Module

| Color | Controls the color of each particle during its lifetime. If some particles have a shorter lifetime than others, they will animate faster. Use constant color, random between two colors, animate it using gradient or specify a random color using two gradients. See Gradient. |
| Color Scale | Use the color scale for easy adjustment of color or gradient. |
Color By Speed Module

Animates particle color based on its speed. Remaps speed in the defined range to a color.
| Color | Color used for remapping of speed. Use gradients for varying colors. See MinMaxGradient. |
| Color Scale | Use the color scale for easy adjustment of color or gradient. |
| Speed Range | The min and max values for defining the speed range which is used for remapping a speed to a color. |
Size Over Lifetime Module

| Size | Controls the size of each particle during its lifetime. Use constant size, animate it using a curve or specify a random size using two curves. See MinMaxCurve. |
Size By Speed Module

| Size | Size used for remapping of speed. Use curves for varying sizes. See MinMaxCurve. |
| Speed Range | The min and max values for defining the speed range which is used for remapping a speed to a size. |
Rotation Over Lifetime Module

Specify values in degrees.
| Rotational Speed | Controls the rotational speed of each particle during its lifetime. Use constant rotational speed, animate it using a curve or specify a random rotational speed using two curves. See MinMaxCurve. |
Rotation By Speed Module

| Rotational Speed | Rotational speed used for remapping of a particle's speed. Use curves for varying rotational speeds. See MinMaxCurve. |
| Speed Range | The min and max values for defining the speed range which is used for remapping a speed to a rotational speed. |
Collision Module

Set up collisions for the particles of this Particle System. For now only planar collisions are supported which is a very efficient for simple collision detection. Planes are set up by referencing an existing transform in the scene or by creating a new empty GameObject for this purpose.
| Planes | Planes are defined by assigning a reference to a transform. This transform can be any transform in the scene and can be animated. Multiple planes can be used. Note: the Y-axis is used as the normal of a plane. |
| Dampen | (0-1) When the particle collides, it will keep this fraction of its speed. Unless it is set to 1.0, the particle will become slower after collision |
| Bounce | (0-1) When the particle collides, it will keep this fraction of the component of the velocity, which is normal to the plane of collision |
| Lifetime Loss | (0-1) The fraction of Start Lifetime lost on each collision. When lifetime reaches 0, the particle dies. For example if a particle should die on first collision, set this to 1.0. |
| Visualization | Only used for visualizing the planes: Grid or Solid. |
| Grid | Rendered as gizmos and is useful for quick indication of position and orientation in the world. |
| Solid | Renders a plane in the scene which is useful for exact positioning of a plane. |
| Scale Plane | Resizes the visualization planes. |
Sub Emitter Module

This is a powerful module that enables spawning of other Particle Systems at the follwing particle events: birth, death or collision of a particle.
| Birth | Spawn another Particle System at birth of each particle in this Particle System |
| Death | Spawn another Particle System at death of each particle in this Particle System |
| Collision | Spawn another Particle System at collision of each particle in this Particle System. IMPORTANT: Collison needs to be set up using the Collision Module. See Collision Module |
Texture Sheet Animation Module

Animates UV coordinates of the particle over its lifetime. Animation frames can be presented in a form of a grid or every row in the sheet can be separate animation. The frames are animated with curves or can be a random frame between two curves. The speed of the animation is defined by "Cycles".
| Tiles | Define the tiling of the texture. |
| Animation | Specify the animation type: Whole Sheet or Single Row. |
| Whole Sheet | Uses the whole sheet for uv animation |
| - Frame over Time | Controls the uv animation frame of each particle during its lifetime over the whole sheet. Use constant, animate it using a curve or specify a random frame using two curves. See MinMaxCurve. |
| Single Row | Uses a single row of the texture sheet for uv animation |
| - Random Row | If checked the start row will be random and if unchecked the row index can be specified (first row is 0). |
| - Frame over Time | Controls the uv animation frame of each particle during its lifetime within the specified row. Use constant, animate it using a curve or specify a random frame using two curves. See MinMaxCurve. |
| - Cycles | Specify speed of animation. |
Renderer Module

The renderer module exposes the ParticleSystemRenderer component's properties. Note that even though a GameObject has a ParticleSystemRenderer component, its properties are only exposed here, when this module is removed/added. It is actually the ParticleSystemRenderer component that is added or removed.
| Render Mode | Select one of the following particle render modes |
| Billboard | Makes the particles always face the camera |
| Stretched Billboard | Particles are stretched using the following parameters |
| - Camera Scale | How much the camera speed is factored in when determining particle stretching |
| - Speed Scale | Defines the length of the particle compared to its speed |
| - Length Scale | Defines the length of the particle compared to its width |
| Horizontal Billboard | Makes the particles align with the Y axis |
| Vertical Billboard | Makes the particles align with the XZ plane while facing the camera |
| Mesh | Particles are rendered using a mesh instead of a quad |
| - Mesh | The reference to the mesh used for rendering particles |
| Material | Material used by billboarded or mesh particles. |
| Sort Mode | The draw order of particles can be sorted by distance, youngest first, or oldest first. |
| Sorting Fudge | Use this to affect the draw order. Particle systems with lower sorting fudge numbers are more likely to be drawn last, and thus appear in front of other transparent objects, including other particles. |
| Cast Shadows | Should particles cast shadows? May or may not be possible depending on the material |
| Receive Shadows | Should particles receive shadows? May or may not be possible depending on the material |
| Max Particle Size | Set max relative viewport size. Valid values: 0-1 |
Particle System Grouping
An important feature of Unity's Particle System is that individual Particle Systems can be grouped by being parented to the same root. We will use the term Paricle Effect for such a group. Particle Systems belonging to the same Particle Effect, are played, stopped and paused together.
For managing complex particle effects, Unity provides a Particle Editor, which can be accessed from the Inspector, by pressing

Overview of the Particle System Editor
You can toggle between and in this Editor. will render the entire particle effect. will only render the selected particle systems. What is selected will be highlighted with a blue frame in the Particle Editor and also shown in blue in the Hierarchy view. You can also change the selection both from the Hierarchy View and the Particle Editor, by clicking the icon in the top-left corner of the Particle System. To do a multiselect, use Ctrl+click on windows and Command+click on the Mac.
You can explicitly control rendering order of grouped particles (or otherwise spatially close particle emitters) by tweaking Sorting Fudge property in the Renderer module.

Particle Systems in the same hierarchy is considered as part of the same Particle Effect. This hierarchy shows the setup of the effect shown above.
Page last updated: 2012-01-24Animation
The Animation View in Unity allows you to create and modify Animation Clips directly inside Unity. It is designed to act as a powerful and straightforward alternative to external 3D animation programs. In addition to animating movement, the editor also allows you to animate variables of materials and components and augment your Animation Clips with Animation Events, functions that are called at specified points along the timeline.
See the pages about Animation import and Animation Scripting for further information about these subject.
The Animation View Guide is broken up into several pages that each focus on different areas of the View:-
Using the Animation View
This section covers the basic operations of the Animation View, such as creating and editing Animations Clips.
Using Animation Curves
This section explains how to create Animation Curves, add and move keyframes and set WrapModes. It also offers tips for using Animation Curves to their full advantage.
Editing Curves
This section explains how to navigate efficienlty in the editor, create and move keys, and edit tangents and tangent types.
Objects with Multiple Moving Parts
This section explains how to animate Game Objects with multiple moving parts and how to handle cases where there is more than one Animation Component that can control the selected Game Object.
Using Animation Events
This section explains how to add Animation Events to an Animation Clip. Animation Events allow you call a script function at specified points in the animation's timeline.
Page last updated: 2010-06-30Animation Scripting
Unity's Animation System allows you to create beautifully animated skinned characters. The Animation System supports animation blending, mixing, additive animations, walk cycle time synchronization, animation layers, control over all aspects of the animation playback (time, speed, blend-weights), mesh skinning with 1, 2 or 4 bones per vertex as well as supporting physically based rag-dolls and procedural animation. To obtain the best results, it is recommended that you read about the best practices and techniques for creating a rigged character with optimal performance in Unity on the Modeling Optimized Characters page.
Making an animated character involves two things; moving it through the world and animating it accordingly. If you want to learn more about moving characters around, take a look at the Character Controller page. This page focuses on the animation. The actual animating of characters is done through Unity's scripting interface.
You can download example demos showing pre-setup animated characters. Once you have learned the basics on this page you can also see the animation script interface.
This page contains the following sections:-
- Animation Blending
- Animation Layers
- Animation Mixing
- Additive Animation
- Procedural Animation
- Animation Playback and Sampling
Animation Blending
In today's games, animation blending is an essential feature to ensure that characters have smooth animations. Animators create separate animations, for example, a walk cycle, run cycle, idle animation or shoot animation. At any point in time during your game you need to be able to transition from the idle animation into the walk cycle and vice versa. Naturally, you want the transition to be smooth and avoid sudden jerks in the motion.
This is where animation blending comes in. In Unity you can have any number of animations playing on the same character. All animations are blended or added together to generate the final animation.
Our first step will be to make a character blend smoothly between the idle and walk animations. In order to make the scripter's job easier, we will first set the Wrap Mode of the animation to Loop. Then we will turn off Play Automatically to make sure our script is the only one playing animations.
Our first script for animating the character is quite simple; we only need some way to detect how fast our character is moving, and then fade between the walk and idle animations. For this simple test, we will use the standard input axes:-
function Update () {
if (Input.GetAxis("Vertical") > 0.2)
animation.CrossFade ("walk");
else
animation.CrossFade ("idle");
}
To use this script in your project:-
- Create a Javascript file using .
- Copy and paste the code into it
- Drag the script onto the character (it needs to be attached to the GameObject that has the animation)
When you hit the Play button, the character will start walking in place when you hold the up arrow key and return to the idle pose when you release it.
Animation Layers
Layers are an incredibly useful concept that allow you to group animations and prioritize weighting.
Unity's animation system can blend between as many animation clips as you want. You can assign blend weights manually or simply use animation.CrossFade(), which will animate the weight automatically.
Blend weights are always normalized before being applied
Let's say you have a walk cycle and a run cycle, both having a weight of 1 (100%). When Unity generates the final animation, it will normalize the weights, which means the walk cycle will contribute 50% to the animation and the run cycle will also contribute 50%.
However, you will generally want to prioritize which animation receives most weight when there are two animations playing. It is certainly possible to ensure that the weight sums up to 100% manually, but it is easier just to use layers for this purpose.
Layering Example
As an example, you might have a shoot animation, an idle and a walk cycle. The walk and idle animations would be blended based on the player's speed but when the player shoots, you would want to show only the shoot animation. Thus, the shoot animation essentially has a higher priority.
The easiest way to do this is to simply keep playing the walk and idle animations while shooting. To do this, we need to make sure that the shoot animation is in a higher layer than the idle and walk animations, which means the shoot animation will receive blend weights first. The walk and idle animations will receive weights only if the shoot animation doesn't use all 100% of the blend weighting. So, when CrossFading the shoot animation in, the weight will start out at zero and over a short period become 100%. In the beginning the walk and idle layer will still receive blend weights but when the shoot animation is completely faded in, they will receive no weights at all. This is exactly what we need!
function Start () {
// Set all animations to loop
animation.wrapMode = WrapMode.Loop;
// except shooting
animation["shoot"].wrapMode = WrapMode.Once;
// Put idle and walk into lower layers (The default layer is always 0)
// This will do two things
// - Since shoot and idle/walk are in different layers they will not affect
// each other's playback when calling CrossFade.
// - Since shoot is in a higher layer, the animation will replace idle/walk
// animations when faded in.
animation["shoot"].layer = 1;
// Stop animations that are already playing
//(In case user forgot to disable play automatically)
animation.Stop();
}
function Update () {
// Based on the key that is pressed,
// play the walk animation or the idle animation
if (Mathf.Abs(Input.GetAxis("Vertical")) > 0.1)
animation.CrossFade("walk");
else
animation.CrossFade("idle");
// Shoot
if (Input.GetButtonDown ("Fire1"))
animation.CrossFade("shoot");
}
By default the animation.Play() and animation.CrossFade() will stop or fade out animations that are in the same layer. This is exactly what we want in most cases. In our shoot, idle, run example, playing idle and run will not affect the shoot animation and vice versa (you can change this behavior with an optional parameter to animation.CrossFade if you like).
Animation Mixing
Animation mixing allow you to cut down on the number of animations you need to create for your game by having some animations apply to part of the body only. This means such animations can be used together with other animations in various combinations.
You add an animation mixing transform to an animation by calling AddMixingTransform() on the given AnimationState.
Mixing Example
An example of mixing might be something like a hand-waving animation. You might want to make the hand wave either when the character is idle or when it is walking. Without animation mixing you would have to create separate hand waving animations for the idle and walking states. However, if you add the shoulder transform as a mixing transform to the hand waving animation, the hand waving animation will have full control only from the shoulder joint to the hand. Since the rest of the body will not be affected by he hand-waving, it will continue playing the idle or walk animation. Consequently, only the one animation is needed to make the hand wave while the rest of the body is using the idle or walk animation.
/// Adds a mixing transform using a Transform variable var shoulder : Transform; animation["wave_hand"].AddMixingTransform(shoulder);
Another example using a path.
function Start () {
// Adds a mixing transform using a path instead
var mixTransform : Transform = transform.Find("root/upper_body/left_shoulder");
animation["wave_hand"].AddMixingTransform(mixTransform);
}
Additive Animations
Additive animations and animation mixing allow you to cut down on the number of animations you have to create for your game, and are important for creating facial animations.
Suppose you want to create a character that leans to the sides as it turns while walking and running. This leads to four combinations (walk-lean-left, walk-lean-right, run-lean-left, run-lean-right), each of which needs an animation. Creating a separate animation for each combination clearly leads to a lot of extra work even in this simple case but the number of combinations increases dramatically with each additional action. Fortunately additive animation and mixing avoids the need to produce separate animations for combinations of simple movements.
Additive Animation Example
Additive animations allow you to overlay the effects of one animation on top of any others that may be playing. When generating additive animations, Unity will calculate the difference between the first frame in the animation clip and the current frame. Then it will apply this difference on top of all other playing animations.
Referring to the previous example, you could make animations to lean right and left and Unity would be able to superimpose these on the walk, idle or run cycle. This could be achieved with code like the following:-
private var leanLeft : AnimationState;
private var leanRight : AnimationState;
function Start () {
leanLeft = animation["leanLeft"];
leanRight = animation["leanRight"];
// Put the leaning animation in a separate layer
// So that other calls to CrossFade won't affect it.
leanLeft.layer = 10;
leanRight.layer = 10;
// Set the lean animation to be additive
leanLeft.blendMode = AnimationBlendMode.Additive;
leanRight.blendMode = AnimationBlendMode.Additive;
// Set the lean animation ClampForever
// With ClampForever animations will not stop
// automatically when reaching the end of the clip
leanLeft.wrapMode = WrapMode.ClampForever;
leanRight.wrapMode = WrapMode.ClampForever;
// Enable the animation and fade it in completely
// We don't use animation.Play here because we manually adjust the time
// in the Update function.
// Instead we just enable the animation and set it to full weight
leanRight.enabled = true;
leanLeft.enabled = true;
leanRight.weight = 1.0;
leanLeft.weight = 1.0;
// For testing just play "walk" animation and loop it
animation["walk"].wrapMode = WrapMode.Loop;
animation.Play("walk");
}
// Every frame just set the normalized time
// based on how much lean we want to apply
function Update () {
var lean = Input.GetAxis("Horizontal");
// normalizedTime is 0 at the first frame and 1 at the last frame in the clip
leanLeft.normalizedTime = -lean;
leanRight.normalizedTime = lean;
}
Tip: When using Additive animations, it is critical that you also play some other non-additive animation on every transform that is also used in the additive animation, otherwise the animations will add on top of the last frame's result. This is most certainly not what you want.
Animating Characters Procedurally
Sometimes you want to animate the bones of your character procedurally. For example, you might want the head of your character to look at a specific point in 3D space which is best handled by a script that tracks the target point. Fortunately, Unity makes this very easy, since bones are just Transforms which drive the skinned mesh. Thus, you can control the bones of a character from a script just like the Transforms of a GameObject.
One important thing to know is that the animation system updates Transforms after the Update() function and before the LateUpdate() function. Thus if you want to do a LookAt() function you should do that in LateUpdate() to make sure that you are really overriding the animation.
Ragdolls are created in the same way. You simply have to attach Rigidbodies, Character Joints and Capsule Colliders to the different bones. This will then physically animate your skinned character.
Animation Playback and Sampling
This section explains how animations in Unity are sampled when they are played back by the engine.
AnimationClips are typically authored at a fixed frame rate. For example, you may create your animation in 3ds Max or Maya at a frame rate of 60 frames per second (fps). When importing the animation in Unity, this frame rate will be read by the importer, so the data of the imported animation is also sampled at 60 fps.
However, games typically run at a variable frame rate. The frame rate may be higher on some computers than on others, and it may also vary from one second to the next based on the complexity of the view the camera is looking at at any given moment. Basically this means that we can make no assumptions about the exact frame rate the game is running at. What this means is that even if an animation is authored at 60 fps, it may be played back at a different framerate, such as 56.72 fps, or 83.14 fps, or practically any other value.
As a result, Unity must sample an animation at variable framerates, and cannot guarantee the framerate for which it was originally designed. Fortunately, animations for 3D computer graphics do not consist of discrete frames, but rather of continuous curves. These curves can be sampled at any point in time, not just at those points in time that correspond to frames in the original animation. In fact, if the game runs at a higher frame rate than the animation was authored with, the animation will actually look smoother and more fluid in the game than it did in the animation software.
For most practical purposes, you can ignore the fact that Unity samples animations at variable framerates. However, if you have gameplay logic that relies on animations that animate transforms or properties into very specific configurations, then you need to be aware that the re-sampling takes place behind the scenes. For example, if you have an animation that rotates an object from 0 to 180 degrees over 30 frames, and you want to know from your code when it has reached half way there, you should not do it by having a conditional statement in your code that checks if the current rotation is 90 degrees. Because Unity samples the animation according to the variable frame rate of the game, it may sample it when the rotation is just below 90 degrees, and the next time right after it reached 90 degrees. If you need to be notified when a specific point in an animation is reached, you should use an AnimationEvent instead.
Note also that as a consequence of the variable framerate sampling, an animation that is played back using WrapMode.Once may not be sampled at the exact time of the last frame. In one frame of the game the animation may be sampled just before the end of the animation, and in the next frame the time can have exceeded the length of the animation, so it is disabled and not sampled further. If you absolutely need the last frame of the animation to be sampled exactly, you should use WrapMode.ClampForever which will keep sampling the last frame indefinitely until you stop the animation yourself.
Page last updated: 2011-11-17Navmesh and Pathfinding
A navigation mesh (also known as the Navmesh) is a simplified representation of world geometry, which gameplay agents use to navigate the world. Typically an agent has a goal, or a destination, to which it is trying to find a path, and then navigate to that goal along the path. This process is called pathfinding. Note that Navmesh generation (or baking) is done by game developers inside the editor, while the pathfinding is done by agents at runtime based on that Navmesh.
In the complex world of games, there can be many agents, dynamic obstacles, and constantly changing accessibility levels for different areas in the world. Agents need to react dynamically to those changes. An agent's pathfinding task can be interrupted by or affected by things like collision avoidance with other characters, changing characteristics of the terrain, physical obstacles (such as closing doors), and an update to the actual destination.
Here is a simple example of how to set up a navmesh, and an agent that will do pathfinding on it:
- Create some geometry in the level, for example a Plane or a Terrain.
- In the Inspector Window's right hand corner click on and make sure that this geometry is marked up as
- Pull up the Navigation Mesh window (->).
- Bake the mesh. This will generate the navmesh for all navigation-static geometry.
- Create some dynamic geometry in the scene (such as characters).
- Set up an agent (or multiple agents), by adding a NavMeshAgent component to a dynamic geometry in the scene.
- Give the agent a destination (by setting the destination property) in a script attached to the agent.
- Press play and watch the magic.
Note that it is also possible to define custom NavMesh layers. These are needed for situations where some parts of the environment are easier for agents to pass through than others. For parts of the mesh that are not directly connected, it is possible to create Off Mesh Links.
Automatic off-mesh links
Navmesh geometry can also be marked up for automatic off-mesh link generation, like this:

Marking up geometry for automatic off-mesh link generation
Geometry marked up in this way will be checked during the Navmesh Baking process for creating links to other Navmesh geometry. This way, we can control the auto-generation for each GameObject. Whether an off-mesh link will be auto-generated in the baking process is also determined by the Jump distance and the Drop height properties in the settings.
The NavMeshLayer assigned to auto-generated off-mesh links, is the built-in layer Jump. This allows for global control of the auto-generated off-mesh links costs (see Navmesh layers).
Note, that there is also a possibility for setting up manual off-mesh links (described here).
Page last updated: 2012-02-02Navmesh Baking
Once the Navmesh geometry and layers are marked up, it's time to bake the Navmesh geometry.
Inside the Navigation window (), go to the tab (the upper-right corner), and click on the button (the lower-right corner).

Navigation Bake Window
Here are the properties that affect Navmesh baking:
| Radius | radius of the "typical" agent (preferrably the smallest). |
| Height | height of the "typical" agent (the "clearance" needed to get a character through). |
| Max Slope | all surfaces with higher slope than this, will be discarded. |
| Step height | the height difference below which navmesh regions are considered connected. |
| Drop height | If the value of this property is positive, off-mesh links will be placed for adjacent navmesh surfaces where the height difference is below this value. |
| Jump distance | If the value of this property is positive, off-mesh links will be placed for adjacent navmesh surfaces where the horizontal distance is below this value. |
| Advanced | |
| Min region area | Regions with areas below this threshold will be discarded. |
| Width inaccuracy % | Allowable width inaccuracy |
| Height inaccuracy % | Allowable height inaccuracy |
| Height mesh | If this options is on, original height information is stored. This has performance implications for speed and memory usage. |
Note that the baked navmesh is part of the scene and agents will be able to traverse it. To remove the navmesh, click on when you're in the tab.
(back to Navigation and Pathfinding)
Page last updated: 2012-02-01Sound
Audio Listener
The Audio Listener acts as a microphone-like device. It receives input from any given Audio Source in the scene and plays sounds through the computer speakers. For most applications it makes the most sense to attach the listener to the Main Camera. If an audio listener is within the boundaries of a Reverb Zone reverberation is applied to all audible sounds in the scene. (PRO only) Furthermore, Audio Effects can be applied to the listener and it will be applied to all audible sounds in the scene.

The Audio Listener, attached to the Main Camera
Properties
The Audio Listener has no properties. It simply must be added to work. It is always added to the Main Camera by default.
Details
The Audio Listener works in conjunction with Audio Sources, allowing you to create the aural experience for your games. When the Audio Listener is attached to a GameObject in your scene, any Sources that are close enough to the Listener will be picked up and output to the computer's speakers. Each scene can only have 1 Audio Listener to work properly.
If the Sources are 3D (see import settings in Audio Clip), the Listener will emulate position, velocity and orientation of the sound in the 3D world (You can tweak attenuation and 3D/2D behavior in great detail in Audio Source) . 2D will ignore any 3D processing. For example, if your character walks off a street into a night club, the night club's music should probably be 2D, while the individual voices of characters in the club should be mono with their realistic positioning being handled by Unity.
You should attach the Audio Listener to either the Main Camera or to the GameObject that represents the player. Try both to find what suits your game best.
Hints
- Each scene can only have one Audio Listener.
- You access the project-wide audio settings using the Audio Manager, found in the menu.
- View the Audio Clip Component page for more information about Mono vs Stereo sounds.
Audio Source
The Audio Source plays back an Audio Clip in the scene. If the Audio Clip is a 3D clip, the source is played back at a given position and will attenuate over distance. The audio can be spread out between speakers (stereo to 7.1) (Spread) and morphed between 3D and 2D (PanLevel). This can be controlled over distance with falloff curves. Also, if the listener is within 1 or multiple Reverb Zones, reverberations is applied to the source. (PRO only) Individual filters can be applied to each audio source for an even richer audio experience. See Audio Effects for more details.

The Audio Source gizmo in the Scene View and its settings in the inspector.
Properties
| Audio Clip | Reference to the sound clip file that will be played. |
| Mute | If enabled the sound will be playing but muted. |
| Bypass Effects | This Is to quickly "by-pass" filter effects applied to the audio source. An easy way to turn all effects on/off. |
| Play On Awake | If enabled, the sound will start playing the moment the scene launches. If disabled, you need to start it using the Play() command from scripting. |
| Loop | Enable this to make the Audio Clip loop when it reaches the end. |
| Priority | Determines the priority of this audio source among all the ones that coexist in the scene. (Priority: 0 = most important. 256 = least important. Default = 128.). Use 0 for music tracks to avoid it getting occasionally swapped out. |
| Volume | How loud the sound is at a distance of 1 world unit (1 meter) from the Audio Listener. |
| Pitch | Amount of change in pitch due to slowdown/speed up of the Audio Clip. Value 1 is normal playback speed. |
| 3D Sound Settings | Settings that are applied to the audio source if the Audio Clip is a 3D Sound. |
| Pan Level | Sets how much the 3d engine has an effect on the audio source. |
| Spread | Sets the spread angle to 3d stereo or multichannel sound in speaker space. |
| Doppler Level | Determines how much doppler effect will be applied to this audio source (if is set to 0, then no effect is applied). |
| Min Distance | Within the MinDistance, the sound will stay at loudest possible. Outside MinDistance it will begin to attenuate. Increase the MinDistance of a sound to make it 'louder' in a 3d world, and decrease it to make it 'quieter' in a 3d world. |
| Max Distance | The distance where the sound stops attenuating at. Beyond this point it will stay at the volume it would be at MaxDistance units from the listener and will not attenuate any more. |
| Rolloff Mode | How fast the sound fades. The higher the value, the closer the Listener has to be before hearing the sound.(This is determined by a Graph). |
| Logarithmic Rolloff | The sound is loud when you are close to the audio source, but when you get away from the object it decreases significantly fast. |
| Linear Rolloff | The more far away from the audio source you go, the less you can hear it. |
| Custom Rolloff | The sound from the audio source behaves accordingly to how you set the graph of roll offs. |
| 2D Sound Settings | Settings that are applied to the audio source if the Audio clip is a 2D Sound. |
| Pan 2D | Sets how much the engine has an effect on the audio source. |
Types of Rolloff
There are three Rolloff modes: Logarithmic, Linear and Custom Rolloff. The Custom Rolloff can be modified by modifying the volume distance curve as described below. If you try to modify the volume distance function when it is set to Logarithmic or Linear, the type will automatically change to Custom Rolloff.

Rolloff Modes that an audio source can have.
Distance Functions
There are several properties of the audio that can be modified as a function of the distance between the audio source and the audio listener.
Volume: Amplitude(0.0 - 1.0) over distance.
Pan: Left(-1.0) to Right(1.0) over distance.
Spread: Angle (degrees 0.0 - 360.0) over distance.
Low-Pass (only if LowPassFilter is attached to the AudioSource): Cutoff Frequency (22000.0-10.0) over distance.

Distance functions for Volume, Pan, Spread and Low-Pass audio filter. The current distance to the Audio Listener is marked in the graph.
To modify the distance functions, you can edit the curves directly. For more information, see the guide to Editing Curves.
Creating Audio Sources
Audio Sources don't do anything without an assigned Audio Clip. The Clip is the actual sound file that will be played back. The Source is like a controller for starting and stopping playback of that clip, and modifying other audio properties.
To create a new Audio Source:
- Import your audio files into your Unity Project. These are now Audio Clips.
- Go to from the menubar.
- With the new GameObject selected, select .
- Assign the Audio Clip property of the Audio Source Component in the Inspector.
Note: If you want to create an audio source just for one Audio Clip that you have in the Assets folder, you can drag and drop that Audio Clip to the scene view and an Audio Source game object will be created automatically for it.
Platform specific details
iOS
On mobile platforms compressed audio is encoded as MP3 for speedier decompression. Beware that this compression can remove samples at the end of the clip and potentially break a "perfect-looping" clip. Make sure the clip is right on a specific MP3 sample boundary to avoid sample clipping (Tools to perform this is widely available). For performance reasons audio clips can be played back using the Apple hardware codec. To enable this check the "Use Hardware" checkbox in the import settings. See the Audio Clip documentation for more details.
Android
On mobile platforms compressed audio is encoded as MP3 for speedier decompression. Beware that this compression can remove samples at the end of the clip and potentially break a "perfect-looping" clip. Make sure the clip is right on a specific MP3 sample boundary to avoid sample clipping (Tools to perform this is widely available).
Audio Clip
Audio Clips contain the audio data used by Audio Sources. Unity supports mono, stereo and multichannel audio assets (up to eight channels). The audio file formats that Unity can import are .aif, .wav, .mp3, and .ogg. Unity can also import tracker modules in the .xm, .mod, .it, and .s3m formats. The tracker module assets behave the same way as any other audio assets in Unity although no waveform preview is available in the asset import inspector.

The Audio Clip Inspector
Properties
| Audio Format | The specific format that will be used for the sound at runtime. |
| Native | This option offers higher quality at the expense of larger file size and is best for very short sound effects. |
| Compressed | The compression results in smaller files but with somewhat lower quality compared to native audio. This format is best for medium length sound effects and music. |
| 3D Sound | If enabled, the sound will play back in 3D space. Both Mono and Stereo sounds can be played in 3D. |
| Force to mono | If enabled, the audio clip will be down-mixed to a single channel sound. |
| Load Type | The method Unity uses to load audio assets at runtime. |
| Decompress on load | Audio files will be decompressed as soon as they are loaded. Use this option for smaller compressed sounds to avoid the performance overhead of decompressing on the fly. Be aware that decompressing sounds on load will use about ten times more memory than keeping them compressed, so don't use this option for large files. |
| Compressed in memory | Keep sounds compressed in memory and decompress while playing. This option has a slight performance overhead (especially for Ogg/Vorbis compressed files) so only use it for bigger files where decompression on load would use a prohibitive amount of memory. |
| Stream from disc | Stream audio data directly from disc. The memory used by this option is typically a small fraction of the file size, so it is very useful for music or other very long tracks. For performance reasons, it is usually advisable to stream only one or two files from disc at a time but the of streams that can comfortably be handled depends on the hardware. |
| Compression | Amount of Compression to be applied to a Compressed clip. Statistics about the file size can be seen under the slider. A good approach to tuning this value is to drag the slider to a place that leaves the playback "good enough" while keeping the file small enough for your distribution requirements. |
| Hardware Decoding | (iOS only) On iOS devices, Apple's hardware decoder can be used resulting in lower CPU overhead during decompression. Check out platform specific details for more info. |
| Gapless looping | (Android/iOS only) Use this when compressing a seamless looping audio source file (in a non-compressed PCM format) to ensure perfect continuity is preserved at the seam. Standard MPEG encoders introduce a short silence at the loop point, which will be audible as a brief "click" or "pop". |
Importing Audio Assets
Unity supports both Compressed and Native Audio. Any type of file (except MP3/Ogg Vorbis) will be initially imported as Native. Compressed audio files must be decompressed by the CPU while the game is running, but have smaller file size. If Stream is checked the audio is decompressed on the fly, otherwise it is decompressed completely as soon as it loads. Native PCM formats (WAV, AIFF) have the benefit of giving higher fidelity without increasing the CPU overhead, but files in these formats are typically much larger than compressed files. Module files (.mod,.it,.s3m..xm) can deliver very high quality with an extremely low footprint.
As a general rule of thumb, Compressed audio (or modules) are best for long files like background music or dialog, while Native is better for short sound effects. You should tweak the amount of Compression using the compression slider. Start with high compression and gradually reduce the setting to the point where the loss of sound quality is perceptible. Then, increase it again slightly until the perceived loss of quality disappears.
Using 3D Audio
If an audio clip is marked as a 3D Sound then it will be played back so as to simulate its position in the game world's 3D space. 3D sounds emulate the distance and location of sounds by attenuating volume and panning across speakers. Both mono and multiple channel sounds can be positioned in 3D. For multiple channel audio, use the spread option on the Audio Source to spread and split out the discrete channels in speaker space. Unity offers a variety of options to control and fine-tune the audio behavior in 3D space - see the Audio Source component reference for further details.
Platform specific details
iOS
On mobile platforms compressed audio is encoded as MP3 to take advantage of hardware decompression.
To improve performance, audio clips can be played back using the Apple hardware codec. To enable this option, check the "Hardware Decoding" checkbox in the Audio Importer. Note that only one hardware audio stream can be decompressed at a time, including the background iPod audio.
If the hardware decoder is not available, the decompression will fall back on the software decoder (on iPhone 3GS or later, Apple's software decoder is used in preference to Unity's own decoder (FMOD)).
Android
On mobile platforms compressed audio is encoded as MP3 to take advantage of hardware decompression.
Game Interface Elements
Unity gives you a number of options for creating your game's graphic user interface (GUI). You can use GUI Text and GUI Texture objects in the scene, or generate the interface from scripts using UnityGUI.
The rest of this page contains a detailed guide for getting up and running with UnityGUI.
GUI Scripting Guide
Overview
UnityGUI allows you to create a wide variety of highly functional GUIs very quickly and easily. Rather than creating a GUI object, manually positioning it, and then writing a script that handles its functionality, you can do everything at once with just a few lines of code. The code produces GUI controls that are instantiated, positioned and handled with a single function call.
For example, the following code will create and handle a button with no additional work in the editor or elsewhere:-
// JavaScript
function OnGUI () {
if (GUI.Button (Rect (10,10,150,100), "I am a button")) {
print ("You clicked the button!");
}
}
// C#
using UnityEngine;
using System.Collections;
public class GUITest : MonoBehaviour {
void OnGUI () {
if (GUI.Button (new Rect (10,10,150,100), "I am a button")) {
print ("You clicked the button!");
}
}
}

This is the button created by the code above
Although this example is very simple, there are very powerful and complex techniques available for use in UnityGUI. GUI construction is a broad subject but the following sections should help you get up to speed as quickly as possible. This guide can be read straight through or used as reference material.
UnityGUI Basics
This section covers the fundamental concepts of UnityGUI, giving you an overview as well as a set of working examples you can paste into your own code. UnityGUI is very friendly to play with, so this is a good place to get started.
Controls
This section lists every available Control in UnityGUI, along with code samples and images showing the results.
Customization
It is important to be able to change the appearance of the GUI to match the look of your game. All controls in UnityGUI can be customized with GUIStyles and GUISkins, as explained in this section.
Layout Modes
UnityGUI offers two ways to arrange your GUIs: you can manually place each control on the screen, or you can use an automatic layout system which works in a similar way to HTML tables. Either system can be used as desired and the two can be freely mixed. This section explains the functional differences between the two systems, including examples.
Extending UnityGUI
UnityGUI is very easy to extend with new Control types. This chapter shows you how to make simple compound controls - complete with integration into Unity's event system.
Extending Unity Editor
The GUI of the Unity editor is actually written using UnityGUI. Consequently, the editor is highly extensible using the same type of code you would use for in-game GUI. In addition, there are a number of Editor-specific GUI controls to help you create custom editor GUI.
Page last updated: 2011-11-17Networked Multiplayer
Realtime networking is a complex field but Unity makes it easy to add networking features to your game. Nevertheless, it is useful to have some idea of the scope of networking before using it in a game. This section explains the fundamentals of networking along with the specifics of Unity's implementation. If you have never created a network game before then it is strongly recommended that you work through this guide before getting started.
High Level Overview
This section outlines all the concepts involved in networking and serves as an introduction to deeper topics.
Networking Elements in Unity
This section of the guide covers Unity's implementation of the concepts explained in the overview.
RPC Details
Remote Procedure Call or RPC is a way of calling a function on a remote machine. This may be a client calling a function on the server, or the server calling a function on some or all clients. This section explains RPC concepts in detail.
State Synchronization
State Synchronization is a method of regularly updating a specific set of data across two or more game instances running on the network.
Minimizing Bandwidth
Every choice you make about where and how to share data will affect the network bandwidth your game uses. This page explains how bandwidth is used and how to keep usage to a minimum.
Network View
Network Views are Components you use to share data across the network and are a fundamental aspect of Unity networking. This page explains them in detail.
Network Instantiate
A complex subject in networking is ownership of an object and determination of who controls what. Network Instantiation handles this task for you, as explained in this section. Also covered are some more sophisticated alternatives for situations where you need more control over object ownership.
Master Server
The Master Server is like a game lobby where servers can advertise their presence to clients. It can also enable communication from behind a firewall or home network using a technique called NAT punchthrough (with help from a facilitator) to make sure your players can always connect with each other. This page explains how to use the Master Server.
Page last updated: 2011-11-17iphone-GettingStarted
Building games for devices like the iPhone and iPad requires a different approach than you would use for desktop PC games. Unlike the PC market, your target hardware is standardized and not as fast or powerful as a computer with a dedicated video card. Because of this, you will have to approach the development of your games for these platforms a little differently. Also, the features available in Unity for iOS differ slightly from those for desktop PCs.
Setting Up Your Apple Developer Account
Before you can run Unity iOS games on the actual device, you will need to have your Apple Developer account approved and set up. This includes establishing your team, adding your devices, and finalizing your provisioning profiles. All this setup is performed through Apple's developer website. Since this is a complex process, we have provided a basic outline of the tasks that must be completed before you can run code on your iOS devices. However, the best thing to do is follow the step-by-step instructions at Apple's iPhone Developer portal.
Note: We recommend that you set up your Apple Developer account before proceeding because you will need it to use Unity to its full potential with iOS.
Accessing iOS Functionality
Unity provides a number of scripting APIs to access the multi-touch screen, accelerometer, device geographical location system and much more. You can find out more about the script classes on the iOS scripting page.
Exposing Native C, C++ or Objective-C Code to Scripts
Unity allows you to call custom native functions written in C, C++ or Objective-C directly from C# scripts. To find out how to bind native functions, visit the plugins page.
Prepare Your Application for In-App Purchases
The Unity iOS runtime allows you to download new content and you can use this feature to implement in-app purchases. See the downloadable content manual page for further information.
Occlusion Culling
Unity supports occlusion culling which is useful for squeezing high performance out of complex scenes with many objects. See the occlusion culling manual page for further information.
Splash Screen Customization
See the splash screen customization page to find out how to change the image your game shows while launching.
Troubleshooting and Reporting Crashes.
If you are experiencing crashes on the iOS device, please consult the iOS troubleshooting page for a list of common issues and solutions. If you can't find a solution here then please file a bug report for the crash (menu: in the Unity editor).
How Unity's iOS and Desktop Targets Differ
Statically Typed JavaScript
Dynamic typing in JavaScript is always turned off in Unity when targetting iOS (this is equivalent to #pragma strict getting added to all your scripts automatically). Static typing greatly improves performance, which is especially important on iOS devices. When you switch an existing Unity project to the iOS target, you will get compiler errors if you are using dynamic typing. You can easily fix these either by using explicitly declared types for the variables that are causing errors or taking advantage of type inference.
MP3 Instead of Ogg Vorbis Audio Compression
For performance reasons, MP3 compression is favored on iOS devices. If your project contains audio files with Ogg Vorbis compression, they will be re-compressed to MP3 during the build. Consult the audio clip documentation for more information on using compressed audio on the iPhone.
PVRTC Instead of DXT Texture Compression
Unity iOS does not support DXT textures. Instead, PVRTC texture compression is natively supported by iPhone/iPad devices. Consult the texture import settings documentation to learn more about iOS texture formats.
Movie Playback
MovieTextures are not supported on iOS. Instead, full-screen streaming playback is provided via scripting functions. To learn about the supported file formats and scripting API, consult the movie page in the manual.
Further Reading
- Unity iOS Basics
- Unity Remote
- iOS Scripting
- iOS Hardware Guide
- Optimizing Performance in iOS.
- Account Setup
- Features currently not supported by Unity iOS
- Building Plugins for iOS
- Preparing your application for "In App Purchases"
- Customizing the Splash screen of Your Mobile Application
- Trouble Shooting
- Reporting crash bugs on iOS
iphone-basic
This section covers the most common and important questions that come up when starting to work with iOS.
Prerequisites
I've just received iPhone Developer approval from Apple, but I've never developed for iOS before. What do I do first?
A: Download the SDK, get up and running on the Apple developer site, and set up your team, devices, and provisioning. We've provided a basic list of steps to get you started.
Can Unity-built games run in the iPhone Simulator?
A: No, but Unity iOS can build to iPad Simulator if you're using the latest SDK. However the simulator itself is not very useful for Unity because it does not simulate all inputs from iOS or properly emulate the performance you get on the iPhone/iPad. You should test out gameplay directly inside Unity using the iPhone/iPad as a remote control while it is running the Unity Remote application. Then, when you are ready to test performance and optimize the game, you publish to iOS devices.
Unity Features
How do I work with the touch screen and accelerometer?
A: In the scripting reference inside your Unity iOS installation, you will find classes that provide the hooks into the device's functionality that you will need to build your apps. Consult the Input System page for more information.
My existing particle systems seem to run very slowly on iOS. What should I do?
A: iOS has relatively low fillrate. If your particles cover a rather large portion of the screen with multiple layers, it will kill iOS performance even with the simplest shader. We suggest baking your particle effects into a series of textures off-line. Then, at run-time, you can use 1-2 particles to display them via animated textures. You can get fairly decent looking effects with a minimum amount of overdraw this way.
Can I make a game that uses heavy physics?
A: Physics can be expensive on iOS is it requires a lot of floating point number crunching. You should completely avoid MeshColliders if at all possible, but they can be used if they are really necessary. To improve performance, use a low fixed framerate using . A framerate of 10-30 is recommended. Enable rigidbody interpolation to achieve smooth motion while using low physics frame rates. In order to achieve completely fluid framerate without oscillations, it is best to pick fixed deltaTime value based on the average framerate your game is getting on iOS. Either 1:1 or half the frame rate is recommended. For example, if you get 30 fps, you should use 15 or 30 fps for fixed frame rate (0.033 or 0.066)
Can I access the gallery, music library or the native iPod player in Unity iOS?
A: Yes - if you implement it. Unity iPhone supports the native plugin system, where you can add any feature you need -- including access to Gallery, Music library, iPod Player and any other feature that the iOS SDK exposes. Unity iOS does not provide an API for accessing the listed features through Unity scripts.
UnityGUI Considerations
What kind of performance impact will UnityGUI make on my games?
A: UnityGUI is fairly expensive when many controls are used. It is ideal to limit your use of UnityGUI to game menus or very minimal GUI Controls while your game is running. It is important to note that every object with a script containing an OnGUI() call will require additional processor time -- even if it is an empty OnGUI() block. It is best to disable any scripts that have an OnGUI() call if the GUI Controls are not being used. You can do this by marking the script as enabled = false.
Any other tips for using UnityGUI?
A: Try using GUILayout as little as possible. If you are not using GUILayout at all from one OnGUI() call, you can disable all GUILayout rendering using MonoBehaviour.useGUILayout = false; This doubles GUI rendering performance. Finally, use as few GUI elements while rendering 3D scenes as possible.
unity-remote
Unity Remote is an application that allows you to use your iOS device as a remote control for your project in Unity. This is useful during development since it is much quicker to test your project in the editor with remote control than to build and deploy it to the device after each change.
Where can I find Unity Remote?
Unity remote is available for download from the AppStore at no charge. If you prefer to build and deploy the application yourself, you can download the source here at the Unity website.
How do I build Unity Remote?
First, download the project source code here and unzip it to your preferred location. The zip file contains an XCode project to build Unity Remote and install it on your device.
Assuming you have already created the provisioning profile and successfully installed iOS builds on your device, you just need to open the Xcode project file UnityRemote.xcodeproj. Once XCode is launched, you should click "Build and Go" to install the app on your iOS device. If you have never built and run applications before, we recommend that you try building some of the Apple examples first to familiarize yourself with XCode and iOS.
Once Unity Remote is installed, make sure your device is connected via Wi-Fi to the same network as your development machine. Launch Unity Remote on your iPhone/iPad while Unity is running on your computer and select your computer from the list that appears. Now, whenever you enter Play mode in the Editor, your device will act as a remote control that you can use for developing and testing your game. You can control the application with the device wirelessly and you will also see a low-res version of the app on the device's screen.
Note: The Unity iOS editor cannot emulate the device's hardware perfectly, so you may not get the exact behavior (graphics performance, touch responsiveness, sounds playback, etc) that you would on a real device.
Xcode shows strange errors while deploying Unity Remote to my device. What should I do?
This indicates that the default Identifier in the Unity Remote project is not compatbile with your provisioning profile. You will have to alter this Identifier manually in your XCode project. The Identifier must match your provisioning profile.
You will need to create an AppID with an trailing asterisk if you have not already done so; you can do this in the Program Portal on Apple's iPhone Developer Program. First, go to the Program Portal and choose the AppIDs tab. Then, click the Add ID button in the top right corner and type your usual bundle identifier followed by dot and asterisk (eg, com.mycompany.*) in the App ID Bundle Seed ID and Bundle Identifier field. Add the new AppID to your provisioning profile, then download and reinstall it. Don't forget to restart Xcode afterwards. If you have any problems creating the AppID, consult the Provisioning How-to section on Apple's website.

Don't forget to change the Identifier before you install Unity Remote on your device.
Open the Unity Remote project with XCode. From the menu, select . This will open a new window entitled Target "Unity Remote" Info. Select the Properties tab. Change the Identifier property field from com.unity3d.UnityRemote to the bundle identifier in your AppID followed by "." (dot) followed by "UnityRemote". For example, if your provisioning profile contains ######.com.mycompany.* AppID, then change the Identifier field to com.mycompany.UnityRemote.
Next, select from the menu, and compile and install Unity Remote again. You may also need to change the active SDK from Simulator to Device - 2.0 | Release. There is no problem using SDK 2.0 even if your device runs a newer version of the OS.
I'm getting really poor graphics quality when running my game in Unity Remote. What can I do to improve it?
When you use Unity Remote, the game actually runs on your Mac while its visual content is heavily compressed and streamed to the device. As a result, what you see on the device screen is just a low-res version of what the app would really look like. You should check how the game runs on the device occasionally by building and deploying the app (select in the Unity editor).
Unity Remote is laggy. Can I improve it?
The performance of Unity Remote depends heavily on the speed of the Wi-Fi network, the quality of the networking hardware and other factors. For the best experience, create an ad-hoc network between your Mac and iOS device. Click the Airport icon on your Mac and choose "Create Network". Then, enter a name and password and click OK. On the device, choose Settings->Wi-Fi and select the new Wi-Fi network you have just created. Remember that an ad-hoc network is really a wireless connection that does not involve a wireless access point. Therefore, you will usually not have internet access while using ad-hoc networking.
Turning Bluetooth off on both on your iPhone/iPad and on Mac should also improve connection quality.
If you do not need to see the game view on the device, you can turn image synchronization off in the Remote machine list. This will reduce the network traffic needed for the Remote to work.
The connection to Unity Remote is easily lost
This can be due to a problem with the installation or other factors that prevent Unity Remote from functioning properly. Try the following steps in sequence, checking if the performance improves at each step before moving on to the next:-
- First of all, check if Bluetooth is switched on. Both your Mac and iOS device should have Bluetooth disabled for best performance.
- Delete the settings file located at ~/Library/Preferences/com.unity3d.UnityEditoriPhone.plist
- Reinstall the game on your iPhone/iPad.
- Reinstall Unity on your Mac.
- As a last resort, performing a hard reset on the iOS device can sometimes improve the performance of Unity Remote.
If you still experience problems then try installing Unity Remote on another device (in another location if possible) and see if it gives you better results. There could be problems with RF interference or other software influencing the performance of the wireless adapter on your Mac or iOS device.
Unity Remote doesn't see my Mac. What should I do?
- Check if Unity Remote and your Mac are connected to the same wireless network.
- Check your firewall settings, router security settings, and any other hardware/software that may filter packets on your network.
- Leave Unity Remote running, switch off your Mac's Airport for a minute or two, and switch on again.
- Restart both Unity and Unity Remote. Sometimes you also need to cold-restart your iPhone/iPad (hold down the menu and power buttons simultaneously).
- Unity Remote uses the Apple Bonjour service, so check that your Mac has it switched on.
- Reinstall Unity Remote from the latest Unity iOS package.
iphone-API
Unity iOS provides a number of new scripting APIs to access unique device functionality. For cross-platform projects, UNITY_IPHONE is defined for conditionally compiling iOS-specific C# code. The following new scripting classes were introduced:
| iPhoneInput | Access to multi-touch screen, accelerometer, device orientation and geographical location. |
| iPhoneSettings | iOS specific settings, such as screen orientation, dimming and information about device hardware. |
| iPhoneKeyboard | Support for native on-screen keyboard. |
| iPhoneUtils | Useful functions for movie playback, anti-piracy protection and vibration. |
Further Reading
Page last updated: 2010-09-08iphone-Input
Desktop
Note: Keyboard, joystick and gamepad input works only on the desktop version of Unity.
Unity supports keyboard, joystick and gamepad input.
Virtual axes and buttons can be created in the Input Manager, and end users can configure Keyboard input in a nice screen configuration dialog.

You can setup joysticks, gamepads, keyboard, and mouse, then access them all through one simple scripting interface.
From scripts, all virtual axes are accessed by their name.
Every project has the following default input axes when it's created:
- Horizontal and Vertical are mapped to w, a, s, d and the arrow keys.
- Fire1, Fire2, Fire3 are mapped to Control, Option (Alt), and Command, respectively.
- Mouse X and Mouse Y are mapped to the delta of mouse movement.
- Window Shake X and Window Shake Y is mapped to the movement of the window.
Adding new Input Axes
If you want to add new virtual axes go to the menu. Here you can also change the settings of each axis.

You map each axis to two buttons on a joystick, mouse, or keyboard keys.
| Name | The name of the string used to check this axis from a script. |
| Descriptive Name | Positive value name displayed in the input tab of the configuration dialog for standalone builds. |
| Descriptive Negative Name | Negative value name displayed in the Input tab of the Configuration dialog for standalone builds. |
| Negative Button | The button used to push the axis in the negative direction. |
| Positive Button | The button used to push the axis in the positive direction. |
| Alt Negative Button | Alternative button used to push the axis in the negative direction. |
| Alt Positive Button | Alternative button used to push the axis in the positive direction. |
| Gravity | Speed in units per second that the axis falls toward neutral when no buttons are pressed. |
| Dead | Size of the analog dead zone. All analog device values within this range result map to neutral. |
| Sensitivity | Speed in units per second that the the axis will move toward the target value. This is for digital devices only. |
| Snap | If enabled, the axis value will reset to zero when pressing a button of the opposite direction. |
| Invert | If enabled, the Negative Buttons provide a positive value, and vice-versa. |
| Type | The type of inputs that will control this axis. |
| Axis | The axis of a connected device that will control this axis. |
| Joy Num | The connected Joystick that will control this axis. |
Use these settings to fine tune the look and feel of input. They are all documented with tooltips in the Editor as well.
Using Input Axes from Scripts
You can query the current state from a script like this:
value = Input.GetAxis ("Horizontal");
An axis has a value between -1 and 1. The neutral position is 0. This is the case for joystick input and keyboard input.
However, Mouse Delta and Window Shake Delta are how much the mouse or window moved during the last frame. This means it can be larger than 1 or smaller than -1 when the user moves the mouse quickly.
It is possible to create multiple axes with the same name. When getting the input axis, the axis with the largest absolute value will be returned. This makes it possible to assign more than one input device to one axis name. For example, create one axis for keyboard input and one axis for joystick input with the same name. If the user is using the joystick, input will come from the joystick, otherwise input will come from the keyboard. This way you don't have to consider where the input comes from when writing scripts.
Button Names
To map a key to an axis, you have to enter the key's name in the Positive Button or Negative Button property in the Inspector.
The names of keys follow this convention:
- Normal keys: "a", "b", "c" ...
- Number keys: "1", "2", "3", ...
- Arrow keys: "up", "down", "left", "right"
- Keypad keys: "[1]", "[2]", "[3]", "[+]", "[equals]"
- Modifier keys: "right shift", "left shift", "right ctrl", "left ctrl", "right alt", "left alt", "right cmd", "left cmd"
- Mouse Buttons: "mouse 0", "mouse 1", "mouse 2", ...
- Joystick Buttons (from any joystick): "joystick button 0", "joystick button 1", "joystick button 2", ...
- Joystick Buttons (from a specific joystick): "joystick 1 button 0", "joystick 1 button 1", "joystick 2 button 0", ...
- Special keys: "backspace", "tab", "return", "escape", "space", "delete", "enter", "insert", "home", "end", "page up", "page down"
- Function keys: "f1", "f2", "f3", ...
The names used to identify the keys are the same in the scripting interface and the Inspector.
value = Input.GetKey ("a");
Mobile Input
Unity iOS/Android offers you access to the iPhone, iPad and Android input systems via Input and iOS Input scripting interfaces.
Input provides access to the multi-touch screen, accelerometer and device orientation. iOS Input provides access to geographical location.
Access to keyboard on mobile devices is provided via the iOS keyboard.
Multi-Touch Screen
The iPhone and iPod Touch devices are capable of tracking up to five fingers touching the screen simultaneously. You can retrieve the status of each finger touching the screen during the last frame by accessing the Input.touches property array.
Android devices don't have a unified limit on how many fingers they track. Instead, it varies from device to device and can be anything from two-touch on older devices to five fingers on some newer devices.
Each finger touch is represented by an Input.Touch data structure:
| fingerId | The unique index for a touch. |
| position | The screen position of the touch. |
| deltaPosition | The screen position change since the last frame. |
| deltaTime | Amount of time that has passed since the last state change. |
| tapCount | The iPhone/iPad screen is able to distinguish quick finger taps by the user. This counter will let you know how many times the user has tapped the screen without moving a finger to the sides. Android devices do not count number of taps, this field is always 1. |
| phase | Describes so called "phase" or the state of the touch. It can help you determine if the touch just began, if user moved the finger or if he just lifted the finger. |
Phase can be one of the following:
| Began | A finger just touched the screen. |
| Moved | A finger moved on the screen. |
| Stationary | A finger is touching the screen but hasn't moved since the last frame. |
| Ended | A finger was lifted from the screen. This is the final phase of a touch. |
| Canceled | The system cancelled tracking for the touch, as when (for example) the user puts the device to her face or more than five touches happened simultaneously. This is the final phase of a touch. |
Following is an example script which will shoot a ray whenever the user taps on the screen:
var particle : GameObject;
function Update () {
for (var touch : Touch in Input.touches) {
if (touch.phase == TouchPhase.Began) {
// Construct a ray from the current touch coordinates
var ray = Camera.main.ScreenPointToRay (touch.position);
if (Physics.Raycast (ray)) {
// Create a particle if hit
Instantiate (particle, transform.position, transform.rotation);
}
}
}
}
Mouse Simulation
On top of native touch support Unity iOS/Android provides a mouse simulation. You can use mouse functionality from the standard Input class.
Device Orientation
Unity iOS/Android allows you to get discrete description of the device physical orientation in three-dimensional space. Detecting a change in orientation can be useful if you want to create game behaviors depending on how the user is holding the device.
You can retrieve device orientation by accessing the Input.deviceOrientation property. Orientation can be one of the following:
| Unknown | The orientation of the device cannot be determined. For example when device is rotate diagonally. |
| Portrait | The device is in portrait mode, with the device held upright and the home button at the bottom. |
| PortraitUpsideDown | The device is in portrait mode but upside down, with the device held upright and the home button at the top. |
| LandscapeLeft | The device is in landscape mode, with the device held upright and the home button on the right side. |
| LandscapeRight | The device is in landscape mode, with the device held upright and the home button on the left side. |
| FaceUp | The device is held parallel to the ground with the screen facing upwards. |
| FaceDown | The device is held parallel to the ground with the screen facing downwards. |
Accelerometer
As the mobile device moves, a built-in accelerometer reports linear acceleration changes along the three primary axes in three-dimensional space. Acceleration along each axis is reported directly by the hardware as G-force values. A value of 1.0 represents a load of about +1g along a given axis while a value of -1.0 represents -1g. If you hold the device upright (with the home button at the bottom) in front of you, the X axis is positive along the right, the Y axis is positive directly up, and the Z axis is positive pointing toward you.
You can retrieve the accelerometer value by accessing the Input.acceleration property.
The following is an example script which will move an object using the accelerometer:
var speed = 10.0;
function Update () {
var dir : Vector3 = Vector3.zero;
// we assume that the device is held parallel to the ground
// and the Home button is in the right hand
// remap the device acceleration axis to game coordinates:
// 1) XY plane of the device is mapped onto XZ plane
// 2) rotated 90 degrees around Y axis
dir.x = -Input.acceleration.y;
dir.z = Input.acceleration.x;
// clamp acceleration vector to the unit sphere
if (dir.sqrMagnitude > 1)
dir.Normalize();
// Make it move 10 meters per second instead of 10 meters per frame...
dir *= Time.deltaTime;
// Move object
transform.Translate (dir * speed);
}
Low-Pass Filter
Accelerometer readings can be jerky and noisy. Applying low-pass filtering on the signal allows you to smooth it and get rid of high frequency noise.
The following script shows you how to apply low-pass filtering to accelerometer readings:
var AccelerometerUpdateInterval : float = 1.0 / 60.0;
var LowPassKernelWidthInSeconds : float = 1.0;
private var LowPassFilterFactor : float = AccelerometerUpdateInterval / LowPassKernelWidthInSeconds; // tweakable
private var lowPassValue : Vector3 = Vector3.zero;
function Start () {
lowPassValue = Input.acceleration;
}
function LowPassFilterAccelerometer() : Vector3 {
lowPassValue = Mathf.Lerp(lowPassValue, Input.acceleration, LowPassFilterFactor);
return lowPassValue;
}
The greater the value of LowPassKernelWidthInSeconds, the slower the filtered value will converge towards the current input sample (and vice versa). You should be able to use the LowPassFilter() function instead of avgSamples().
I'd like as much precision as possible when reading the accelerometer. What should I do?
Reading the Input.acceleration variable does not equal sampling the hardware. Put simply, Unity samples the hardware at a frequency of 60Hz and stores the result into the variable. In reality, things are a little bit more complicated -- accelerometer sampling doesn't occur at consistent time intervals, if under significant CPU loads. As a result, the system might report 2 samples during one frame, then 1 sample during the next frame.
You can access all measurements executed by accelerometer during the frame. The following code will illustrate a simple average of all the accelerometer events that were collected within the last frame:
var period : float = 0.0;
var acc : Vector3 = Vector3.zero;
for (var evnt : iPhoneAccelerationEvent in iPhoneInput.accelerationEvents) {
acc += evnt.acceleration * evnt.deltaTime;
period += evnt.deltaTime;
}
if (period > 0)
acc *= 1.0/period;
return acc;
Further Reading
The Unity mobile input API is originally based on Apple's API. It may help to learn more about the native API to better understand Unity's Input API. You can find the Apple input API documentation here:
- Programming Guide: Event Handling (Apple iPhone SDK documentation)
- UITouch Class Reference (Apple iOS SDK documentation)
Note: The above links reference your locally installed iPhone SDK Reference Documentation and will contain native ObjectiveC code. It is not necessary to understand these documents for using Unity on mobile devices, but may be helpful to some!
iOS
Device geographical location
Device geographical location can be obtained via the iPhoneInput.lastLocation property. Before calling this property you should start location service updates using iPhoneSettings.StartLocationServiceUpdates() and check the service status via iPhoneSettings.locationServiceStatus. See the scripting reference for details.
iOS-Keyboard
In most cases, Unity will handle keyboard input automatically for GUI elements but it is also easy to show the keyboard on demand from a script.
iOS
Using the Keyboard
GUI Elements
The keyboard will appear automatically when a user taps on editable GUI elements. Currently, GUI.TextField, GUI.TextArea and GUI.PasswordField will display the keyboard; see the GUI class documentation for further details.
Manual Keyboard Handling
Use the iPhoneKeyboard.Open function to open the keyboard. Please see the iPhoneKeyboard scripting reference for the parameters that this function takes.
Keyboard Type Summary
The Keyboard supports the following types:
| iPhoneKeyboardType.Default | Letters. Can be switched to keyboard with numbers and punctuation. |
| iPhoneKeyboardType.ASCIICapable | Letters. Can be switched to keyboard with numbers and punctuation. |
| iPhoneKeyboardType.NumbersAndPunctuation | Numbers and punctuation. Can be switched to keyboard with letters. |
| iPhoneKeyboardType.URL | Letters with slash and .com buttons. Can be switched to keyboard with numbers and punctuation. |
| iPhoneKeyboardType.NumberPad | Only numbers from 0 to 9. |
| iPhoneKeyboardType.PhonePad | Keyboard used to enter phone numbers. |
| iPhoneKeyboardType.NamePhonePad | Letters. Can be switched to phone keyboard. |
| iPhoneKeyboardType.EmailAddress | Letters with @ sign. Can be switched to keyboard with numbers and punctuation. |
Text Preview
By default, an edit box will be created and placed on top of the keyboard after it appears. This works as preview of the text that user is typing, so the text is always visible for the user. However, you can disable text preview by setting iPhoneKeyboard.hideInput to true. Note that this works only for certain keyboard types and input modes. For example, it will not work for phone keypads and multi-line text input. In such cases, the edit box will always appear. iPhoneKeyboard.hideInput is a global variable and will affect all keyboards.
Keyboard Orientation
By default, the keyboard automatically follows the device orientation. To disable or enable rotation to a certain orientation, use the following properties available in iPhoneKeyboard:
| autorotateToPortrait | Enable or disable autorotation to portrait orientation (button at the bottom). |
| autorotateToPortraitUpsideDown | Enable or disable autorotation to portrait orientation (button at top). |
| autorotateToLandscapeLeft | Enable or disable autorotation to landscape left orientation (button on the right). |
| autorotateToLandscapeRight | Enable or disable autorotation to landscape right orientation (button on the left). |
Visibility and Keyboard Size
There are three keyboard properties in iPhoneKeyboard that determine keyboard visibility status and size on the screen.
| visible | Returns true if the keyboard is fully visible on the screen and can be used to enter characters. |
| area | Returns the position and dimensions of the keyboard. |
| active | Returns true if the keyboard is activated. This property is not static property. You must have a keyboard instance to use this property. |
Note that iPhoneKeyboard.area will return a rect with position and size set to 0 until the keyboard is fully visible on the screen. You should not query this value immediately after iPhoneKeyboard.Open. The sequence of keyboard events is as follows:
- iPhoneKeyboard.Open is called. iPhoneKeyboard.active returns true. iPhoneKeyboard.visible returns false. iPhoneKeyboard.area returns (0, 0, 0, 0).
- Keyboard slides out into the screen. All properties remain the same.
- Keyboard stops sliding. iPhoneKeyboard.active returns true. iPhoneKeyboard.visible returns true. iPhoneKeyboard.area returns real position and size of the keyboard.
Secure Text Input
It is possible to configure the keyboard to hide symbols when typing. This is useful when users are required to enter sensitive information (such as passwords). To manually open keyboard with secure text input enabled, use the following code:
iPhoneKeyboard.Open("", iPhoneKeyboardType.Default, false, false, true);

Hiding text while typing
Alert keyboard
To display the keyboard with a black semi-transparent background instead of the classic opaque, call iPhoneKeyboard.Open as follows:
iPhoneKeyboard.Open("", iPhoneKeyboardType.Default, false, false, true, true);

Classic keyboard

Alert keyboard
Android
Unity Android reuses the iOS API to display system keyboard. Even though Unity Android supports most of the functionality of its iPhone counterpart, there are two aspects which are not supported:
- iPhoneKeyboard.hideInput
- iPhoneKeyboard.area
Please also note that the layout of a iPhoneKeyboardType can differ somewhat between devices.
iOS-Advanced
iOS
Advanced iOS scripting
Determining Device Generation
Different device generations support different functionality and widely varying performance. You should query the device for its generation and decide which functionality should be disabled to compensate for slower devices.
You can retrieve device generation by accessing the iPhoneSettings.generation property. Generation can be one of the following:
- iPhone
- iPhone3G
- iPhone3GS
- iPhone4
- iPodTouch1Gen
- iPodTouch2Gen
- iPodTouch3Gen
- iPodTouch4Gen
- iPad1Gen
You can find more information about different device generations, performance and supported functionality in iPhone Hardware Guide.
Device Properties
There are a number of device specific properties that you can access:
| iPhoneSettings.uniqueIdentifier | Unique device identifier. |
| iPhoneSettings.name | User specified name for device. |
| iPhoneSettings.model | Is it iPhone or iPod Touch? |
| iPhoneSettings.systemName | Operating system. |
| SystemInfo.operatingSystem | Operating system version. |
Anti-Piracy Check
It is not uncommon for pirates to hack applications from AppStore by removing Apple DRM protection and redistributing them for free. Unity iOS comes with anti-piracy check which allows you to determine if your application was altered after it was submitted to AppStore.
You can check if your application is genuine (not-hacked) by accessing iPhoneUtils.isApplicationGenuine property. If this property returns false you're free to notify user that he is using hacked application or you can disable access to some functions of your application.
Note: accessing iPhoneUtils.isApplicationGenuine property is reasonably expensive operation and you should never do it on a frame-to-frame basis.
Vibration Support
You can trigger iOS vibration by calling iPhoneUtils.Vibrate. However iPod Touch devices lack vibration hardware and will just ignore this call.
Standard Assets
"Standard Assets" is a folder with special meaning (same as "Plugins" and "Editor) and its content is compiled before all other scripts. You should keep your scripts in folders without special name.
Android
Advanced iOS scripting
Determining Device Generation
Different Android devices support different functionality and widely varying performance. You should target specific devices or device families and decide which functionality should be disabled to compensate for slower devices. There are a number of device specific properties that you can access to figure out the device.
Note: Android Marketplace does some additional compatibility filtering, so you should not bother that your ARMv7 only app optimized for OGLES2 is offered to some old slow devices.
Device Properties
| iPhoneSettings.uniqueIdentifier | Unique device identifier. |
| iPhoneSettings.model | Is it iPhone or iPod Touch? |
| iPhoneSettings.systemName | Operating system. |
| SystemInfo.operatingSystem | Operating system version. |
Anti-Piracy Check
It is not uncommon for pirates to hack applications by removing Apple DRM protection and redistributing them for free. Unity Android comes with anti-piracy check which allows you to determine if your application was altered after it was submitted to AppStore.
You can check if your application is genuine (not-hacked) by accessing iPhoneUtils.isApplicationGenuine property. If this property returns false you're free to notify user that he is using hacked application or you can disable access to some functions of your application.
Note: iPhoneUtils.isApplicationGenuineAvailable should be used along with iPhoneUtils.isApplicationGenuine to verify that application integrity can actually be confirmed.
Note: accessing iPhoneUtils.isApplicationGenuine property is reasonably expensive operation and you should never do it on a frame-to-frame basis.
Vibration Support
You can trigger device vibration by calling iPhoneUtils.Vibrate. However devices lacking vibration hardware will just ignore this call.
Standard Assets
"Standard Assets" is a folder with special meaning (same as "Plugins" and "Editor) and its content is compiled before all other scripts. You should keep your scripts in folders without special name.
iOS-DotNet
iOS
Now Unity iOS supports two .NET API compatibility levels: .NET 2.0 and a subset of .NET 2.0 You can select the appropriate level in PlayerSettings.
.NET API 2.0
Unity for iPhone/iPad targets supports the .NET 2.0 API profile; It is close to the full .NET 2.0 API and offers best compatibility with pre-existing .NET code.
Pros:
- Better code compatibility with desktop Unity and third party libraries
- More features in standard the API set
Cons:
- Application build size is bigger
- Slightly worse application startup time
Note: Unity iOS does not support namespaces in the scripts. If you have third party library with the source, then the best practice is to compile this library outside Unity iOS Editor and drop library .dll file into Assets folder.
.NET 2.0 Subset
Unity iOS targets also support the .NET 2.0 Subset API profile. It is closest to the Mono "monotouch" profile, so many limitations that are applicable to the "monotouch" profile are also applicable for Unity iOS implementation of this .NET profile. More information on "monotouch" profile limitations can be found here.
Pros:
- Smaller application distribution size especially when stripping is not used
Cons:
- Worse compatibility with standard and third party libraries
Android
Unity Android supports two .NET API compatibility levels: .NET 2.0 and a subset of .NET 2.0 You can select the appropriate level in PlayerSettings.
.NET API 2.0
Unity Android targets supports the .NET 2.0 API profile; It is close to the full .NET 2.0 API and offers best compatibility with pre-existing .NET code.
Pros:
- Better code compatibility with desktop Unity and third party libraries
- More features in standard the API set
Cons:
- Application build size is bigger
- Slightly worse application startup time
Note: Unity Android does not support namespaces in the scripts. If you have third party library with the source, then the best practice is to compile this library outside Unity Android Editor and drop library .dll file into Assets folder.
.NET 2.0 Subset
Unity Android targets also support the .NET 2.0 Subset API profile. It is closest to the Mono "monotouch" profile, so many limitations that are applicable to the "monotouch" profile are also applicable for Unity Android implementation of this .NET profile. More information on "monotouch" profile limitations can be found here.
Pros:
- Smaller application distribution size especially when stripping is not used
Cons:
- Worse compatibility with standard and third party libraries
iphone-Hardware
Hardware models
The following table summarizes iOS hardware available in devices of various generations:
Common to all iOS devices
- Screen: 320x480 pixels, LCD at 163ppi (unless stated otherwise)
- Built-in accelerometer
- Wi-Fi
Original iPhone
- ARM11, 412 Mhz CPU
- PowerVR MBX Lite 3D graphics processor
- 128MB of memory
- 2 megapixel camera
- Speaker and microphone
- Vibration support
- Silent switch
iPhone 3G
- ARM11, 412 Mhz CPU
- PowerVR MBX Lite 3D graphics processor
- 128MB of memory
- 2 megapixel camera
- Speaker and microphone
- Vibration support
- Silent switch
- GPS support
iPhone 3GS
- ARM Cortex A8, 600 MHz CPU
- PowerVR SGX graphics processor
- 256MB of memory
- 3 megapixel camera with video capture capability
- Speaker and microphone
- Vibration support
- Silent switch
- GPS support
- Compass support
iPhone 4
- ARM Cortex-A8 Apple A4 CPU
- ARM Cortex-A8 Apple A4 graphics processor
- 512MB of memory
- Cameras
- Rear 5.0 MP backside illuminated CMOS image sensor with 720p HD video at 30 fps and LED flash
- Front 0.3 MP (VGA) with geotagging, tap to focus, and 480p SD video at 30 fps
- Screen: 960x640 pixels, LCD at 326 ppi, 800:1 contrast ratio.
- Speaker and microphone
- Vibration Support
- Silent switch
- GPS support
- Compass Support
iPod Touch 1st generation
- ARM11, 412 Mhz CPU
- PowerVR MBX Lite 3D graphics processor
- 128MB of memory
iPod Touch 2nd generation
- ARM11, 533 Mhz CPU
- PowerVR MBX Lite 3D graphics processor
- 128MB of memory
- Speaker and microphone
iPad
- 1 GHz Apple A4 CPU
- Wifi + Blueooth + (3G Cellular HSDPA, 2G cellular EDGE on the 3G version)
- Accelerometer, ambient light sensor, magnetometer (for digital compass)
- Mechanical keys: Home, sleep, screen rotation lock, volume.
- Screen: 1024x768 pixels, LCD at 132 ppi, LED-backlit.
Graphics Processing Unit and Hidden Surface Removal
The iPhone/iPad graphics processing unit (GPU) is a Tile-Based Deferred Renderer. In contrast with most GPUs in desktop computers, the iPhone/iPad GPU focuses on minimizing the work required to render an image as early as possible in the processing of a scene. That way, only the visible pixels will consume processing resources.
The GPU's frame buffer is divided up into tiles and rendering happens tile by tile. First, triangles for the whole frame are gathered and assigned to the tiles. Then, visible fragments of each triangle are chosen. Finally, the selected triangle fragments are passed to the rasterizer (triangle fragments occluded from the camera are rejected at this stage).
In other words, the iPhone/iPad GPU implements a Hidden Surface Removal operation at reduced cost. Such an architecture consumes less memory bandwidth, has lower power consumption and utilizes the texture cache better. Tile-Based Deferred Rendering allows the device to reject occluded fragments before actual rasterization, which helps to keep overdraw low.
For more information see also:-
- POWERVR MBX Technology Overview
- Apple Notes on iPhone/iPad GPU and OpenGL ES
- Apple Performance Advices for OpenGL ES in General
- Apple Performance Advices for OpenGL ES Shaders
SGX series
Starting with the iPhone 3GS, newer devices are equipped with the SGX series of GPUs. The SGX series features support for the OpenGL ES2.0 rendering API and vertex and pixel shaders. The Fixed-function pipeline is not supported natively on such GPUs, but instead is emulated by generating vertex and pixel shaders with analogous functionality on the fly.
The SGX series fully supports MultiSample anti-aliasing.
MBX series
Older devices such as the original iPhone, iPhone 3G and iPod Touch 1st and 2nd Generation are equipped with the MBX series of GPUs. The MBX series supports only OpenGL ES1.1, the fixed function Transform/Lighting pipeline and two textures per fragment.
Texture Compression
The only texture compression format supported by iOS is PVRTC. PVRTC provides support for RGB and RGBA (color information plus an alpha channel) texture formats and can compress a single pixel to two or four bits.
The PVRTC format is essential to reduce the memory footprint and to reduce consumption of memory bandwidth (ie, the rate at which data can be read from memory, which is usually very limited on mobile devices).
Vertex Processing Unit
The iPhone/iPad has a dedicated unit responsible for vertex processing which runs calculations in parallel with rasterization. In order to achieve better parallelization, the iPhone/iPad processes vertices one frame ahead of the rasterizer.
Unified Memory Architecture
Both the CPU and GPU on the iPhone/iPad share the same memory. The advantage is that you don't need to worry about running out of video memory for your textures (unless, of course, you run out of main memory too). The disadvantage is that you share the same memory bandwidth for gameplay and graphics. The more memory bandwidth you dedicate to graphics, the less you will have for gameplay and physics.
Multimedia CoProcessing Unit
The iPhone/iPad main CPU is equipped with a powerful SIMD (Single Instruction, Multiple Data) coprocessor supporting either the VFP or the NEON architecture. The Unity iOS run-time takes advantage of these units for multiple tasks such as calculating skinned mesh transformations, geometry batching, audio processing and other calculation-intensive operations.
Page last updated: 2011-11-03iphone-performance
Good performance is an essential ingredient in most games and an understanding of the graphical and processing abilities of iOS devices will help you get the best results from them.
This section explains how to optimize an iOS project to make the best possible use of the hardware.
- Optimizing Graphics Performance
- Optimizing Physics Performance
- Optimizing Script Performance
- Measuring Performance with the Built-in Profiler
- Tuning Main Loop Performance
- Optimizing the Size of the Built iOS Player
iPhone Optimizing Graphics Performance
Desktop
Good performance is critical to the success of many games. Below are some simple guidelines for maximizing the speed of your game's graphical rendering.
Optimizing Meshes
You only pay a rendering cost for objects that have a Mesh Renderer attached and are within the view frustum. There is no rendering cost from empty GameObjects in the scene or from objects that are out of the view of any camera.
Modern graphics cards are really good at handling a lot of polygons but there is a significant overhead for each batch (ie, mesh) that you submit to the graphics card. So if you have a 100-triangle object it is going to be just as expensive to render as a 1500-triangle object. The "sweet spot" for optimal rendering performance is somewhere around 1500-4000 triangles per mesh.
Usually, the best way to improve rendering performance is to combine objects together so that each mesh has around 1500 or more triangles and uses only one Material for the entire mesh. It is important to understand that combining two objects which don't share a material does not give you any performance increase at all. The most common reason for having multiple materials is that two meshes don't share the same textures, so to optimize rendering performance, you should ensure that any objects you combine share the same textures.
However, when using many pixel lights in the Forward rendering path, there are situations where combining objects may not make sense, as explained below.
Pixel Lights in the Forward Rendering Path
Note: this applies only to the Forward rendering path.
If you use pixel lighting then each mesh has to be rendered as many times as there are pixel lights illuminating it. If you combine two meshes that are very far apart, it will increase the effective size of the combined object. All pixel lights that illuminate any part of this combined object will be taken into account during rendering, so the number of rendering passes that need to be made could be increased. Generally, the number of passes that must be made to render the combined object is the sum of the number of passes for each of the separate objects, and so nothing is gained by combining. For this reason, you should not combine meshes that are far enough apart to be affected by different sets of pixel lights.
During rendering, Unity finds all lights surrounding a mesh and calculates which of those lights affect it most. The Quality Settings are used to modify how many of the lights end up as pixel lights and how many as vertex lights. Each light calculates its importance based on how far away it is from the mesh and how intense its illumination is. Furthermore, some lights are more important than others purely from the game context. For this reason, every light has a Render Mode setting which can be set to Important or Not Important; lights marked as Not Important will typically have a lower rendering overhead.
As an example, consider a driving game where the player's car is driving in the dark with headlights switched on. The headlights are likely to be the most visually significant light sources in the game, so their Render Mode would probably be set to Important. On the other hand, there may be other lights in the game that are less important (other cars' rear lights, say) and which don't improve the visual effect much by being pixel lights. The Render Mode for such lights can safely be set to Not Important so as to avoid wasting rendering capacity in places where it will give little benefit.
Per-Layer Cull Distances
In some games, it may be appropriate to cull small objects more aggressively than large ones in order to reduce number of draw calls. For example, small rocks and debris could be made invisible at long distances while large buildings would still be visible. To accomplish this culling, you can put small objects into a separate layer and setup per-layer cull distances using the Camera.layerCullDistances script function.
Shadows
If you are deploying for Desktop platforms then you should be careful when using shadows because they can add a lot of rendering overhead to your game if not used correctly. For further details, see the Shadows page.
Note: Shadows are not currently supported on iOS or Android devices.
See Also
iOS
A useful background to iOS optimization can be found on the iOS hardware page.
Alpha-Testing
Unlike desktop machines, iOS devices incur a high performance overhead for alpha-testing (or use of the discard and clip operations in pixel shaders). You should replace alpha-test shaders with alpha-blend if at all possible. Where alpha-testing cannot be avoided, you should keep the overall number of visible alpha-tested pixels to a minimum.
Vertex Performance
Generally you should aim to have no more than 40,000 vertices visible per frame when targeting iPhone 3GS or newer devices. You should keep the vertex count below 10,000 for older devices equipped with the MBX GPU, such as the original iPhone, iPhone 3G and iPod Touch 1st and 2nd Generation.
Lighting Performance
Per-pixel dynamic lighting will add significant rendering overhead to every affected pixel and can lead to objects being rendered in multiple passes. Avoid having more than one Pixel Light illuminating any single object and use directional lights as far as possible. Note that a Pixel Light is a one which has its Render Mode option set to Important.
Per-vertex dynamic lighting can add significant cost to vertex transformations. Try to avoid situations where multiple lights illuminate any given object. For static objects, baked lighting is much more efficient.
Optimize Model Geometry
When optimizing the geometry of a model, there are two basic rules:
- Don't use any more triangles than necessary
- Try to keep the number of UV mapping seams and hard edges (ie, doubled-up vertices) as low as possible
Note that the actual number of vertices that graphics hardware has to process is usually not the same as the number reported by a 3D application. Modeling applications usually display the geometric vertex count, ie, the number of distinct corner points that make up a model.
For a graphics card, however, some geometric vertices will need to be split into two or more logical vertices for rendering purposes. A vertex must be split if it has multiple normals, UV coordinates or vertex colors. Consequently, the vertex count in Unity is invariably a lot higher than the count given by the 3D application.
Texture Compression
Using iOS's native PVRT compression formats will decrease the size of your textures (resulting in faster load times and smaller memory footprint) and can also dramatically increase rendering performance. Compressed textures use only a fraction of the memory bandwidth needed for uncompressed 32bit RGBA textures. A comparison of uncompressed vs compressed texture performance can be found in the iOS Hardware Guide.
Some images are prone to visual artifacts in the alpha channels of PVRT-compressed textures. In such cases, you might need to tweak the PVRT compression parameters directly in your imaging software. You can do that by installing the PVR export plugin or using PVRTexTool from Imagination Tech, the creators of the PVRT format. The resulting compressed image file with a .pvr extension will be imported by the Unity editor directly and the specified compression parameters will be preserved.
If PVRT-compressed textures do not give good enough visual quality or you need especially crisp imaging (as you might for GUI textures, say) then you should consider using 16-bit textures instead of RGBA textures. By doing so, you will reduce the memory bandwidth by half.
Tips for writing high-performance shaders
The GPUs on iOS devices have fully supported pixel and vertex shaders since the iPhone 3GS. However, the performance is nowhere near what you would get from a desktop machine, so you should not expect desktop shaders to port to iOS unchanged. Typically, shaders will need to be hand optimized to reduce calculations and texture reads in order to get good performance.
Complex mathematical operations
Transcendental mathematical functions (such as pow, exp, log, cos, sin, tan, etc) will tax the GPU greatly, so a good rule of thumb is to have no more than one such operation per fragment. Consider using lookup textures as an alternative where applicable.
It is not advisable to attempt to write your own normalize, dot, inversesqrt operations, however. If you use the built-in ones then the driver will generate much better code for you.
Bear in mind also that the discard operation will make your fragments slower.
Floating point operations
You should always specify the precision of floating point variables when writing custom shaders. It is critical to pick the smallest possible floating point format in order to get the best performance.
If the shader is written in GLSL ES then the floating point precision is specified as follows:-
- highp - full 32-bit floating point format, suitable for vertex transformations but has the slowest performance.
- mediump - reduced 16-bit floating point format, suitable for texture UV coordinates and roughly twice as fast as highp
- lowp - 10-bit fixed point format, suitable for colors, lighting calculation and other high-performance operations and roughly four times faster than highp
If the shader is written in CG or it is a surface shader then precision is specified as follows:-
- float - analogous to highp in GLSL ES, slowest
- half - analogous to mediump in GLSL ES, roughly twice as fast as float
- fixed - analogous to lowp in GLSL ES, roughly four times faster than float
For further details about shader performance, please read the Shader Performance page.
Hardware documentation
Take your time to study Apple documentations on hardware and best practices for writing shaders. Note that we would suggest to be more aggressive with floating point precision hints however.
Bake Lighting into Lightmaps
Bake your scene static lighting into textures using Unity built-in Lightmapper. The process of generating a lightmapped environment takes only a little longer than just placing a light in the scene in Unity, but:
- It is going to run a lot faster (2-3 times for eg. 2 pixel lights)
- And look a lot better since you can bake global illumination and the lightmapper can smooth the results
Share Materials
If a number of objects being rendered by the same camera uses the same material, then Unity iOS will be able to employ a large variety of internal optimizations such as:
- Avoiding setting various render states to OpenGL ES.
- Avoiding calculation of different parameters required to setup vertex and pixel processing
- Batching small moving objects to reduce draw calls
- Batching both big and small objects with enabled "static" property to reduce draw calls
All these optimizations will save you precious CPU cycles. Therefore, putting extra work to combine textures into single atlas and making number of objects to use the same material will always pay off. Do it!
Simple Checklist to make Your Game Faster
- Keep vertex count below:
- 40K per frame when targeting iPhone 3GS and newer devices (with SGX GPU)
- 10K per frame when targeting older devices (with MBX GPU)
- If you're using built-in shaders, peek ones from Mobile category. Keep in mind that Mobile/VertexLit is currently the fastest shader.
- Keep the number of different materials per scene low - share as many materials between different objects as possible.
- Set Static property on a non-moving objects to allow internal optimizations.
- Use PVRTC formats for textures when possible, otherwise choose 16bit textures over 32bit.
- Use combiners or pixel shaders to mix several textures per fragment instead of multi-pass approach.
- If writing custom shaders, always use smallest possible floating point format:
- fixed / lowp -- perfect for color, lighting information and normals,
- half / mediump -- for texture UV coordinates,
- float / highp -- avoid in pixel shaders, fine to use in vertex shader for vertex position calculations.
- Minimize use of complex mathematical operations such as pow, sin, cos etc in pixel shaders.
- Do not use Pixel Lights when it is not necessary -- choose to have only a single (preferably directional) pixel light affecting your geometry.
- Do not use dynamic lights when it is not necessary -- choose to bake lighting instead.
- Choose to use less textures per fragment.
- Avoid alpha-testing, choose alpha-blending instead.
- Do not use fog when it is not necessary.
- Learn benefits of Occlusion culling and use it to reduce amount of visible geometry and draw-calls in case of complex static scenes with lots of occlusion. Plan your levels to benefit from Occlusion culling.
- Use skyboxes to "fake" distant geometry.
See Also
Android
Lighting Performance
Per-pixel dynamic lighting will add significant cost to every affected pixel and can lead to rendering object in multiple passes. Avoid having more than one Pixel Light affecting any single object, prefer it to be a directional light. Note that Pixel Light is a light which has a Render Mode setting set to Important.
Per-vertex dynamic lighting can add significant cost to vertex transformations. Avoid multiple lights affecting single objects. Bake lighting for static objects.
Optimize Model Geometry
When optimizing the geometry of a model, there are two basic rules:
- Don't use excessive amount of faces if you don't have to
- Keep the number of UV mapping seams and hard edges as low as possible
Note that the actual number of vertices that graphics hardware has to process is usually not the same as what is displayed in a 3D application. Modeling applications usually display the geometric vertex count, i.e. number of points that make up a model.
For a graphics card however, some vertices have to be split into separate ones. If a vertex has multiple normals (it's on a "hard edge"), or has multiple UV coordinates, or has multiple vertex colors, it has to be split. So the vertex count you see in Unity is almost always different from the one displayed in 3D application.
Texture Compression
All Android devices with support for OpenGL ES 2.0 also support the ETC1 compression format; it's therefore encouraged to whenever possible use ETC1 as the prefered texture format. Using compressed textures is important not only to decrease the size of your textures (resulting in faster load times and smaller memory footprint), but can also increase your rendering performance dramatically! Compressed textures require only a fraction of memory bandwidth compared to full blown 32bit RGBA textures.
If targeting a specific graphics architecture, such as the Nvidia Tegra or Qualcomm Snapdragon, it may be worth considering using the proprietary compression formats available on those architectures. The Android Market also allows filtering based on supported texture compression format, meaning a distribution archive (.apk) with for example DXT compressed textures can be prevented for download on a device which doesn't support it.
Enable Mip Maps
As a rule of thumb, always have Generate Mip Maps enabled. In the same way Texture Compression can help limit the amount of texture data transfered when the GPU is rendering, a mip mapped texture will enable the GPU to use a lower-resolution texture for smaller triangles. The only exception to this rule is when a texel (texture pixel) is known to map 1:1 to the rendered screen pixel, as with UI elements or in a pure 2D game.
Tips for writing well performing shaders
Although all Android OpenGL ES 2.0 GPUs fully support pixel and vertex shaders, do not expect to grab a desktop shader with complex per-pixel functionality and run it on Android device at 30 frames per second. Most often shaders will have to be hand optimized, calculations and texture reads kept to a minimum in order to achieve good frame rates.
Complex arithmetic operations
Arithmetic operations such as pow, exp, log, cos, sin, tan etc heavily tax GPU. Rule of thumb is to have not more than one such operation per fragment. Consider that sometimes lookup textures could be a better alternative.
Do NOT try to roll your own normalize, dot, inversesqrt operations however. Always use built-in ones -- this was driver will generate much better code for you.
Keep in mind that discard operation will make your fragments slower.
Floating point operations
Always specify precision of the floating point variables while writing custom shaders. It is crucial to pick smallest possible format in order to achieve best performance.
If shader is written in GLSL ES, then precision is specified as following:
- highp - full 32 bits floating point format, well suitable for vertex transformations, slowest
- mediump - reduced 16 bits floating point format, well suitable for texture UV coordinates, roughly x2 faster than highp
- lowp - 10 bits fixed point format, well suitable for colors, lighting calculation and other high performant operations, roughly x4 faster than highp
If shader is written in CG or it is a surface shader, then precision is specified as following:
- float - analogous to highp in GLSL ES, slowest
- half - analogous to mediump in GLSL ES, roughly x2 faster than float
- fixed - analogous to lowp in GLSL ES, roughly x4 faster than float
For more details about general shader performance, please read the Shader Performance page. Quoted performance figures are based on the PowerVR graphics architecture, available in devices such as the Samsung Nexus S. Other hardware architectures may experience less (or more) benefit from using reduced register precision.
Bake Lighting into Lightmaps
Bake your scene static lighting into textures using Unity built-in Lightmapper. The process of generating a lightmapped environment takes only a little longer than just placing a light in the scene in Unity, but:
- It is going to run a lot faster (2-3 times for eg. 2 pixel lights)
- And look a lot better since you can bake global illumination and the lightmapper can smooth the results
Share Materials
If a number of objects being rendered by the same camera uses the same material, then Unity Android will be able to employ a large variety of internal optimizations such as:
- Avoiding setting various render states to OpenGL ES.
- Avoiding calculation of different parameters required to setup vertex and pixel processing
- Batching small moving objects to reduce draw calls
- Batching both big and small objects with enabled "static" property to reduce draw calls
All these optimizations will save you precious CPU cycles. Therefore, putting extra work to combine textures into single atlas and making number of objects to use the same material will always pay off. Do it!
Simple Checklist to make Your Game Faster
- If you're using built-in shaders, peek ones from Mobile category. Keep in mind that Mobile/VertexLit is currently the fastest shader.
- Keep the number of different materials per scene low - share as many materials between different objects as possible.
- Set Static property on a non-moving objects to allow internal optimizations.
- Use ETC1 format for textures when possible, otherwise choose 16bit textures over 32bit for uncompressed texture data.
- Use mipmaps.
- Use combiners or pixel shaders to mix several textures per fragment instead of multi-pass approach.
- If writing custom shaders, always use smallest possible floating point format:
- fixed / lowp -- perfect for color, lighting information and normals,
- half / mediump -- for texture UV coordinates,
- float / highp -- avoid in pixel shaders, fine to use in vertex shader for vertex position calculations.
- Minimize use of complex mathematical operations such as pow, sin, cos etc in pixel shaders.
- Do not use Pixel Lights when it is not necessary -- choose to have only a single (preferably directional) pixel light affecting your geometry.
- Do not use dynamic lights when it is not necessary -- choose to bake lighting instead.
- Choose to use less textures per fragment.
- Avoid alpha-testing, choose alpha-blending instead.
- Do not use fog when it is not necessary.
- Learn benefits of Occlusion culling and use it to reduce amount of visible geometry and draw-calls in case of complex static scenes with lots of occlusion. Plan your levels to benefit from Occlusion culling.
- Use skyboxes to "fake" distant geometry.
See Also
- iPhone Optimizing Graphics Performance (for when the graphics architecture is known to be Imagination Tech's PowerVR.)
iphone-DrawCall-Batching
To draw an object on the screen, the engine has to issue a draw call to the graphics API (OpenGL ES in the case of iOS). Every single draw call requires a significant amount of work on the part of the graphics API, causing significant performance overhead on the CPU side.
Unity combines a number of objects at runtime and draws them together with a single draw call. This operation is called "batching". The more objects Unity can batch together, the better rendering performance you will get.
Built-in batching support in Unity has significant benefit over simply combining geometry in the modeling tool (or using the CombineChildren script from the Standard Assets package). Batching in Unity happens after visibility determination step. The engine does culling on each object individually, and the amount of rendered geometry is going to be the same as without batching. Combining geometry in the modeling tool, on the other hand, prevents effecient culling and results in much higher amount of geometry being rendered.
Materials
Only objects sharing the same material can be batched together. Therefore, if you want to achieve good batching, you need to share as many materials among different objects as possible.
If you have two identical materials which differ only in textures, you can combine those textures into a single big texture - a process often called texture atlasing. Once textures are in the same atlas, you can use single material instead.
If you need to access shared material properties from the scripts, then it is important to note that modifying Renderer.material will create a copy of the material. Instead, you should use Renderer.sharedMaterial to keep material shared.
Dynamic Batching
Unity can automatically batch moving objects into the same draw call if they share the same material.
Dynamic batching is done automatically and does not require any additional effort on your side.
- Batching dynamic objects has certain overhead per vertex, so batching is applied only to meshes containing less than 900 vertex attributes in total.
- If your shader is using Vertex Position, Normal and single UV, then you can batch up to 300 verts and if your shader is using Vertex Position, Normal, UV0, UV1 and Tangent, then only 180 verts.
- Please note: attribute count limit might be changed in future
- Don't use scale. Objects with scale (1,1,1) and (2,2,2) won't batch.
- Uniformly scaled objects won't be batched with non-uniformly scaled ones.
- Objects with scale (1,1,1) and (1,2,1) won't be batched. On the other hand (1,2,1) and (1,3,1) will be.
- Using different material instances will cause batching to fail.
- Objects with lightmaps have additional (hidden) material parameter: offset/scale in lightmap, so lightmapped objects won't be batched (unless they point to same portions of lightmap)
- Multi-pass shaders will break batching. E.g. Almost all unity shaders supports several lights in forward rendering, effectively doing additional pass for them
- Using instances of a prefab automatically are using the same mesh and material.
Static Batching
Static batching, on the other hand, allows the engine to reduce draw calls for geometry of any size (provided it does not move and shares the same material). Static batching is significantly more efficient than dynamic batching. You should choose static batching as it will require less CPU power.
In order to take advantage of static batching, you need explicitly specify that certain objects are static and will not move, rotate or scale in the game. To do so, you can mark objects as static using the Static checkbox in the Inspector:

Using static batching will require additional memory for storing the combined geometry. If several objects shared the same geometry before static batching, then a copy of geometry will be created for each object, either in the Editor or at runtime. This might not always be a good idea - sometimes you will have to sacrifice rendering performance by avoiding static batching for some objects to keep a smaller memory footprint. For example, marking trees as static in a dense forest level can have serious memory impact.
Static batching is only available in Unity iOS Advanced.
Further Reading
Page last updated: 2012-02-02iphone-ModelingOptimizedCharacters
Below are some tips for designing character models to give optimal rendering speed.
Use a Single Skinned Mesh Renderer
You should use only a single skinned mesh renderer for each character. Unity optimizes animation using visibility culling and bounding volume updates and these optimizations are only activated if you use one animation component and one skinned mesh renderer in conjunction. The rendering time for a model could roughly double as a result of using two skinned meshes in place of a single mesh and there is seldom any practical advantage in using multiple meshes.
Use as Few Materials as Possible
You should also keep the number of materials on each mesh as low as possible. The only reason why you might want to have more than one material on a character is that you need to use different shaders for different parts (eg, a special shader for the eyes). However, two or three materials per character should be sufficient in almost all cases.
Use as Few Bones as Possible
A bone hierarchy in a typical desktop game uses somewhere between fifteen and sixty bones. The fewer bones you use, the better the performance will be. You can achieve very good quality on desktop platforms and fairly good quality on mobile platforms with about thirty bones. Ideally, keep the number below thirty for mobile devices and don't go too far above thirty for desktop games.
Polygon Count
The number of polygons you should use depends on the quality you require and the platform you are targeting. For mobile devices, somewhere between 300 and 1500 polygons per mesh will give good results, whereas for desktop platforms the ideal range is about 1500 to 4000. You may need to reduce the polygon count per mesh if the game can have lots of characters onscreen at any given time. As an example, Half Life 2 used 2500-5000 triangles per character. Current AAA games running on the PS3 or Xbox 360 usually have characters with 5000-7000 triangles.
Keep Forward and Inverse Kinematics Separate
When animations are imported, a model's inverse kinematic (IK) nodes are baked into forward kinematics (FK) and as a result, Unity doesn't need the IK nodes at all. However, if they are left in the model then they will have a CPU overhead even though they don't affect the animation. You can delete the redundant IK nodes in Unity or in the modeling tool, according to your preference. Ideally, you should keep separate IK and FK hierarchies during modeling to make it easier to remove the IK nodes when necessary.
Page last updated: 2011-11-04iphone-RenderingStatistics
The has a button in the top right corner. When the button is pressed, an overlay window is displayed which shows realtime rendering statistics, which are useful for optimizing performance. The exact statistics displayed vary according to the build target.

Rendering Statistics Window.
The Statistics window contains the following information:-
| Time per frame and FPS | The amount of time taken to process and render one game frame (and its reciprocal, frames per second). Note that this number only includes the time taken to do the frame update and render the game view; it does not include the time taken in the editor to draw the scene view, inspector and other editor-only processing. |
| Draw Calls | The total number of meshes drawn after batching was applied. Note that where objects are rendered multiple times (for example, objects illuminated by pixel lights), each rendering results in a separate draw call. |
| Batched (Draw Calls) | The number of initially separate draw calls that were added to batches. "Batching" is where the engine attempts to combine the rendering of multiple objects into one draw call in order to reduce CPU overhead. To ensure good batching, you should share materials between different objects as often as possible. |
| Tris and Verts | The number of triangles and vertices drawn. This is mostly important when optimizing for low-end hardware |
| Used Textures | The number of textures used to draw this frame and their memory usage. |
| Render Textures | The number of Render Textures and their memory usage. The number of times the active Render Texture was switched each frame is also displayed. |
| Screen | The size of the screen, along with its anti-aliasing level and memory usage. |
| VRAM usage | Approximate bounds of current video memory (VRAM) usage. This also shows how much video memory your graphics card has. |
| VBO total | The number of unique meshes (Vertex Buffers Objects or VBOs) that are uploaded to the graphics card. Each different model will cause a new VBO to be created. In some cases scaled objects will cause additional VBOs to be created. In the case of a static batching, several different objects can potentially share the same VBO. |
| Visible Skinned Meshes | The number of skinned meshes rendered. |
| Animations | The number of animations playing. |
iphone-Optimizing-Physics
The NVIDIA PhysX physics engine used by Unity is available on iOS but the performance limits of the hardware will be reached more easily on mobile platforms than desktops.
Here are some tips for tuning physics to get better performance on iOS:-
- You can adjust the Fixed Timestep setting (in the Time manager) to reduce the time spent on physics updates. Increasing the timestep will reduce the CPU overhead at the expense of the accuracy of the physics. Often, lower accuracy is an acceptable tradeoff for increased speed.
- Set the Maximum Allowed Timestep in the Time manager in the 8-10fps range to cap the time spent on physics in the worst case scenario.
- Mesh colliders have a much higher performance overhead than primitive colliders, so use them sparingly. It is often possible to approximate the shape of a mesh by using child objects with primitive colliders. The child colliders will be controlled collectively as a single compound collider by the rigidbody on the parent.
- While wheel colliders are not strictly colliders in the sense of solid objects, they nonetheless have a high CPU overhead.
The total amount of physics calculation depends on the number of non-sleeping rigid bodies and colliders in the scene and the complexity of the colliders. You can keep track of how many physics objects there are in the scene using the internal profiler.
Page last updated: 2011-11-04iphone-Optimizing-Scripts
This page gives some general hints for improving script performance on iOS.
Reduce Fixed Delta Time
Use a fixed delta time value between 0.04 and 0.067 seconds (ie, 15-25 frames per second). You can change this in . This reduces the frequency with which FixedUpdate is called and how often the physics engine has to perform collision detection and rigidbody updates. If you are using a rigidbody for the main character, you can enable interpolation in the Rigidbody Component to smooth out low fixed delta time steps.
Reduce GetComponent Calls
Using GetComponent or built-in component accessors can have a noticeable overhead. You can avoid this by getting a reference to the component once and assigning it to a variable (sometimes referred to as "caching" the reference). For example, if you are using something like:-
function Update () {
transform.Translate(0, 1, 0);
}
...you would get better performance by changing it to:-
var myTransform : Transform;
function Awake () {
myTransform = transform;
}
function Update () {
myTransform.Translate(0, 1, 0);
}
Avoid Allocating Memory
You should avoid allocating new objects unless you really need to, since they increase the garbage collection overhead when they are no longer in use. You can often reuse arrays and other objects rather than allocate new ones and doing so will help to minimise garbage collection. Also, you should use structs instead of classes where possible. Struct variables are allocated from the stack like simple types rather than from the heap like object types. Since stack allocation is faster and involves no garbage collection, structs will often improve performance if they are fairly small in size. While large structs will still avoid allocation/collection overhead, they will incur a separate overhead due to "pass-by-value" copying and may actually be less efficient than the equivalent object classes.
Minimise the GUI
The GUILayout functions are very convenient for automatic spacing of GUI elements. However, this automation naturally comes with a processing overhead. You can avoid some of this overhead by handling the layout manually using the GUI functions. Additionally, you can set a script's useGUILayout variable to false in order to disable the layout phase completely:-
function Awake () {
useGUILayout = false;
}
Use iOS Script Call Optimization
Most of the functions in the UnityEngine namespace are implemented in C/C++. Calling a C/C++ function from a Mono script involves a performance overhead. You can use iOS Script Call optimization (menu: ) to save about 1 to 4 milliseconds per frame. The options for this setting are:-
- Slow and Safe - the default Mono internal call handling with exception support.
- Fast and Exceptions Unsupported - a faster implementation of Mono internal call handling. However, this doesn't support exceptions and so should be used with caution. An app that doesn't explicitly handle exceptions (and doesn't need to deal with them gracefully) is an ideal candidate for this option.
Optimizing Garbage Collection
As mentioned above, it is best to avoid allocations as far as possible. However, given that they can't be completely eliminated, there are two main strategies you can use to minimise their intrusion into gameplay:-
Small heap with fast and frequent garbage collection
This strategy is often best for games that have long periods of gameplay where a smooth framerate is the main concern. A game like this will typically allocate small blocks frequently but these blocks will be in use only briefly. The typical heap size when using this strategy on iOS is about 200KB and garbage collection will take about 5ms on an iPhone 3G. If the heap increases to 1MB, the collection will take about 7ms. It can therefore be advantageous sometimes to request a garbage collection at a regular frame interval. This will generally make collections happen more often than strictly necessary but they will be processed quickly and with minimal effect on gameplay:-
if (Time.frameCount % 30 == 0)
{
System.GC.Collect();
}
However, you should use this technique with caution and check the profiler statistics to make sure that it is really reducing collection time for your game.
Large heap with slow but infrequent garbage collection
This strategy works best for games where allocations (and therefore collections) are relatively infrequent and can be handled during pauses in gameplay. It is useful for the heap to be as large as possible without being so large as to get your app killed by the OS due to low system memory. However, the Mono runtime avoids expanding the heap automatically if at all possible. You can expand the heap manually by preallocating some placeholder space during startup (ie, you instantiate a "useless" object that is allocated purely for its effect on the memory manager):-
function Start() {
var tmp = new System.Object[1024];
// make allocations in smaller blocks to avoid them to be treated in a special way, which is designed for large blocks
for (var i : int = 0; i < 1024; i++)
tmp[i] = new byte[1024];
// release reference
tmp = null;
}
A sufficiently large heap should not get completely filled up between those pauses in gameplay that would accommodate a collection. When such a pause occurs, you can request a collection explicitly:-
System.GC.Collect();
Again, you should take care when using this strategy and pay attention to the profiler statistics rather than just assuming it is having the desired effect.
Page last updated: 2011-10-11iphone-InternalProfiler
Unity comes with a performance profiler. It is disabled by default so to enable it, you need to open the Unity-generated XCode project, select the iPhone_Profiler.h file and change the line
#define ENABLE_INTERNAL_PROFILER 0
to
#define ENABLE_INTERNAL_PROFILER 1
Select in the XCode menu to display the output console (GDB) and then run your project. Unity will output statistics to the console window every thirty frames. For example:
iPhone/iPad Unity internal profiler stats: cpu-player> min: 9.8 max: 24.0 avg: 16.3 cpu-ogles-drv> min: 1.8 max: 8.2 avg: 4.3 cpu-waits-gpu> min: 0.8 max: 1.2 avg: 0.9 cpu-present> min: 1.2 max: 3.9 avg: 1.6 frametime> min: 31.9 max: 37.8 avg: 34.1 draw-call #> min: 4 max: 9 avg: 6 | batched: 10 tris #> min: 3590 max: 4561 avg: 3871 | batched: 3572 verts #> min: 1940 max: 2487 avg: 2104 | batched: 1900 player-detail> physx: 1.2 animation: 1.2 culling: 0.5 skinning: 0.0 batching: 0.2 render: 12.0 fixed-update-count: 1 .. 2 mono-scripts> update: 0.5 fixedUpdate: 0.0 coroutines: 0.0 mono-memory> used heap: 233472 allocated heap: 548864 max number of collections: 1 collection total duration: 5.7
All times are measured in milliseconds per frame. You can see the minimum, maximum and average times over the last thirty frames.
General CPU Activity
| cpu-player | Displays the time your game spends executing code inside the Unity engine and executing scripts on the CPU. |
| cpu-ogles-drv | Displays the time spent executing OpenGL ES driver code on the CPU. Many factors like the number of draw calls, number of internal rendering state changes, the rendering pipeline setup and even the number of processed vertices can have an effect on the driver stats. |
| cpu-waits-gpu | Displays the time the CPU is idle while waiting for the GPU to finish rendering. If this number exceeds 2-3 milliseconds then your application is most probably fillrate/GPU processing bound. |
| cpu-present | The amount of time spent executing the presentRenderbuffer command in OpenGL ES. |
| frametime | Represents the overall time of a game frame. Note that iOS hardware is always locked at a 60Hz refresh rate, so you will always get multiples times of ~16.7ms (1000ms/60Hz = ~16.7ms). |
Rendering Statistics
| draw-call # | The number of draw calls per frame. Keep it as low as possible. |
| tris # | Total number of triangles sent for rendering. |
| verts # | Total number of vertices sent for rendering. You should keep this number below 10000 if you use only static geometry but if you have lots of skinned geometry then you should keep it much lower. |
| batched | Number of draw-calls, triangles and vertices which were automatically batched by the engine. Comparing these numbers with draw-call and triangle totals will give you an idea how well is your scene prepared for batching. Share as many materials as possible among your objects to improve batching. |
Detailed Unity Player Statistics
The player-detail section provides a detailed breakdown of what is happening inside the engine:-
| physx | Time spent on physics. |
| animation | Time spent animating bones. |
| culling | Time spent culling objects outside the camera frustum. |
| skinning | Time spent applying animations to skinned meshes. |
| batching | Time spent batching geometry. Batching dynamic geometry is considerably more expensive than batching static geometry. |
| render | Time spent rendering visible objects. |
| fixed-update-count | Minimum and maximum number of FixedUpdates executed during this frame. Too many FixedUpdates will deteriorate performance considerably. There are some simple guidelines to set a good value for the fixed time delta here. |
Detailed Scripts Statistics
The mono-scripts section provides a detailed breakdown of the time spent executing code in the Mono runtime:
| update | Total time spent executing all Update() functions in scripts. |
| fixedUpdate | Total time spent executing all FixedUpdate() functions in scripts. |
| coroutines | Time spent inside script coroutines. |
Detailed Statistics on Memory Allocated by Scripts
The mono-memory section gives you an idea of how memory is being managed by the Mono garbage collector:
| allocated heap | Total amount of memory available for allocations. A garbage collection will be triggered if there is not enough memory left in the heap for a given allocation. If there is still not enough free memory even after the collection then the allocated heap will grow in size. |
| used heap | The portion of the allocated heap which is currently used up by objects. Every time you create a new class instance (not a struct) this number will grow until the next garbage collection. |
| max number of collections | Number of garbage collection passes during the last 30 frames. |
| collection total duration | Total time (in milliseconds) of all garbage collection passes that have happened during the last 30 frames. |
iphone-Optimizing-MainLoop
Setting the Desired Framerate
Unity iOS allows you to change the frequency with which your application will try to execute its rendering loop, which is set to 30 frames per second by default. You can lower this number to save battery power but of course this saving will come at the expense of frame updates. Conversely, you can increase the framerate to give the rendering priority over other activities such as touch input and accelerometer processing. You will need to experiment with your choice of framerate to determine how it affects gameplay in your case.
If your application involves heavy computation or rendering and can maintain only 15 frames per second, say, then setting the desired frame rate higher than fifteen wouldn't give any extra performance. The application has to be optimized sufficiently to allow for a higher framerate.
To set the desired framerate, open the XCode project generated by Unity and open the AppController.mm file. The line
#define kFPS 30
...determines the the current framerate, so you can just change to set the desired value. For example, if you change the define to:-
#define kFPS 60
...then the application will attempt to render at 60 FPS instead of 30 FPS.
The Rendering Loop
When iOS version 3.1 or later is in use, Unity will use the CADisplayLink class to schedule the rendering loop. Versions before 3.1 need to use one of several fallback methods to handle the loop. However, the fallback methods can be activated even for iOS 3.1 and later by changing the line
#define USE_DISPLAY_LINK_IF_AVAILABLE 1
...and changing it to
#define USE_DISPLAY_LINK_IF_AVAILABLE 0
Fallback Loop Types
Apple recommends the system timer for scheduling the rendering operation on iOS versions before 3.1. This approach is good for applications where performance is not critical and favours battery life and correct processing of events over rendering performance. However, better rendering performance is often more important to games, so Unity provides several scheduling methods to tweak the performance of the rendering loop:-
- System Timer: this is the standard approach suggested by Apple. It uses the NSTimer class to schedule rendering and has the worst rendering performance but guarantees to process all input events.
- Thread: a separate thread is used to schedule rendering. This offers better rendering performance than the NSTimer approach, but sometimes could miss touch or accelerometer events. This method of scheduling is also the easiest to set up and is the default method used by Unity for iOS versions before 3.1.
- Event Pump: this uses a CFRunLoop object to dispatch events. It gives better rendering performance than the NSTimer approach and also allows you to set the amount of time the OS should spend processing touch and accelerometer events. This option must be used with care since touch and accelerometer events will be lost if there is not enough processor time available to handle them.
The different fallback loop types can be selected by changing defines in the AppController.mm file. The significant lines are the following:-
#define FALLBACK_LOOP_TYPE NSTIMER_BASED_LOOP #define FALLBACK_LOOP_TYPE THREAD_BASED_LOOP #define FALLBACK_LOOP_TYPE EVENT_PUMP_BASED_LOOP
The file should have all but one of these lines commented out. The uncommented line selects the rendering loop method that will be used by the application.
If you want to prioritize rendering over input processing with the NSTimer approach you should locate and change the line
#define kThrottleFPS 2.0
...in AppController.mm. Increasing this number will give higher priority to rendering. The result of changing this value varies among applications, so it is best to try it for yourself and see what happens in your specific case.
If you use the Event Pump rendering loop then you need to tweak the kMillisecondsPerFrameToProcessEvents constant precisely to achieve the desired responsiveness. The kMillisecondsPerFrameToProcessEvents constant allows you to specify exactly how much time (in milliseconds) you will allow the OS to process events. If you allocate insufficient time for this task then touch or accelerometer events might be lost, and while the application will be fast, it will also be less responsive.
To specify the amount of time (in milliseconds) that the OS will spend processing events, locate and change the line
#define kMillisecondsPerFrameToProcessEvents 7.0
...in AppController.mm.
Tuning Accelerometer Processing Frequency
If accelerometer input is processed too frequently then the overall performance of your game may suffer as a result. By default, a Unity iOS application will sample the accelerometer 60 times per second. You may see some performance benefit by reducing the accelerometer sampling frequency and it can even be set to zero for games that don't use accelerometer input. You can change the accelerometer frequency from the Other Settings panel in the iOS Player Settings.
Page last updated: 2011-11-08iphone-playerSizeOptimization
The two main ways of reducing the size of the player are by changing the Active Build Configuration within Xcode and by changing the Stripping Level within Unity.
Building in Release Mode
You can choose between the Debug and Release options on the Active Build Configuration drop-down menu in Xcode. Building as Release instead of Debug can reduce the size of the built player by as much as 2-3MB, depending on the game.

The Active Build Configuration drop-down
In Release mode, the player will be built without any debug information, so if your game crashes or has other problems there will be no stack trace information available for output. This is fine for deploying a finished game but you will probably want to use Debug mode during development.
iOS Stripping Level (Advanced License feature)
The size optimizations activated by stripping work in the following way:-
- Strip assemblies level: the scripts' bytecode is analyzed so that classes and methods that are not referenced from the scripts can be removed from the DLLs and thereby excluded from the AOT compilation phase. This optimization reduces the size of the main binary and accompanying DLLs and is safe as long as no reflection is used.
- Strip ByteCode level: any .NET DLLs (stored in the Data folder) are stripped down to metadata only. This is possible because all the code is already precompiled during the AOT phase and linked into the main binary.
- Use micro mscorlib level: a special, smaller version of mscorlib is used. Some components are removed from this library, for example, Security, Reflection.Emit, Remoting, non Gregorian calendars, etc. Also, interdependencies between internal components are minimized. This optimization reduces the main binary and mscorlib.dll size but it is not compatible with some System and System.Xml assembly classes, so use it with care.
These levels are cumulative, so level 3 optimization implicitly includes levels 2 and 1, while level 2 optimization includes level 1.
Note: Micro mscorlib is a heavily stripped-down version of the core library. Only those items that are required by the Mono runtime in Unity remain. Best practice for using micro mscorlib is not to use any classes or other features of .NET that are not required by your application. GUIDs are a good example of something you could omit; they can easily be replaced with custom made pseudo GUIDs and doing this would result in better performance and app size.
Tips
How to Deal with Stripping when Using Reflection
Stripping depends highly on static code analysis and sometimes this can't be done effectively, especially when dynamic features like reflection are used. In such cases, it is necessary to give some hints as to which classes shouldn't be touched. Unity supports a per-project custom stripping blacklist. Using the blacklist is a simple matter of creating a link.xml file and placing it into the Assets folder. An example of the contents of the link.xml file follows. Classes marked for preservation will not be affected by stripping:-
<linker>
<assembly fullname="System.Web.Services">
<type fullname="System.Web.Services.Protocols.SoapTypeStubInfo" preserve="all"/>
<type fullname="System.Web.Services.Configuration.WebServicesConfigurationSectionHandler" preserve="all"/>
</assembly>
<assembly fullname="System">
<type fullname="System.Net.Configuration.WebRequestModuleHandler" preserve="all"/>
<type fullname="System.Net.HttpRequestCreator" preserve="all"/>
<type fullname="System.Net.FileWebRequestCreator" preserve="all"/>
</assembly>
</linker>
Note: it can sometimes be difficult to determine which classes are getting stripped in error even though the application requires them. You can often get useful information about this by running the stripped application on the simulator and checking the Xcode console for error messages.
Simple Checklist for Making Your Distribution as Small as Possible
- Minimize your assets: enable PVRTC compression for textures and reduce their resolution as far as possible. Also, minimize the number of uncompressed sounds. There are some additional tips for file size reduction here.
- Set the iOS Stripping Level to Use micro mscorlib.
- Set the script call optimization level to Fast but no exceptions.
- Don't use anything that lives in System.dll or System.Xml.dll in your code. These libraries are not compatible with micro mscorlib.
- Remove unnecessary code dependencies.
- Set the API Compatibility Level to .Net 2.0 subset. Note that .Net 2.0 subset has limited compatibility with other libraries.
- Set the Target Platform to armv6 (OpenGL ES1.1).
- Don't use JS Arrays.
- Avoid generic containers in combination with value types, including structs.
Can I produce apps of less than 20 megabytes with Unity?
Yes. An empty project would take about 13 MB in the AppStore if all the size optimizations were turned off. This gives you a budget of about 7MB for compressed assets in your game. If you own an Advanced License (and therefore have access to the stripping option), the empty scene with just the main camera can be reduced to about 6 MB in the AppStore (zipped and DRM attached) and you will have about 14 MB available for compressed assets.
Why did my app increase in size after being released to the AppStore?
When they publish your app, Apple first encrypt the binary file and then compresses it via zip. Most often Apple's DRM increases the binary size by about 4 MB or so. As a general rule, you should expect the final size to be approximately equal to the size of the zip-compressed archive of all files (except the executable) plus the size of the uncompressed executable file.
Page last updated: 2011-11-07iphone-accountsetup
There are some steps you must follow before you can build and run any code (including Unity-built games) on your iOs device. These steps are prerequisite to publishing your own iOS games.
1. Apply to Apple to Become a Registered iPhone/iPad Developer
You do this through Apple's website: http://developer.apple.com/iphone/program/
2. Upgrade your Operating System and iTunes Installation
Please note that these are Apple's requirements as part of using the iPhone SDK, but the requirements can change from time to time.
3. Download the iPhone SDK
Download the latest iOS SDK from the iOS dev center and install it. Do not download the beta version of the SDK - you should use only the latest shipping version. Note that downloading and installing the iPhone SDK will also install XCode.
4. Get Your Device Identifier
Connect your iOS device to the Mac with the USB cable and launch XCode. XCode will detect your phone as a new device and you should register it with the "Use For Development" button. This will usually open the Organizer window but if it doesn't then go to Window->Organizer. You should see your iOS device) in the devices list on the left; select it and note your device's identifier code (which is about 40 characters long).
5. Add Your Device
Log in to the iPhone developer center and enter the program portal (button on the right). Go to the Devices page via the link on left side and then click the Add Device button on the right. Enter a name for your device (alphanumeric characters only) and your device's identifier code (noted in step 5 above). Click the Submit button when done.
6. Create a Certificate
From the iPhone Developer Program Portal, click the Certificates link on the left side and follow the instructions listed under How-To...
7. Download and Install the WWDR Intermediate Certificate
The download link is in the same "Certificates" section (just above the "Important Notice" rubric) as WWDR Intermediate Certificate. Once downloaded, double-click the certificate file to install it.
8. Create a Provisioning File
Provisioning profiles are a bit complex, and need to be set up according to the way you have organized your team. It is difficult to give general instructions for provisioning, so we recommend that you look at the Provisioning How-to section on the Apple Developer website.
Page last updated: 2011-11-08iphone-unsupported
Graphics
- DXT texture compression is not supported; use PVRTC formats instead. Please see the Texture2D Component page for more information.
- Rectangular textures can not be compressed to PVRTC formats.
- Movie Textures are not supported; use a full-screen streaming playback instead. Please see the Movie playback page for more information.
- Open GL ES2.0 is not supported on iPhone, iPhone 3G, iPod Touch 1st and iPod Touch 2nd Generation hardware.
Audio
- Ogg audio compression is not supported. Ogg audio will be automatically converted to MP3 when you switch to iOS platform in the Editor. Please see the AudioClip Component page for more information about audio support in Unity iOS.
Scripting
- OnMouseDown, OnMouseEnter, OnMouseOver, OnMouseExit, OnMouseDown, OnMouseUp, OnMouseDrag events are not supported.
- Dynamic features like Duck Typing are not supported. Use
#pragma strictfor your scripts to force the compiler to report dynamic features as errors. - Video streaming via WWW class is not supported.
- FTP support by WWW class is limited.
Features Restricted to Unity iOS Advanced License
- Static batching is only supported in Unity iOS Advanced.
- Video playback is only supported in Unity iOS Advanced.
- Splash-screen customization is only supported in Unity iOS Advanced.
- AssetBundles are only supported in Unity iOS Advanced.
- Code stripping is only supported in Unity iOS Advanced.
- .NET sockets are only supported in Unity iOS Advanced.
Note: it is recommended to minimize your references to external libraries, because 1 MB of .NET CIL code roughly translates to 3-4 MB of ARM code. For example, if your application references System.dll and System.Xml.dll then it means additional 6 MB of ARM code if stripping is not used. At some point application will reach limit when linker will have troubles linking the code. If you care a lot about application size you might find C# a more suitable language for your code as is has less dependencies than JavaScript.
Page last updated: 2011-10-29iphone-Plugins
This page describes Native Code Plugins for the iOS platform.
Building an Application with a Native Plugin for iOS
- Define your extern method in the C# file as follows:
[DllImport ("__Internal")] private static extern float FooPluginFunction (); - Set the editor to the iOS build target
- Add your native code source files to the generated XCode project's "Classes" folder (this folder is not overwritten when the project is updated, but don't forget to backup your native code).
If you are using C++ (.cpp) or Objective-C (.mm) to implement the plugin you must ensure the functions are declared with C linkage to avoid name mangling issues.
extern "C" {
float FooPluginFunction ();
}
Using Your Plugin from C#
iOS native plugins can be called only when deployed on the actual device, so it is recommended to wrap all native code methods with an additional C# code layer. This code should check Application.platform and call native methods only when the app is running on the device; dummy values can be returned when the app runs in the Editor. See the Bonjour browser sample application for an example.
Calling C# / JavaScript back from native code
Unity iOS supports limited native-to-managed callback functionality via UnitySendMessage:UnitySendMessage("GameObjectName1", "MethodName1", "Message to send");
This function has three parameters : the name of the target GameObject, the script method to call on that object and the message string to pass to the called method.
Known limitations:
- Only script methods that correspond to the following signature can be called from native code:
function MethodName(message:string) - Calls to UnitySendMessage are asynchronous and have a delay of one frame.
Automated plugin integration
Unity iOS supports automated plugin integration in a limited way. All files with extensions .a,.m,.mm,.c,.cpp located in the Assets/Plugins/iOS folder will be merged into the generated Xcode project automatically. However, merging is done by symlinking files from Assets/Plugins/iOS to the final destination, which might affect some workflows. The .h files are not included in the Xcode project tree, but they appear on the destination file system, thus allowing compilation of .m/.mm/.c/.cpp files.
Note: subfolders are currently not supported.
iOS Tips
- Managed-to-unmanaged calls are quite processor intensive on iOS. Try to avoid calling multiple native methods per frame.
- As mentioned above, wrap your native methods with an additional C# layer that calls native code on the device and returns dummy values in the Editor.
- String values returned from a native method should be UTF-8 encoded and allocated on the heap. Mono marshaling calls are free for strings like this.
- As mentioned above, the XCode project's "Classes" folder is a good place to store your native code because it is not overwritten when the project is updated.
- Another good place for storing native code is the Assets folder or one of its subfolders. Just add references from the XCode project to the native code files: right click on the "Classes" subfolder and choose "Add->Existing files...".
Examples
Bonjour Browser Sample
A simple example of the use of a native code plugin can be found here
This sample demonstrates how objective-C code can be invoked from a Unity iOS application. This application implements a very simple Bonjour client. The application consists of a Unity iOS project (Plugins/Bonjour.cs is the C# interface to the native code, while BonjourTest.js is the JS script that implements the application logic) and native code (Assets/Code) that should be added to the built XCode project.
Page last updated: 2011-11-01iphone-Downloadable-Content
This chapter does not aim to cover how to integrate your game with Apple's "StoreKit" API. It is assumed that you already have integration with "StoreKit" via a native code plugin.
Apple's "StoreKit" documentation defines four kinds of Products that could be sold via the "In App Purchase" process:
- Content
- Functionality
- Services
- Subscriptions
This chapter covers the first case only and focuses mainly on the downloadable content concept. AssetBundles are ideal candidates for use as downloadable content, and two scenarios will be covered:
- How to export asset bundles for use on iOS
- How download and cache them on iOS
Exporting your assets for use on iOS
Having separate projects for downloadable content can be a good idea, allowing better separation between content that comes with your main application and content that is downloaded later.
Please note: Any game scripts included in downloadable content must also be present in the main executable.
- Create an Editor folder inside the Project View.
- Create an ExportBundle.js script there and place the following code inside:
@MenuItem ("Assets/Build AssetBundle From Selection - Track dependencies") static function ExportBundle(){ var str : String = EditorUtility.SaveFilePanel("Save Bundle...", Application.dataPath, Selection.activeObject.name, "assetbundle"); if (str.Length != 0){ BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, str, BuildAssetBundleOptions.CompleteAssets, BuildTarget.iPhone); } } - Design your objects that need to be downloadable as prefabs
- Select a prefab that needs to be exported and mouse right click

If the first two steps were done properly, then the Build AssetBundle From Selection - Track dependencies context menu item should be visible. - Select it if you want to include everything that this asset uses.
- A save dialog will be shown, enter the desired asset bundle file name. An .assetbundle extension will be added automatically. The Unity iOS runtime accepts only asset bundles built with the same version of the Unity editor as the final application. Read BuildPipeline.BuildAssetBundle for details.
Downloading your assets on iOS
- Asset bundles can be downloaded and loaded by using the WWW class and instantiating a main asset. Code sample:
var download : WWW; var url = "http://somehost/somepath/someassetbundle.assetbundle"; download = new WWW (url); yield download; assetBundle = download.assetBundle; if (assetBundle != null) { // Alternatively you can also load an asset by name (assetBundle.Load("my asset name")) var go : Object = assetBundle.mainAsset; if (go != null) instanced = Instantiate(go); else Debug.Log("Couldnt load resource"); } else { Debug.Log("Couldnt load resource"); } - You can save required files to a Documents folder next to your game's Data folder.
public static string GetiPhoneDocumentsPath () { // Your game has read+write access to /var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/Documents // Application.dataPath returns // /var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/myappname.app/Data // Strip "/Data" from path string path = Application.dataPath.Substring (0, Application.dataPath.Length - 5); // Strip application name path = path.Substring(0, path.LastIndexOf('/')); return path + "/Documents"; } - Cache a downloaded asset bundle using the .NET file API and for reuse it in the future by loading it via WWW class and file:///pathtoyourapplication/Documents/savedassetbundle.assetbundle. Sample code for caching:
// Code designed for caching on iPhone, cachedAssetBundle path must be different when running in Editor // See code snippet above for getting the path to your Documents folder private var cachedAssetBundle : String = "path to your Documents folder" + "/savedassetbundle.assetbundle"; var cache = new System.IO.FileStream(cachedAssetBundle, System.IO.FileMode.Create); cache.Write(download.bytes, 0, download.bytes.Length); cache.Close(); Debug.Log("Cache saved: " + cachedAssetBundle);
MobileCustomizeSplashScreen
iOS
Under iOS Basic, a default splash screen will be displayed while your game loads, oriented according to the Default Screen Orientation option in the Player Settings.
Users with an iOS Pro license can use any texture in the project as a splash screen. The size of the texture depends on the target device (320x480 pixels for 1-3rd gen devices, 1024x768 for iPad, 640x960 for 4th gen devices) and supplied textures will be scaled to fit if necessary. You can set the splash screen textures using the iOS Player Settings.
Android
Under Android Basic, a default splash screen will be displayed while your game loads, oriented according to the Default Screen Orientation option in the Player Settings.
Android Pro users can use any texture in the project as a splash screen. You can set the texture from the Splash Image section of the Android Player Settings. You should also select the Splash scaling method from the following options:-
- Center (only scale down) will draw your image at its natural size unless it is too large, in which case it will be scaled down to fit.
- Scale to fit (letter-boxed) will draw your image so that the longer dimension fits the screen size exactly. Empty space around the sides in the shorter dimension will be filled in black.
- Scale to fill (cropped) will scale your image so that the shorter dimension fits the screen size exactly. The image will be cropped in the longer dimension.
iphone-troubleshooting
This section addresses common problems that can arise when using Unity. Each platform is dealt with separately below.
Desktop
In MonoDevelop, the Debug button is greyed out!
- This means that MonoDevelop was unable to find the Unity executable. In the MonoDevelop preferences, go to the Unity/Debugger section and then browse to where your Unity executable is located.
Is there a way to get rid of the welcome page in MonoDevelop?
- Yes. In the MonoDevelop preferences, go to the Visual Style section, and uncheck "Load welcome page on startup".
Geforce 7300GT on OSX 10.6.4
- Deferred rendering is disabled because materials are not displayed correctly for Geforce 7300GT on OX 10.6.4; This happens because of buggy video drivers.
On Windows x64, Unity crashes when my script throws a NullReferenceException
- Please apply Windows Hotfix #976038.
Graphics
Slow framerate and/or visual artifacts.
- This may occur if your video card drivers are not up to date. Make sure you have the latest official drivers from your card vendor.
Shadows
I see no shadows at all!
- Shadows are a Unity Pro only feature, so without Unity Pro you won't get shadows. Simpler shadow methods, like using a Projector, are still possible, of course.
- Shadows also require certain graphics hardware support. See Shadows page for details.
- Check if shadows are not completely disabled in Quality Settings.
- Shadows are currently not supported for Android and iOS mobile platforms.
Some of my objects do not cast or receive shadows
An object's Renderer must have Receive Shadows enabled for shadows to be rendered onto it. Also, an object must have Cast Shadows enabled in order to cast shadows on other objects (both are on by default).
Only opaque objects cast and receive shadows. This means that objects using the built-in Transparent or Particle shaders will not cast shadows. In most cases it is possible to use Transparent Cutout shaders for objects like fences, vegetation, etc. If you use custom written Shaders, they have to be pixel-lit and use the Geometry render queue. Objects using VertexLit shaders do not receive shadows but are able to cast them.
Only Pixel lights cast shadows. If you want to make sure that a light always casts shadows no matter how many other lights are in the scene, then you can set it to Force Pixel render mode (see the Light reference page).
iOS
Troubleshooting on iOS devices
There are some situations with iOS where your game can work perfectly in the Unity editor but then doesn't work or maybe doesn't even start on the actual device. The problems are often related to code or content quality. This section describes the most common scenarios.
Xcode 3.2.x fails to build the application with the error "libiPhone-lib.a, missing required architecture i386 in file Undefined symbols: "Register_UnityEngine_Input_GetMouseButtonDown()", referenced from: RegisterAllStrippedInternalCalls() in RegisterMonoModules.o
This build error usually happens when a non-simulator SDK is selected in the Player Settings but a simulator SDK is selected in Xcode. The SDK settings in Unity and Xcode must be consistent.
Xcode 4.x fails to build the application with the error "No architectures to compile for (ARCHS=armv6, VALID_ARCHS=i386)."
Currently Unity has limited support for Xcode 4.x and some manual effort is required to build the final application. The Build & Run command will open the generated Xcode project but it won't select the appropriate build target and target device. If you are building for a test on the device you should select the "Unity-iPhone" build target and an iOS device connected to your Mac. If you are building for testing on the simulator (which requires the right SDK selection as described above) then you should select the "Unity-iPhone-simulator" target and the appropriate simulator device.
The game stops responding after a while. Xcode shows "interrupted" in the status bar.
There are a number of reasons why this may happen. Typical causes include:
- Scripting errors such as using uninitialized variables, etc.
- Using 3rd party Thumb compiled native libraries. Such libraries trigger a known problem in the iOS SDK linker and might cause random crashes.
- Using generic types with value types as parameters (eg, List<int>, List<SomeStruct>, List<SomeEnum>, etc) for serializable script properties.
- Using reflection when managed code stripping is enabled.
- Errors in the native plugin interface (the managed code method signature does not match the native code function signature).
Information from the XCode Debugger console can often help detect these problems (Xcode menu: Run > Console).
The Xcode console shows "Program received signal: “SIGBUS” or EXC_BAD_ACCESS error.
This message typically appears on iOS devices when your application receives a NullReferenceException. There two ways to figure out where the fault happened:
Managed stack traces
Since version 3.4 Unity includes software-based handling of the NullReferenceException. The AOT compiler includes quick checks for null references each time a method or variable is accessed on an object. This feature affects script performance which is why it is enabled only for development builds (for basic license users it is enough to enable the "development build" option in the Build Settings dialog, while iOS pro license users additionally need to enable the "script debugging" option). If everything was done right and the fault actually is occurring in .NET code then you won't see EXC_BAD_ACCESS anymore. Instead, the .NET exception text will be printed in the Xcode console (or else your code will just handle it in a "catch" statement). Typical output might be:
Unhandled Exception: System.NullReferenceException: A null value was found where an object instance was required. at DayController+$handleTimeOfDay$121+$.MoveNext () [0x0035a] in DayController.js:122
This indicates that the fault happened in the handleTimeOfDay method of the DayController class, which works as a coroutine. Also if it is script code then you will generally be told the exact line number (eg, "DayController.js:122"). The offending line might be something like the following:
Instantiate(_imgwww.assetBundle.mainAsset);
This might happen if, say, the script accesses an asset bundle without first checking that it was downloaded correctly.
Native stack traces
Native stack traces are a much more powerful tool for fault investigation but using them requires some expertise. Also, you generally can't continue after these native (hardware memory access) faults happen. To get a native stack trace, type thread apply all bt into the Xcode Debugger Console. Carefully inspect the printed stack traces - they may contain hints about where the error occurred. You might see something like:
... Thread 1 (thread 11523): #0 0x006267d0 in OptionsMenu_Start () #1 0x002e4160 in wrapper_runtime_invoke_object_runtime_invoke_void__this___object_intptr_intptr_intptr () #2 0x00a1dd64 in mono_jit_runtime_invoke (method=0x18b63bc, obj=0x5d10cb0, params=0x0, exc=0x2fffdd34) at /Users/mantasp/work/unity/unity-mono/External/Mono/mono/mono/mini/mini.c:4487 #3 0x0088481c in MonoBehaviour::InvokeMethodOrCoroutineChecked () ...
First of all you should find the stack trace for "Thread 1", which is the main thread. The very first lines of the stack trace will point to the place where the error occurred. In this example, the trace indicates that the NullReferenceException happened inside the "OptionsMenu" script's "Start" method. Looking carefully at this method implementation would reveal the cause of the problem. Typically, NullReferenceExceptions happen inside the Start method when incorrect assumptions are made about initialization order. In some cases only a partial stack trace is seen on the Debugger Console:
Thread 1 (thread 11523): #0 0x0062564c in start ()
This indicates that native symbols were stripped during the Release build of the application. The full stack trace can be obtained with the following procedure:
- Select Debug configuration in the Xcode project.
- Clean all targets.
- Build and run.
- Get stack traces again as described above.
EXC_BAD_ACCESS starts occurring when an external library is linked to the Unity iOS application.
This usually happens when an external library is compiled with the ARM Thumb instruction set. Currently such libraries are not compatible with Unity. The problem can be solved easily by recompiling the library without Thumb instructions. You can do this for the library's Xcode project with the following steps:
- in Xcode, select "Project" > "Edit active target" from the menu
- in the "Target Info" dialog, select "Configuration: All Configurations"
- in the search field enter : "thumb"
- a "Compile for Thumb" setting will appear; uncheck it and rebuild the library.
If the library source is not available you should ask the supplier for a non-thumb version of the library.
The Xcode console shows "WARNING -> applicationDidReceiveMemoryWarning()" and the application crashes immediately afterwards
(Sometimes you might see a message like Program received signal: “0”.) This warning message is often not fatal and merely indicates that iOS is low on memory and is asking applications to free up some memory. Typically, background processes like Mail will free some memory and your application can continue to run. However, if your application continues to use memory or ask for more, the OS will eventually start killing applications and yours could be one of them. Apple does not document what memory usage is safe, but empirical observations show that applications using less than 25 MB of RAM (or 80 MB for 3rd generation devices) do not have any memory usage problems. Applications using 40 MB of RAM may have memory problems on 1-2nd generation devices and may require a device restart to run properly. The main metric you should rely on is how much RAM your application uses. Your application memory usage consists of three major components:
- application code (the OS needs to load and keep your application code in RAM)
- native heap (used by the engine to store its state, your assets, etc. in RAM)
- managed heap (used by your Mono runtime to keep C# or JavaScript objects)
Your application memory usage can be tracked by two Xcode Instruments tools: Activity Monitor and Object Allocations. You can start one or the other from the Xcode Run menu: Run > Start with Performance Tool > Activity Monitor and Run > Start with Performance Tool > Object Allocations. The first tool shows all process statistics including Real memory which can be regarded as the total amount of RAM used by your application.
Note: The internal profiler shows only the heap allocated by .NET scripts. Total memory usage can be determined via Xcode Instruments as shown above. This figure includes the application binary (which will be loaded into memory and uses about 7 MB), some standard framework buffers, Unity engine internal state buffers, the .NET runtime heap (number printed by internal profiler), and some other miscellaneous stuff.
The other tool displays all allocations made by your application and includes both native heap and managed heap statistics (don't forget to check the Created and still living box to get the current state of the application). The important statistic is the Net bytes value.

To keep memory usage low:
- Reduce the application binary size by using the strongest iOS stripping options (Advanced license feature), and avoid unnecessary dependencies on different .NET libraries. See the player settings and player size optimization manual pages for further details.
- Reduce the size of your content. Use PVRTC compression for textures and use low poly models. See the manual page about reducing file size for more information.
- Don't allocate more memory than necessary in your scripts. Track mono heap size and usage with the internal profiler
- Note: with Unity 3.0, the scene loading implementation has changed significantly and now all scene assets are preloaded. This results in fewer hiccups when instantiating game objects. If you need more fine-grained control of asset loading and unloading during gameplay, you should use Resources.Load and Object.Destroy.
Querying the OS about the amount of free memory may seem like a good idea to evaluate how well your application is performing. However, the free memory statistic is likely to be unreliable since the OS uses a lot of dynamic buffers and caches. The only reliable approach is to keep track of memory consumption for your application and use that as the main metric. Pay attention to how the graphs from the tools described above change over time, especially after loading new levels.
The game runs correctly when launched from Xcode but crashes while loading the first level when launched manually on the device.
There could be several reasons for this. You need to inspect the device logs to get more details. Connect the device to your Mac, launch Xcode and select Window > Organizer from the menu. Select your device in the Organizer's left toolbar, then click on the "Console" tab and review the latest messages carefully. Additionally, you may need to investigate crash reports. You can find out how to obtain crash reports here: http://developer.apple.com/iphone/library/technotes/tn2008/tn2151.html.
The Xcode Organizer console contains the message "killed by SpringBoard".
There is a poorly-documented time limit for an iOS application to render its first frames and process input. If your application exceeds this limit, it will be killed by SpringBoard. This may happen in an application with a first scene which is too large, for example. To avoid this problem, it is advisable to create a small initial scene which just displays a splash screen, waits a frame or two with yield and then starts loading the real scene. This can be done with code as simple as the following:
function Start () {
yield;
Application.LoadLevel("Test");
}
Type.GetProperty() / Type.GetValue() cause crashes on the device
Currently Type.GetProperty() and Type.GetValue() are supported only for the .NET 2.0 Subset profile. You can select the .NET API compatibility level in the Player Settings.
Note: Type.GetProperty() and Type.GetValue() might be incompatible with managed code stripping and might need to be excluded (you can supply a custom non-strippable type list during the stripping process to accomplish this). For further details, see the iOS player size optimization guide.
The game crashes with the error message "ExecutionEngineException: Attempting to JIT compile method 'SometType`1<SomeValueType>:.ctor ()' while running with --aot-only."
The Mono .NET implementation for iOS is based on AOT (ahead of time compilation to native code) technology, which has its limitations. It compiles only those generic type methods (where a value type is used as a generic parameter) which are explicitly used by other code. When such methods are used only via reflection or from native code (ie, the serialization system) then they get skipped during AOT compilation. The AOT compiler can be hinted to include code by adding a dummy method somewhere in the script code. This can refer to the missing methods and so get them compiled ahead of time.
void _unusedMethod()
{
var tmp = new SomeType<SomeValueType>();
}
Note: value types are basic types, enums and structs.
Various crashes occur on the device when a combination of System.Security.Cryptography and managed code stripping is used
.NET Cryptography services rely heavily on reflection and so are not compatible with managed code stripping since this involves static code analysis. Sometimes the easiest solution to the crashes is to exclude the whole System.Security.Crypography namespace from the stripping process.
The stripping process can be customized by adding a custom link.xml file to the Assets folder of your Unity project. This specifies which types and namespaces should be excluded from stripping. Further details can be found in the iOS player size optimization guide.
link.xml
<linker>
<assembly fullname="mscorlib">
<namespace fullname="System.Security.Cryptography" preserve="all"/>
</assembly>
</linker>
"Ran out of trampolines of type 1/2" runtime error
This error usually happens if you use lots of recursive generics. You can hint to the AOT compiler to allocate more trampolines of type 1 or type 2. Additional AOT compiler command line options can be specified in the "Other Settings" section of the Player Settings. For type 1 trampolines, specify nrgctx-trampolines=ABCD, where ABCD is the number of new trampolines required (i.e. 4096). For type 2 trampolines specify nimt-trampolines=ABCD.
"PlayerLoop called recursively!" error occurs when using Cocoa via a native function called from a script
Some operations with the UI will result in iOS redrawing the window immediately (the most common example is adding a UIView with a UIViewController to the main UIWindow). If you call a native function from a script, it will happen inside Unity's PlayerLoop, resulting in PlayerLoop being called recursively. In such cases, you should consider using the performSelectorOnMainThread method with waitUntilDone set to false. It will inform iOS to schedule the operation to run between Unity's PlayerLoop calls.
UIScrollView stops scrolling sometimes or scrolls wrong
It is difficult to get CADisplayLink and UIScrollView to work together. The simplest solution is to set
#define USE_DISPLAY_LINK_IF_AVAILABLE 0
in AppController.mm
Profiler or Debugger unable to see game running on iOS device
- Check that you have built a Development build, and ticked the "Enable Script Debugging" and "Autoconnect profiler" boxes (as appropriate).
- The application running on the device will make a multicast broadcast to 225.0.0.222 on UDP port 54997. Check that your network settings allow this traffic. Then, the profiler will make a connection to the remote device on a port in the range 55000 - 55511 to fetch profiler data from the device. These ports will need to be open for UDP access.
Android
Troubleshooting Android development
Unity fails to install your application to your device
- Verify that your computer can actually see and communicate with the device. See the Publishing Builds page for further details.
- Check the error message in the Unity console. This will often help diagnose the problem.
If you get an error saying "Unable to install APK, protocol failure" during a build then this indicates that the device is connected to a low-power USB port (perhaps a port on a keyboard or other peripheral). If this happens, try connecting the device to a USB port on the computer itself.
Your application crashes immediately after launch.
- Ensure that you are not trying to use NativeActivity with devices that do not support it.
- Try removing any native plugins you have.
- Try disabling stripping.
- Use adb logcat to get the crash report from your device.
Building DEX Failed
This an error which will produce a message like the following:-
Building DEX Failed! G:\Unity\JavaPluginSample\Temp/StagingArea> java -Xmx1024M -Djava.ext.dirs="G:/AndroidSDK/android-sdk_r09-windows\platform-tools/lib/" -jar "G:/AndroidSDK/android-sdk_r09-windows\platform-tools/lib/dx.jar" --dex --verbose --output=bin/classes.dex bin/classes.jar plugins Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine.
This is usually caused by having the wrong version of Java installed on your machine. Updating your Java installation to the latest version will generally solve this issue.
The game crashes after a couple of seconds when playing video
Make sure Settings->Developer Options->Don't keep activities isn't enabled on the phone. The video player is its own activity and therefore the regular game activity will be destroyed if the video player is activated.
My game quits when I press the sleep button
Change the <activity> tag in the AndroidManifest.xml to contain <android:configChanges> tag as described here.
An example activity tag might look something like this:-
<activity android:name=".AdMobTestActivity"
android:label="@string/app_name"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
iphone-bugreporting
Before submitting a bug report, please check the iOS Troubleshooting page, where you will find solutions to common crashes and other problems.
If your application crashes in the Xcode debugger then you can add valuable information to your bug report as follows:-
- Click Continue (Run->Continue) twice
- Open the debugger console (Run->Console) and enter (in the console): thread apply all bt
- Copy all console output and send it together with your bugreport.
If your application crashes on the iOS device then you should retrieve the crash report as described here on Apple's website. Please attach the crash report, your built application and console log to your bug report before submitting.
Page last updated: 2011-11-08android-GettingStarted
Building games for a device running Android OS requires an approach similar to that for iOS development. However, the hardware is not completely standardized across all devices, and this raises issues that don't occur in iOS development. There are some feature differences in the Android version of Unity just as there are with the iOS version.
Setting up your Android Developer environment
You will need to have your Android developer environment set up before you can test your Unity games on the device. This involves downloading and installing the Android SDK with the different Android plaforms and adding your physical device to your system (this is done a bit differently depending on whether you are developing on Windows or Mac). This setup process is explained on the Android developer website, and there may be additional information provided by the manufacturer of your device. Since this is a complex process, we've provided a basic outline of the tasks that must be completed before you can run code on your Android device or in the Android emulator. However, the best thing to do is follow the instructions step-by-step from the Android developer portal.
Access Android Functionality
Unity Android provides scripting APIs to access various input data and settings. You can find out more about the available classes on the Android scripting page.
Exposing Native C, C++ or Java Code to Scripts
Unity Android allows you to call custom functions written in C/C++ directly from C# scripts (Java functions can be called indirectly). To find out how to make functions from native code accessible from Unity, visit the plugins page.
Occlusion Culling
Unity includes support for occlusion culling which is a particularly valuable optimization on mobile platforms. More information can be found on the occlusion culling page.
Splash Screen Customization
The splash screen displayed while the game launches can be customized - see this page for further details.
Troubleshooting and Bug Reports
There are many reasons why your application may crash or fail to work as you expected. Our Android troubleshooting guide will help you get to the bottom of bugs as quickly as possible. If, after consulting the guide, you suspect the problem is internal to Unity then you should file a bug report - see this page for details on how to do this.
How Unity Android Differs from Desktop Unity
Strongly Typed JavaScript
For performance reasons, dynamic typing in JavaScript is always turned off in Unity Android, as if #pragma strict were applied automatically to all scripts. This is important to know if you start with a project originally developed for the desktop platforms since you may find you get unexpected compile errors when switching to Android; dynamic typing is the first thing to investigate. These errors are usually easy to fix if you make sure all variables are explicitly typed or use type inference on initialization.
ETC as Recommended Texture Compression
Although Unity Android does support DXT/PVRTC/ATC textures, Unity will decompress the textures into RGB(A) format at runtime if those compression methods are not supported by the particular device in use. This could have an impact on the GPU rendering speed and it is recommended to use the ETC format instead. ETC is the de facto standard compression format on Android, and should be supported on all post 2.0 devices. However, ETC does not support an alpha channel and RGBA 16-bit will sometimes be the best trade-off between size, quality and rendering speed where alpha is required.
It is also possible to create separate android distribution archives (.apk) for each of the DXT/PVRTC/ATC formats, and let the Android Market's filtering system select the correct archives for different devices (see Publishing Builds for Android).
Movie Playback
Movie textures are not supported on Android, but a full-screen streaming playback is provided via scripting functions. To learn about supported file formats and scripting API, consult the movie page or the Android supported media formats page.
Further Reading
- Android SDK Setup
- Android Remote
- Trouble Shooting
- Reporting crash bugs under Android
- Features currently not supported by Unity Android
- Player Settings
- Android Scripting
- Building Plugins for Android
- Customizing the Splash screen of Your Mobile Application
- Devices That we Have Tested On
android-sdksetup
There are some steps you must follow before you can build and run any code on your Android device. This is true regardless of whether you use Unity or write Android applications from scratch.
1. Download the Android SDK
Go to the Android Developer SDK webpage. Download and unpack the latest Android SDK.
2. Installing the Android SDK
Follow the instructions under Installing the SDK (although you can freely skip the optional parts relating to Eclipse). In step 4 of Installing the SDK be sure to add at least one Android platform with API level equal to or higher than 9 (Platform 2.3 or greater), the Platform Tools, and the USB drivers if you're using Windows.
3. Get the device recognized by your system
This can be tricky, especially under Windows based systems where drivers tend to be a problem. Also, your device may come with additional information or specific drivers from the manufacturer.
- For Windows: If the Android device is automatically recognized by the system you still might need to update the drivers with the ones that came with the Android SDK. This is done through the Windows Device Manager.
- If the device is not recognized automatically use the drivers from the Android SDK, or any specific drivers provided by the manufacturer.Additional info can be found here: USB Drivers for Windows
- For Mac: If you're developing on Mac OSX then no additional drivers are usually required.
Note: Don't forget to turn on "USB Debugging" on your device. You can do this from the home screen: press MENU, select Applications > Development, then enable USB debugging.
If you are unsure whether your device is propperly installed on your system, please read the trouble-shooting page for details.
4. Add the Android SDK path to Unity
The first time you build a project for Android (or if Unity later fails to locate the SDK) you will be asked to locate the folder where you installed the Android SDK (you should select the root folder of the SDK installation). The location of the Android SDK can also be changed in the editor by accessing Edit then Preferences.
Page last updated: 2011-11-22android-remote
Android Remote is a Android application that makes your device act as a remote control for the project in Unity. This is useful for rapid development when you don't want to compile and deploy your project to device for each change.
How to use Android remote
To use Android Remote, you should firstly make sure that you have the latest Android SDK installed (this is necessary to set up port-forwarding on the device). Then, connect the device to your computer with a USB cable and launch the Android Remote app. When you press Play in the Unity editor, the device will act as a remote control and will pass accelerometer and touch input events to the running game.
Page last updated: 2011-11-23android-troubleshooting
This section addresses common problems that can arise when using Unity. Each platform is dealt with separately below.
Desktop
In MonoDevelop, the Debug button is greyed out!
- This means that MonoDevelop was unable to find the Unity executable. In the MonoDevelop preferences, go to the Unity/Debugger section and then browse to where your Unity executable is located.
Is there a way to get rid of the welcome page in MonoDevelop?
- Yes. In the MonoDevelop preferences, go to the Visual Style section, and uncheck "Load welcome page on startup".
Geforce 7300GT on OSX 10.6.4
- Deferred rendering is disabled because materials are not displayed correctly for Geforce 7300GT on OX 10.6.4; This happens because of buggy video drivers.
On Windows x64, Unity crashes when my script throws a NullReferenceException
- Please apply Windows Hotfix #976038.
Graphics
Slow framerate and/or visual artifacts.
- This may occur if your video card drivers are not up to date. Make sure you have the latest official drivers from your card vendor.
Shadows
I see no shadows at all!
- Shadows are a Unity Pro only feature, so without Unity Pro you won't get shadows. Simpler shadow methods, like using a Projector, are still possible, of course.
- Shadows also require certain graphics hardware support. See Shadows page for details.
- Check if shadows are not completely disabled in Quality Settings.
- Shadows are currently not supported for Android and iOS mobile platforms.
Some of my objects do not cast or receive shadows
An object's Renderer must have Receive Shadows enabled for shadows to be rendered onto it. Also, an object must have Cast Shadows enabled in order to cast shadows on other objects (both are on by default).
Only opaque objects cast and receive shadows. This means that objects using the built-in Transparent or Particle shaders will not cast shadows. In most cases it is possible to use Transparent Cutout shaders for objects like fences, vegetation, etc. If you use custom written Shaders, they have to be pixel-lit and use the Geometry render queue. Objects using VertexLit shaders do not receive shadows but are able to cast them.
Only Pixel lights cast shadows. If you want to make sure that a light always casts shadows no matter how many other lights are in the scene, then you can set it to Force Pixel render mode (see the Light reference page).
iOS
Troubleshooting on iOS devices
There are some situations with iOS where your game can work perfectly in the Unity editor but then doesn't work or maybe doesn't even start on the actual device. The problems are often related to code or content quality. This section describes the most common scenarios.
Xcode 3.2.x fails to build the application with the error "libiPhone-lib.a, missing required architecture i386 in file Undefined symbols: "Register_UnityEngine_Input_GetMouseButtonDown()", referenced from: RegisterAllStrippedInternalCalls() in RegisterMonoModules.o
This build error usually happens when a non-simulator SDK is selected in the Player Settings but a simulator SDK is selected in Xcode. The SDK settings in Unity and Xcode must be consistent.
Xcode 4.x fails to build the application with the error "No architectures to compile for (ARCHS=armv6, VALID_ARCHS=i386)."
Currently Unity has limited support for Xcode 4.x and some manual effort is required to build the final application. The Build & Run command will open the generated Xcode project but it won't select the appropriate build target and target device. If you are building for a test on the device you should select the "Unity-iPhone" build target and an iOS device connected to your Mac. If you are building for testing on the simulator (which requires the right SDK selection as described above) then you should select the "Unity-iPhone-simulator" target and the appropriate simulator device.
The game stops responding after a while. Xcode shows "interrupted" in the status bar.
There are a number of reasons why this may happen. Typical causes include:
- Scripting errors such as using uninitialized variables, etc.
- Using 3rd party Thumb compiled native libraries. Such libraries trigger a known problem in the iOS SDK linker and might cause random crashes.
- Using generic types with value types as parameters (eg, List<int>, List<SomeStruct>, List<SomeEnum>, etc) for serializable script properties.
- Using reflection when managed code stripping is enabled.
- Errors in the native plugin interface (the managed code method signature does not match the native code function signature).
Information from the XCode Debugger console can often help detect these problems (Xcode menu: Run > Console).
The Xcode console shows "Program received signal: “SIGBUS” or EXC_BAD_ACCESS error.
This message typically appears on iOS devices when your application receives a NullReferenceException. There two ways to figure out where the fault happened:
Managed stack traces
Since version 3.4 Unity includes software-based handling of the NullReferenceException. The AOT compiler includes quick checks for null references each time a method or variable is accessed on an object. This feature affects script performance which is why it is enabled only for development builds (for basic license users it is enough to enable the "development build" option in the Build Settings dialog, while iOS pro license users additionally need to enable the "script debugging" option). If everything was done right and the fault actually is occurring in .NET code then you won't see EXC_BAD_ACCESS anymore. Instead, the .NET exception text will be printed in the Xcode console (or else your code will just handle it in a "catch" statement). Typical output might be:
Unhandled Exception: System.NullReferenceException: A null value was found where an object instance was required. at DayController+$handleTimeOfDay$121+$.MoveNext () [0x0035a] in DayController.js:122
This indicates that the fault happened in the handleTimeOfDay method of the DayController class, which works as a coroutine. Also if it is script code then you will generally be told the exact line number (eg, "DayController.js:122"). The offending line might be something like the following:
Instantiate(_imgwww.assetBundle.mainAsset);
This might happen if, say, the script accesses an asset bundle without first checking that it was downloaded correctly.
Native stack traces
Native stack traces are a much more powerful tool for fault investigation but using them requires some expertise. Also, you generally can't continue after these native (hardware memory access) faults happen. To get a native stack trace, type thread apply all bt into the Xcode Debugger Console. Carefully inspect the printed stack traces - they may contain hints about where the error occurred. You might see something like:
... Thread 1 (thread 11523): #0 0x006267d0 in OptionsMenu_Start () #1 0x002e4160 in wrapper_runtime_invoke_object_runtime_invoke_void__this___object_intptr_intptr_intptr () #2 0x00a1dd64 in mono_jit_runtime_invoke (method=0x18b63bc, obj=0x5d10cb0, params=0x0, exc=0x2fffdd34) at /Users/mantasp/work/unity/unity-mono/External/Mono/mono/mono/mini/mini.c:4487 #3 0x0088481c in MonoBehaviour::InvokeMethodOrCoroutineChecked () ...
First of all you should find the stack trace for "Thread 1", which is the main thread. The very first lines of the stack trace will point to the place where the error occurred. In this example, the trace indicates that the NullReferenceException happened inside the "OptionsMenu" script's "Start" method. Looking carefully at this method implementation would reveal the cause of the problem. Typically, NullReferenceExceptions happen inside the Start method when incorrect assumptions are made about initialization order. In some cases only a partial stack trace is seen on the Debugger Console:
Thread 1 (thread 11523): #0 0x0062564c in start ()
This indicates that native symbols were stripped during the Release build of the application. The full stack trace can be obtained with the following procedure:
- Select Debug configuration in the Xcode project.
- Clean all targets.
- Build and run.
- Get stack traces again as described above.
EXC_BAD_ACCESS starts occurring when an external library is linked to the Unity iOS application.
This usually happens when an external library is compiled with the ARM Thumb instruction set. Currently such libraries are not compatible with Unity. The problem can be solved easily by recompiling the library without Thumb instructions. You can do this for the library's Xcode project with the following steps:
- in Xcode, select "Project" > "Edit active target" from the menu
- in the "Target Info" dialog, select "Configuration: All Configurations"
- in the search field enter : "thumb"
- a "Compile for Thumb" setting will appear; uncheck it and rebuild the library.
If the library source is not available you should ask the supplier for a non-thumb version of the library.
The Xcode console shows "WARNING -> applicationDidReceiveMemoryWarning()" and the application crashes immediately afterwards
(Sometimes you might see a message like Program received signal: “0”.) This warning message is often not fatal and merely indicates that iOS is low on memory and is asking applications to free up some memory. Typically, background processes like Mail will free some memory and your application can continue to run. However, if your application continues to use memory or ask for more, the OS will eventually start killing applications and yours could be one of them. Apple does not document what memory usage is safe, but empirical observations show that applications using less than 25 MB of RAM (or 80 MB for 3rd generation devices) do not have any memory usage problems. Applications using 40 MB of RAM may have memory problems on 1-2nd generation devices and may require a device restart to run properly. The main metric you should rely on is how much RAM your application uses. Your application memory usage consists of three major components:
- application code (the OS needs to load and keep your application code in RAM)
- native heap (used by the engine to store its state, your assets, etc. in RAM)
- managed heap (used by your Mono runtime to keep C# or JavaScript objects)
Your application memory usage can be tracked by two Xcode Instruments tools: Activity Monitor and Object Allocations. You can start one or the other from the Xcode Run menu: Run > Start with Performance Tool > Activity Monitor and Run > Start with Performance Tool > Object Allocations. The first tool shows all process statistics including Real memory which can be regarded as the total amount of RAM used by your application.
Note: The internal profiler shows only the heap allocated by .NET scripts. Total memory usage can be determined via Xcode Instruments as shown above. This figure includes the application binary (which will be loaded into memory and uses about 7 MB), some standard framework buffers, Unity engine internal state buffers, the .NET runtime heap (number printed by internal profiler), and some other miscellaneous stuff.
The other tool displays all allocations made by your application and includes both native heap and managed heap statistics (don't forget to check the Created and still living box to get the current state of the application). The important statistic is the Net bytes value.

To keep memory usage low:
- Reduce the application binary size by using the strongest iOS stripping options (Advanced license feature), and avoid unnecessary dependencies on different .NET libraries. See the player settings and player size optimization manual pages for further details.
- Reduce the size of your content. Use PVRTC compression for textures and use low poly models. See the manual page about reducing file size for more information.
- Don't allocate more memory than necessary in your scripts. Track mono heap size and usage with the internal profiler
- Note: with Unity 3.0, the scene loading implementation has changed significantly and now all scene assets are preloaded. This results in fewer hiccups when instantiating game objects. If you need more fine-grained control of asset loading and unloading during gameplay, you should use Resources.Load and Object.Destroy.
Querying the OS about the amount of free memory may seem like a good idea to evaluate how well your application is performing. However, the free memory statistic is likely to be unreliable since the OS uses a lot of dynamic buffers and caches. The only reliable approach is to keep track of memory consumption for your application and use that as the main metric. Pay attention to how the graphs from the tools described above change over time, especially after loading new levels.
The game runs correctly when launched from Xcode but crashes while loading the first level when launched manually on the device.
There could be several reasons for this. You need to inspect the device logs to get more details. Connect the device to your Mac, launch Xcode and select Window > Organizer from the menu. Select your device in the Organizer's left toolbar, then click on the "Console" tab and review the latest messages carefully. Additionally, you may need to investigate crash reports. You can find out how to obtain crash reports here: http://developer.apple.com/iphone/library/technotes/tn2008/tn2151.html.
The Xcode Organizer console contains the message "killed by SpringBoard".
There is a poorly-documented time limit for an iOS application to render its first frames and process input. If your application exceeds this limit, it will be killed by SpringBoard. This may happen in an application with a first scene which is too large, for example. To avoid this problem, it is advisable to create a small initial scene which just displays a splash screen, waits a frame or two with yield and then starts loading the real scene. This can be done with code as simple as the following:
function Start () {
yield;
Application.LoadLevel("Test");
}
Type.GetProperty() / Type.GetValue() cause crashes on the device
Currently Type.GetProperty() and Type.GetValue() are supported only for the .NET 2.0 Subset profile. You can select the .NET API compatibility level in the Player Settings.
Note: Type.GetProperty() and Type.GetValue() might be incompatible with managed code stripping and might need to be excluded (you can supply a custom non-strippable type list during the stripping process to accomplish this). For further details, see the iOS player size optimization guide.
The game crashes with the error message "ExecutionEngineException: Attempting to JIT compile method 'SometType`1<SomeValueType>:.ctor ()' while running with --aot-only."
The Mono .NET implementation for iOS is based on AOT (ahead of time compilation to native code) technology, which has its limitations. It compiles only those generic type methods (where a value type is used as a generic parameter) which are explicitly used by other code. When such methods are used only via reflection or from native code (ie, the serialization system) then they get skipped during AOT compilation. The AOT compiler can be hinted to include code by adding a dummy method somewhere in the script code. This can refer to the missing methods and so get them compiled ahead of time.
void _unusedMethod()
{
var tmp = new SomeType<SomeValueType>();
}
Note: value types are basic types, enums and structs.
Various crashes occur on the device when a combination of System.Security.Cryptography and managed code stripping is used
.NET Cryptography services rely heavily on reflection and so are not compatible with managed code stripping since this involves static code analysis. Sometimes the easiest solution to the crashes is to exclude the whole System.Security.Crypography namespace from the stripping process.
The stripping process can be customized by adding a custom link.xml file to the Assets folder of your Unity project. This specifies which types and namespaces should be excluded from stripping. Further details can be found in the iOS player size optimization guide.
link.xml
<linker>
<assembly fullname="mscorlib">
<namespace fullname="System.Security.Cryptography" preserve="all"/>
</assembly>
</linker>
"Ran out of trampolines of type 1/2" runtime error
This error usually happens if you use lots of recursive generics. You can hint to the AOT compiler to allocate more trampolines of type 1 or type 2. Additional AOT compiler command line options can be specified in the "Other Settings" section of the Player Settings. For type 1 trampolines, specify nrgctx-trampolines=ABCD, where ABCD is the number of new trampolines required (i.e. 4096). For type 2 trampolines specify nimt-trampolines=ABCD.
"PlayerLoop called recursively!" error occurs when using Cocoa via a native function called from a script
Some operations with the UI will result in iOS redrawing the window immediately (the most common example is adding a UIView with a UIViewController to the main UIWindow). If you call a native function from a script, it will happen inside Unity's PlayerLoop, resulting in PlayerLoop being called recursively. In such cases, you should consider using the performSelectorOnMainThread method with waitUntilDone set to false. It will inform iOS to schedule the operation to run between Unity's PlayerLoop calls.
UIScrollView stops scrolling sometimes or scrolls wrong
It is difficult to get CADisplayLink and UIScrollView to work together. The simplest solution is to set
#define USE_DISPLAY_LINK_IF_AVAILABLE 0
in AppController.mm
Profiler or Debugger unable to see game running on iOS device
- Check that you have built a Development build, and ticked the "Enable Script Debugging" and "Autoconnect profiler" boxes (as appropriate).
- The application running on the device will make a multicast broadcast to 225.0.0.222 on UDP port 54997. Check that your network settings allow this traffic. Then, the profiler will make a connection to the remote device on a port in the range 55000 - 55511 to fetch profiler data from the device. These ports will need to be open for UDP access.
Android
Troubleshooting Android development
Unity fails to install your application to your device
- Verify that your computer can actually see and communicate with the device. See the Publishing Builds page for further details.
- Check the error message in the Unity console. This will often help diagnose the problem.
If you get an error saying "Unable to install APK, protocol failure" during a build then this indicates that the device is connected to a low-power USB port (perhaps a port on a keyboard or other peripheral). If this happens, try connecting the device to a USB port on the computer itself.
Your application crashes immediately after launch.
- Ensure that you are not trying to use NativeActivity with devices that do not support it.
- Try removing any native plugins you have.
- Try disabling stripping.
- Use adb logcat to get the crash report from your device.
Building DEX Failed
This an error which will produce a message like the following:-
Building DEX Failed! G:\Unity\JavaPluginSample\Temp/StagingArea> java -Xmx1024M -Djava.ext.dirs="G:/AndroidSDK/android-sdk_r09-windows\platform-tools/lib/" -jar "G:/AndroidSDK/android-sdk_r09-windows\platform-tools/lib/dx.jar" --dex --verbose --output=bin/classes.dex bin/classes.jar plugins Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine.
This is usually caused by having the wrong version of Java installed on your machine. Updating your Java installation to the latest version will generally solve this issue.
The game crashes after a couple of seconds when playing video
Make sure Settings->Developer Options->Don't keep activities isn't enabled on the phone. The video player is its own activity and therefore the regular game activity will be destroyed if the video player is activated.
My game quits when I press the sleep button
Change the <activity> tag in the AndroidManifest.xml to contain <android:configChanges> tag as described here.
An example activity tag might look something like this:-
<activity android:name=".AdMobTestActivity"
android:label="@string/app_name"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
android-bugreporting
Before submitting a bug with just "it crashes" in the message body, please look through the Troubleshooting Android development page first.
At this point there are no advanced debug tools to investigate on-device app crashes. However you can use adb application (found under Android-SDK/platform-tools) with logcat parameter. It prints status reports from your device. These reports may include information related to the occurred crash.
If you are sure that the crash you're experiencing happens due to a bug in Unity software, please save the adb logcat output, conduct a repro project and use the bugreporter () to inform us about it. We will get back to you as soon as we can.
Page last updated: 2011-02-24android-unsupported
Graphics
- Non-square textures are not supported by the ETC format.
- Movie Textures are not supported, use a full-screen streaming playback instead. Please see the Movie playback page for more information.
Scripting
- OnMouseEnter, OnMouseOver, OnMouseExit, OnMouseDown, OnMouseUp, and OnMouseDrag events are not supported on Android.
- Dynamic features like Duck Typing are not supported. Use #pragma strict for your scripts to force the compiler to report dynamic features as errors.
- Video streaming via WWW class is not supported.
Android Player Settings
Player Settings is where you define various parameters (platform specific) for the final game that you will build in Unity. Some of these values for example are used in the Resolution Dialog that launches when you open a standalone game, others are used by XCode when building your game for the iOS devices, so it's important to fill them out correctly.
To see the Player Settings choose from the menu bar.

Global Settings that apply to any project you create.
| Cross-Platform Properties | |
|---|---|
| Company Name | The name of your company. This is used to locate the preferences file. |
| Product Name | The name that will appear on the menu bar when your game is running and is used to locate the preferences file also. |
| Default Icon | Default icon the application will have on every platform (You can override this later for platform specific needs). |
Per-Platform Settings
Desktop
Web-Player
Resolution And Presentation

| Resolution | |
| Default Screen Width | Screen Width the player will be generated with. |
| Default Screen Height | Screen Height the plater will be generated with. |
| Run in background | Check this if you dont want to stop executing your game if the player looses focus. |
| WebPlayer Template | For more information you should check the "Using WebPlayer templates page", note that for each built-in and custom template there will be an icon in this section. |
Icon

Icons don't have any meaning for most webplayer builds but they are needed for Native Client builds used as Chrome applications. You can set these icons here.
Other Settings

| Rendering | |
| Rendering Path | This property is shared between Standalone and WebPlayer content. |
| Vertex Lit | Lowest lighting fidelity, no shadows support. Best used on old machines or limited mobile platforms. |
| Forward with Shaders | Good support for lighting features; limited support for shadows. |
| Deferred Lighting | Best support for lighting and shadowing features, but requires certain level of hardware support. Best used if you have many realtime lights. Unity Pro only. |
| Color Space | The color space to be used for rendering |
| GammaSpace Rendering | Rendering is gamma-corrected |
| Linear Rendering Hardware Sampling | Rendering is done in linear space |
| Static Batching | Set this to use Static batching on your build (Inactive by default in webplayers). Unity Pro only. |
| Dynamic Batching | Set this to use Dynamic Batching on your build (Activated by default). |
| Streaming | |
| First Streamed Level | If you are publishing a Streamed Web Player, this is the index of the first level that will have access to all Resources.Load assets. |
Standalone
Resolution And Presentation

| Resolution | |
| Default Screen Width | Screen Width the stand alone game will be using by default. |
| Default Screen Height | Screen Height the plater will be using by default. |
| Run in background | Check this if you dont want to stop executing your game if it looses focus. |
| Standalone Player Options | |
| Default is Full Screen | Check this if you want to start your game by default in full screen mode. |
| Capture Single Screen | If enabled, standalone games in fullscreen mode will not darken the secondary monitor in multi-monitor setups. |
| DisplayResolution Dialog | |
| Disabled | No resolution dialog will appear when starting the game. |
| Enabled | Resolution dialog will always appear when the game is launched. |
| Hidden by default | The resolution player is possible to be opened only if you have pressed the "alt" key when starting the game. |
| Use Player Log | Write a log file with debugging information. |
| Mac App Store Validation | Enable receipt validation for the Mac App Store. |
| Supported Aspect Ratios | Aspect Ratios selectable in the Resolution Dialog will be monitor-supported resolutions of enabled items from this list. |
Icon

| Override for Standalone | Check if you want to assign a custom icon you would like to be used for your standalone game. Different sizes of the icon should fill in the squares below. |
Splash Image

| Config Dialog Banner | Add your custom splash image that will be displayed when the game is starting. |
Other Settings

| Rendering | |
| Rendering Path | This property is shared between Standalone and WebPlayer content. |
| Vertex Lit | Lowest lighting fidelity, no shadows support. Best used on old machines or limited mobile platforms. |
| Forward with Shaders | Good support for lighting features; limited support for shadows. |
| Deferred Lighting | Best support for lighting and shadowing features, but requires certain level of hardware support. Best used if you have many realtime lights. Unity Pro only. |
| Color Space | The color space to be used for rendering |
| GammaSpace Rendering | Rendering is gamma-corrected |
| Linear Rendering Hardware Sampling | Rendering is done in linear space |
| Static Batching | Set this to use Static batching on your build (Inactive by default in webplayers). Unity Pro only. |
| Dynamic Batching | Set this to use Dynamic Batching on your build (Activated by default). |
| API Compatibility Level | |
| .Net 2.0 | .Net 2.0 libraries. Maximum .net compatibility, biggest file sizes |
| .Net 2.0 Subset | Subset of full .net compatibility, smaller file sizes |
iOS
Resolution And Presentation

| Resolution | |
| Default Orientation | (This setting is shared between iOS and Android devices) |
| Portrait | The device is in portrait mode, with the device held upright and the home button at the bottom. |
| Portrait Upside Down (iOS Only) | The device is in portrait mode but upside down, with the device held upright and the home button at the top. |
| Landscape Right (iOS Only) | The device is in landscape mode, with the device held upright and the home button on the left side. |
| Landscape Left | The device is in landscape mode, with the device held upright and the home button on the right side. |
| Auto Rotation | The screen orientation is automatically set based on the physical device orientation. |
| Auto Rotation settings | |
| Use Animated Autorotation | When checked, orientation change is animated. This only applies when Default orientation is set to Auto Rotation. |
| Allowed Orientations for Auto Rotation | |
| Portrait | When checked, portrait orientation is allowed. This only applies when Default orientation is set to Auto Rotation. |
| Portrait Upside Down | When checked, portrait upside down orientation is allowed. This only applies when Default orientation is set to Auto Rotation. |
| Landscape Right | When checked, landscape right (home button on the left side) orientation is allowed. This only applies when Default orientation is set to Auto Rotation. |
| Landscape Left | When checked, landscape left (home button is on the right side) orientation is allowed. This only applies when Default orientation is set to Auto Rotation. |
| Status Bar | |
| Status Bar Hidden | Specifies whether the status bar is initially hidden when the application launches. |
| Status Bar Style | Specifies the style of the status bar as the application launches |
| Default | |
| Black Translucent | |
| Black Opaque | |
| Use 32-bit Display Buffer | Specifies if Display Buffer should be created to hold 32-bit color values (16-bit by default). Use it if you see banding, or need alpha in your ImageEffects, as they will create RTs in same format as Display Buffer. |
| Show Loading Indicator | Options for the loading indicator |
| Don't Show | No indicator |
| White Large | Indicator shown large and in white |
| White | Indicator shown at normal size in white |
| Gray | Indicator shown at normal size in gray |
Icon

| Override for iOS | Check if you want to assign a custom icon you would like to be used for your iPhone/iPad game. Different sizes of the icon should fill in the squares below. |
| Prerendered icon | If unchecked iOS applies sheen and bevel effects to the application icon. |
Splash Image

| Mobile Splash Screen (Pro-only feature) | Specifies texture which should be used for iOS Splash Screen. Standard Splash Screen size is 320x480.(This is shared between Android and iOS) |
| High Res. iPhone (Pro-only feature) | Specifies texture which should be used for iOS 4th gen device Splash Screen. Splash Screen size is 640x960. |
| iPad Portrait (Pro-only feature) | Specifies texture which should be used as iPad Portrait orientation Splash Screen. Standard Splash Screen size is 768x1024. |
| iPad Landscape (Pro-only feature) | Specifies texture which should be used as iPad Landscape orientation Splash Screen. Standard Splash Screen size is 1024x768. |
Other Settings

| Rendering | |
| Static Batching | Set this to use Static batching on your build (Activated by default). Pro-only feature. |
| Dynamic Batching | Set this to use Dynamic Batching on your build (Activated by default). |
| Identification | |
| Bundle Identifier | The string used in your provisioning certificate from your Apple Developer Network account(This is shared between iOS and Android) |
| Bundle Version | Specifies the build version number of the bundle, which identifies an iteration (released or unreleased) of the bundle. This is a monotonically increased string, comprised of one or more period-separated |
| Configuration | |
| Target Device | Specifies application target device type. |
| iPhone Only | Application is targeted for iPhone devices only. |
| iPad Only | Application is targeted for iPad devices only. |
| iPhone + iPad | Application is targeted for both iPad and iPhone devices. |
| Target Platform | Specifies the target arquitecture you are going to build for.(This setting is shared between iOS and Android Platforms) |
| armv6 (OpenGL ES1.1) | Application is optimized for armv6 chipsets |
| Universal armv6+armv7 (OpenGL ES1.1+2.0) | Application supports both armv6 and armv7 chipsets. Note: increases application distribution size |
| armv7 | Application is optimized for armv7 chipsets. 1st-2nd gen. devices are not supported. There might be additional requirements for this build target imposed by Apple App Store. Defaults to OpenGL ES 2.0. |
| Target Resolution | Resolution you want to use on your deployed device.(This setting will not have any effect on devices with maximum resolution of 480x320) |
| Native(Default Device Resolution) | Will use the device native resolution. |
| Standard(Medium or Low Resolution) | Use the lowest resolution possible (480x320). |
| HD(Highest available resolution) | Use the maximum resolution allowed on the device (960x640). |
| Accelerometer Frequency | How often the accelerometer is sampled |
| Disabled | Accelerometer is not sampled |
| 15Hz | 15 samples per second |
| 30Hz | 30 samples per second |
| 60Hz | 60 samples per second |
| 100Hz | 100 samples per second |
| Override iPod Music | If selected application will silence user's iPod music. Otherwise user's iPod music will continue playing in the background. |
| UI Requires Persistent WiFi | Specifies whether the application requires a Wi-Fi connection. iOS maintains the active Wi-Fi connection open while the application is running. |
| Exit on Suspend | Specifies whether the application should quit when suspended to background on iOS versions that support multitasking. |
| Optimization | |
| Api Compatibility Level | Specifies active .NET API profile |
| .Net 2.0 | .Net 2.0 libraries. Maximum .net compatibility, biggest file sizes |
| .Net 2.0 Subset | Subset of full .net compatibility, smaller file sizes |
| AOT compilation options | Additional AOT compiler options. |
| SDK Version | Specifies iPhone OS SDK version to use for building in Xcode |
| iOS 4.0 | iOS SDK 4.0. |
| iOS Simulator 4.0 | iOS Simulator 4.0. Application built for this version of SDK will be able to run only on Simulator from the SDK 4. |
| iOS 4.1 | iOS 4.1. |
| iOS Simulator 4.1 | iOS Simulator 4.1. Application built for this version of SDK will be able to run only on Simulator from the SDK 4.x. |
| iOS 4.2 | iOS 4.2. |
| iOS Simulator 4.2 | iOS Simulator 4.2. Application built for this version of SDK will be able to run only on Simulator from the SDK 4.x. |
| iOS 4.3 | iOS 4.3. |
| iOS Simulator 4.3 | iOS Simulator 4.3. Application built for this version of SDK will be able to run only on Simulator from the SDK 4.x. |
| iOS 5.0 | iOS 5.0 |
| iOS Simulator 5.0 | iOS Simulator 5.0. Application built for this version of SDK will be able to run only on Simulator from the SDK 5.x. |
| iOS latest | Latest available iOS SDK. Available since iOS SDK 4.2. (default value) |
| iOS Simulator latest | Latest available iOS Simulator SDK. Available since iOS SDK 4.2. |
| Unknown | iOS SDK version is not managed by Unity Editor. |
| Target iOS Version | Specifies lowest iOS version where final application will able to run |
| 3.0 | iPhone OS 3.0. (default value) |
| 3.1 | iPhone OS 3.1. |
| 3.1.2 | iPhone OS 3.1.2. |
| 3.1.3 | iPhone OS 3.1.3. |
| 3.2 | iPhone OS 3.2. |
| 4.0 | iPhone OS 4.0. |
| 4.1 | iPhone OS 4.1. |
| 4.2 | iPhone OS 4.2. |
| 4.3 | iPhone OS 4.3. |
| 5.0 | iPhone OS 5.0 |
| Unknown | iPhone OS SDK version is not managed by Unity Editor. |
| Stripping Level (Pro-only feature) | Options to strip out scripting features to reduce built player size(This setting is shared between iOS and Android Platforms) |
| Disabled | No reduction is done. |
| Strip Assemblies | Level 1 size reduction. |
| Strip ByteCode | Level 2 size reduction (includes reductions from Level 1). |
| Use micro mscorlib | Level 3 size reduction (includes reductions from Levels 1 and 2). |
| Script Call Optimization | Optionally disable exception handling for a speed boost at runtime |
| Slow and Safe | Full exception handling will occur with some performance impact on the device |
| Fast but no Exceptions | No data provided for exceptions on the device, but the game will run faster |
Note: If you build for example for iPhone OS 3.2, and then select Simulator 3.2 in Xcode you will get a ton of errors. So you MUST be sure to select a proper Target SDK in Unity Editor.
Android
Resolution And Presentation

Resolution and presentation for your Android project builds.
| Resolution | |
| Default Orientation | (This setting is shared between iOS and Android devices) |
| Portrait | The device is in portrait mode, with the device held upright and the home button at the bottom. |
| Portrait Upside Down | The device is in portrait mode but upside down, with the device held upright and the home button at the top (only available with Android OS 2.3 and later). |
| Landscape Right | The device is in landscape mode, with the device held upright and the home button on the left side (only available with Android OS 2.3 and later). |
| Landscape Left | The device is in landscape mode, with the device held upright and the home button on the right side. |
| Use 32-bit Display Buffer | Specifies if Display Buffer should be created to hold 32-bit color values (16-bit by default). Use it if you see banding, or need alpha in your ImageEffects, as they will create RTs in same format as Display Buffer. Not supported on devices running pre-Gingerbread OS (will be forced to 16-bit). |
| Use 24-bit Depth Buffer | If set Depth Buffer will be created to hold (at least) 24-bit depth values. Use it only if you see 'z-fighting' or other artifacts, as it may have performance implications. |
| Icon | |
|---|---|

Different icons that your project will have when built.
| Override for Android | Check if you want to assign a custom icon you would like to be used for your Android game. Different sizes of the icon should fill in the squares below. |
| SplashImage | |
|---|---|

Splash image that is going to be displayed when your project is launched.
| Mobile Splash Screen (Pro-only feature) | Specifies texture which should be used by the iOS Splash Screen. Standard Splash Screen size is 320x480.(This is shared between Android and iOS) |
| Splash Scaling | Specifies how will be the splash image scaling on the device. |
| Other Settings | |
|---|---|

| Rendering | |
| Static Batching | Set this to use Static batching on your build (Activated by default). Pro-only feature. |
| Dynamic Batching | Set this to use Dynamic Batching on your build (Activated by default). |
| Identification | |
| Bundle Identifier | The string used in your provisioning certificate from your Apple Developer Network account(This is shared between iOS and Android) |
| Bundle Version | Specifies the build version number of the bundle, which identifies an iteration (released or unreleased) of the bundle. This is a monotonically increased string, comprised of one or more period-separated(This is shared between iOS and Android) |
| Bundle Version Code | An internal version number. This number is used only to determine whether one version is more recent than another, with higher numbers indicating more recent versions. This is not the version number shown to users; that number is set by the versionName attribute. The value must be set as an integer, such as "100". You can define it however you want, as long as each successive version has a higher number. For example, it could be a build number. Or you could translate a version number in "x.y" format to an integer by encoding the "x" and "y" separately in the lower and upper 16 bits. Or you could simply increase the number by one each time a new version is released. |
| Configuration | |
| Device Filter | Specifies the target architecture you are going to build for. |
| ARMv7 only | Application optimized for ARMv7 CPU architecture. It will also enable correct Android Market device filtering, thus recommended for publishing to the Android Market (only devices supporting Unity Android will list the application on the Android Market). |
| ARMv6 with VFP | Application optimized for ARMv6 CPU architecture (requires VFP support). Use runtime detection of hardware capabilities rather than relying on the Android Market filtering mechanism. It means the application when published to the Android Market will be visible also to devices not supporting Unity Android. Obviously this is not recommended, especially for paid applications (though can be combined with other means of filtering instead, like OpenGLES version). |
| x86 | Application compiled for the Intel x86 CPU architecture |
| Graphics Level | Select either ES 1.1 ('fixed function') or ES 2.0 ('shader based') Open GL level. When using the AVD (emulator) only ES 1.x is supported. |
| Install Location | Specifies application install location on the device (for detailed information, please refer to http://developer.android.com/guide/appendix/install-location.html). |
| Automatic | Let OS decide. User will be able to move the app back and forth. |
| Prefer External | Install app to external storage (SD-Card) if possible. OS does not guarantee that will be possible; if not, the app will be installed to internal memory. |
| Force Internal | Force app to be installed into internal memory. User will be unable to move the app to external storage. |
| Internet Access | When set to Require, will enable networking permissions even if your scripts are not using this. Automatically enabled for development builds. |
| Write Access | When set to External (SDCard), will enable write access to external storage such as the SD-Card. Automatically enabled for development builds. |
| Optimization | |
| Api Compatibility Level | Specifies active .NET API profile |
| .Net 2.0 | .Net 2.0 libraries. Maximum .net compatibility, biggest file sizes |
| .Net 2.0 Subset | Subset of full .net compatibility, smaller file sizes |
| Stripping Level (Pro-only feature) | Options to strip out scripting features to reduce built player size(This setting is shared between iOS and Android Platforms) |
| Disabled | No reduction is done. |
| Strip Assemblies | Level 1 size reduction. |
| Strip ByteCode (iOS only) | Level 2 size reduction (includes reductions from Level 1). |
| Use micro mscorlib | Level 3 size reduction (includes reductions from Levels 1 and 2). |
| Enable "logcat" profiler | Enable this if you want to get feedback from your device while testing your projects. So adb logcat prints logs from the device to the console (only available in development builds). |
| Publishing Settings | |
|---|---|

Publishing settings for Android Market
| Keystore | |
| Use Existing Keystore / Create New Keystore | Use this to choose whether to create a new Keystore or use an existing one. |
| Browse Keystore | Lets you select an existing Keystore. |
| Keystore password | Password for the Keystore. |
| Confirm password | Password confirmation, only enabled if the Create New Keystore option is chosen. |
| Key | |
| Alias | Key alias |
| Password | Password for key alias |
| Android Market Licensing (LVL) | |
| Public Key | The public key provided by the Android developer site. |
Note that for security reasons, Unity will save neither the keystore password nor the key password. Also, note that the signing must be done from Unity's player settings - using jarsigner will not work.
Flash
Resolution And Presentation

| Resolution | |
| Default Screen Width | Screen Width the player will be generated with. |
| Default Screen Height | Screen Height the plater will be generated with. |
Other Settings

| Optimization | |
| Stripping | Bytecode can optionally be stripped during the build. |
Details
Desktop
The Player Settings window is where many technical preference defaults are set. See also Quality Settings where the different graphics quality levels can be set up.
Publishing a web player
Default Web Screen Width and Default Web Screen Height determine the size used in the html file. You can modify the size in the html file later.
Default Screen Width and Default Screen Height are used by the Web Player when entering fullscreen mode through the context menu in the Web Player at runtime.
Customizing your Resolution Dialog

The Resolution Dialog, presented to end-users
You have the option of adding a custom banner image to the Screen Resolution Dialog in the Standalone Player. The maximum image size is 432 x 163 pixels. The image will not be scaled up to fit the screen selector. Instead it will be centered and cropped.
Publishing to Mac App Store
Use Player Log enables writing a log file with debugging information. This is useful to find out what happened if there are problems with your game. When publishing games for Apple's Mac App Store, it is recommended to turn this off, because Apple may reject your submission otherwise. See this manual page for further information about log files.
Use Mac App Store Validation enables receipt validation for the Mac App Store. If this is enabled, your game will only run when it contains a valid receipt from the Mac App Store. Use this when submitting games to Apple for publishing on the App Store. This prevents people from running the game on any computer then the one it was purchased on. Note that this feature does not implement any strong copy protection. In particular, any potential crack against one Unity game would work against any other Unity content. For this reason, it is recommended that you implement your own receipt validation code on top of this using Unity's plugin feature. However, since Apple requires plugin validation to initially happen before showing the screen setup dialog, you should still enable this check, or Apple might reject your submission.
iOS
Bundle Identifier
The Bundle Identifier string must match the provisioning profile of the game you are building. The basic structure of the identifier is com.CompanyName.GameName. This structure may vary internationally based on where you live, so always default to the string provided to you by Apple for your Developer Account. Your GameName is set up in your provisioning certificates, that are manageable from the Apple iPhone Developer Center website. Please refer to the Apple iPhone Developer Center website for more information on how this is performed.
Stripping Level (Pro-only)
Most games don't use all necessary dlls. With this option, you can strip out unused parts to reduce the size of the built player on iOS devices. If your game is using classes that would normally be stripped out by the option you currently have selected, you'll be presented with a Debug message when you make a build.
Script Call Optimization
A good development practice on iOS is to never rely on exception handling (either internally or through the use of try/catch blocks). When using the default Slow and Safe option, any exceptions that occur on the device will be caught and a stack trace will be provided. When using the Fast but no Exceptions option, any exceptions that occur will crash the game, and no stack trace will be provided. However, the game will run faster since the processor is not diverting power to handle exceptions. When releasing your game to the world, it's best to publish with the Fast but no Exceptions option.
Android
Bundle Identifier
The Bundle Identifier string is the unique name of your application when published to the Android Market and installed on the device. The basic structure of the identifier is com.CompanyName.GameName, and can be chosen arbitrarily. In Unity this field is shared with the iOS Player Settings for convenience.
Stripping Level (Pro-only)
Most games don't use all the functionality of the provided dlls. With this option, you can strip out unused parts to reduce the size of the built player on Android devices.
android-API
Unity Android provides a number of scripting APIs unified with iOS APIs to access handheld device functionality. For cross-platform projects, UNITY_ANDROID is defined for conditionally compiling Android-specific C# code. The following scripting classes contain Android-related changes (some of the API is shared between Android and iOS):
| Input | Access to multi-touch screen, accelerometer and device orientation. |
| iPhoneSettings | Some of the Android settings, such as screen orientation, dimming and information about device hardware. |
| iPhoneKeyboard | Support for native on-screen keyboard. |
| iPhoneUtils | Useful functions for movie playback, anti-piracy protection and vibration. |
Further Reading
Page last updated: 2010-09-08Android-Input
Desktop
Note: Keyboard, joystick and gamepad input works only on the desktop version of Unity.
Unity supports keyboard, joystick and gamepad input.
Virtual axes and buttons can be created in the Input Manager, and end users can configure Keyboard input in a nice screen configuration dialog.

You can setup joysticks, gamepads, keyboard, and mouse, then access them all through one simple scripting interface.
From scripts, all virtual axes are accessed by their name.
Every project has the following default input axes when it's created:
- Horizontal and Vertical are mapped to w, a, s, d and the arrow keys.
- Fire1, Fire2, Fire3 are mapped to Control, Option (Alt), and Command, respectively.
- Mouse X and Mouse Y are mapped to the delta of mouse movement.
- Window Shake X and Window Shake Y is mapped to the movement of the window.
Adding new Input Axes
If you want to add new virtual axes go to the menu. Here you can also change the settings of each axis.

You map each axis to two buttons on a joystick, mouse, or keyboard keys.
| Name | The name of the string used to check this axis from a script. |
| Descriptive Name | Positive value name displayed in the input tab of the configuration dialog for standalone builds. |
| Descriptive Negative Name | Negative value name displayed in the Input tab of the Configuration dialog for standalone builds. |
| Negative Button | The button used to push the axis in the negative direction. |
| Positive Button | The button used to push the axis in the positive direction. |
| Alt Negative Button | Alternative button used to push the axis in the negative direction. |
| Alt Positive Button | Alternative button used to push the axis in the positive direction. |
| Gravity | Speed in units per second that the axis falls toward neutral when no buttons are pressed. |
| Dead | Size of the analog dead zone. All analog device values within this range result map to neutral. |
| Sensitivity | Speed in units per second that the the axis will move toward the target value. This is for digital devices only. |
| Snap | If enabled, the axis value will reset to zero when pressing a button of the opposite direction. |
| Invert | If enabled, the Negative Buttons provide a positive value, and vice-versa. |
| Type | The type of inputs that will control this axis. |
| Axis | The axis of a connected device that will control this axis. |
| Joy Num | The connected Joystick that will control this axis. |
Use these settings to fine tune the look and feel of input. They are all documented with tooltips in the Editor as well.
Using Input Axes from Scripts
You can query the current state from a script like this:
value = Input.GetAxis ("Horizontal");
An axis has a value between -1 and 1. The neutral position is 0. This is the case for joystick input and keyboard input.
However, Mouse Delta and Window Shake Delta are how much the mouse or window moved during the last frame. This means it can be larger than 1 or smaller than -1 when the user moves the mouse quickly.
It is possible to create multiple axes with the same name. When getting the input axis, the axis with the largest absolute value will be returned. This makes it possible to assign more than one input device to one axis name. For example, create one axis for keyboard input and one axis for joystick input with the same name. If the user is using the joystick, input will come from the joystick, otherwise input will come from the keyboard. This way you don't have to consider where the input comes from when writing scripts.
Button Names
To map a key to an axis, you have to enter the key's name in the Positive Button or Negative Button property in the Inspector.
The names of keys follow this convention:
- Normal keys: "a", "b", "c" ...
- Number keys: "1", "2", "3", ...
- Arrow keys: "up", "down", "left", "right"
- Keypad keys: "[1]", "[2]", "[3]", "[+]", "[equals]"
- Modifier keys: "right shift", "left shift", "right ctrl", "left ctrl", "right alt", "left alt", "right cmd", "left cmd"
- Mouse Buttons: "mouse 0", "mouse 1", "mouse 2", ...
- Joystick Buttons (from any joystick): "joystick button 0", "joystick button 1", "joystick button 2", ...
- Joystick Buttons (from a specific joystick): "joystick 1 button 0", "joystick 1 button 1", "joystick 2 button 0", ...
- Special keys: "backspace", "tab", "return", "escape", "space", "delete", "enter", "insert", "home", "end", "page up", "page down"
- Function keys: "f1", "f2", "f3", ...
The names used to identify the keys are the same in the scripting interface and the Inspector.
value = Input.GetKey ("a");
Mobile Input
Unity iOS/Android offers you access to the iPhone, iPad and Android input systems via Input and iOS Input scripting interfaces.
Input provides access to the multi-touch screen, accelerometer and device orientation. iOS Input provides access to geographical location.
Access to keyboard on mobile devices is provided via the iOS keyboard.
Multi-Touch Screen
The iPhone and iPod Touch devices are capable of tracking up to five fingers touching the screen simultaneously. You can retrieve the status of each finger touching the screen during the last frame by accessing the Input.touches property array.
Android devices don't have a unified limit on how many fingers they track. Instead, it varies from device to device and can be anything from two-touch on older devices to five fingers on some newer devices.
Each finger touch is represented by an Input.Touch data structure:
| fingerId | The unique index for a touch. |
| position | The screen position of the touch. |
| deltaPosition | The screen position change since the last frame. |
| deltaTime | Amount of time that has passed since the last state change. |
| tapCount | The iPhone/iPad screen is able to distinguish quick finger taps by the user. This counter will let you know how many times the user has tapped the screen without moving a finger to the sides. Android devices do not count number of taps, this field is always 1. |
| phase | Describes so called "phase" or the state of the touch. It can help you determine if the touch just began, if user moved the finger or if he just lifted the finger. |
Phase can be one of the following:
| Began | A finger just touched the screen. |
| Moved | A finger moved on the screen. |
| Stationary | A finger is touching the screen but hasn't moved since the last frame. |
| Ended | A finger was lifted from the screen. This is the final phase of a touch. |
| Canceled | The system cancelled tracking for the touch, as when (for example) the user puts the device to her face or more than five touches happened simultaneously. This is the final phase of a touch. |
Following is an example script which will shoot a ray whenever the user taps on the screen:
var particle : GameObject;
function Update () {
for (var touch : Touch in Input.touches) {
if (touch.phase == TouchPhase.Began) {
// Construct a ray from the current touch coordinates
var ray = Camera.main.ScreenPointToRay (touch.position);
if (Physics.Raycast (ray)) {
// Create a particle if hit
Instantiate (particle, transform.position, transform.rotation);
}
}
}
}
Mouse Simulation
On top of native touch support Unity iOS/Android provides a mouse simulation. You can use mouse functionality from the standard Input class.
Device Orientation
Unity iOS/Android allows you to get discrete description of the device physical orientation in three-dimensional space. Detecting a change in orientation can be useful if you want to create game behaviors depending on how the user is holding the device.
You can retrieve device orientation by accessing the Input.deviceOrientation property. Orientation can be one of the following:
| Unknown | The orientation of the device cannot be determined. For example when device is rotate diagonally. |
| Portrait | The device is in portrait mode, with the device held upright and the home button at the bottom. |
| PortraitUpsideDown | The device is in portrait mode but upside down, with the device held upright and the home button at the top. |
| LandscapeLeft | The device is in landscape mode, with the device held upright and the home button on the right side. |
| LandscapeRight | The device is in landscape mode, with the device held upright and the home button on the left side. |
| FaceUp | The device is held parallel to the ground with the screen facing upwards. |
| FaceDown | The device is held parallel to the ground with the screen facing downwards. |
Accelerometer
As the mobile device moves, a built-in accelerometer reports linear acceleration changes along the three primary axes in three-dimensional space. Acceleration along each axis is reported directly by the hardware as G-force values. A value of 1.0 represents a load of about +1g along a given axis while a value of -1.0 represents -1g. If you hold the device upright (with the home button at the bottom) in front of you, the X axis is positive along the right, the Y axis is positive directly up, and the Z axis is positive pointing toward you.
You can retrieve the accelerometer value by accessing the Input.acceleration property.
The following is an example script which will move an object using the accelerometer:
var speed = 10.0;
function Update () {
var dir : Vector3 = Vector3.zero;
// we assume that the device is held parallel to the ground
// and the Home button is in the right hand
// remap the device acceleration axis to game coordinates:
// 1) XY plane of the device is mapped onto XZ plane
// 2) rotated 90 degrees around Y axis
dir.x = -Input.acceleration.y;
dir.z = Input.acceleration.x;
// clamp acceleration vector to the unit sphere
if (dir.sqrMagnitude > 1)
dir.Normalize();
// Make it move 10 meters per second instead of 10 meters per frame...
dir *= Time.deltaTime;
// Move object
transform.Translate (dir * speed);
}
Low-Pass Filter
Accelerometer readings can be jerky and noisy. Applying low-pass filtering on the signal allows you to smooth it and get rid of high frequency noise.
The following script shows you how to apply low-pass filtering to accelerometer readings:
var AccelerometerUpdateInterval : float = 1.0 / 60.0;
var LowPassKernelWidthInSeconds : float = 1.0;
private var LowPassFilterFactor : float = AccelerometerUpdateInterval / LowPassKernelWidthInSeconds; // tweakable
private var lowPassValue : Vector3 = Vector3.zero;
function Start () {
lowPassValue = Input.acceleration;
}
function LowPassFilterAccelerometer() : Vector3 {
lowPassValue = Mathf.Lerp(lowPassValue, Input.acceleration, LowPassFilterFactor);
return lowPassValue;
}
The greater the value of LowPassKernelWidthInSeconds, the slower the filtered value will converge towards the current input sample (and vice versa). You should be able to use the LowPassFilter() function instead of avgSamples().
I'd like as much precision as possible when reading the accelerometer. What should I do?
Reading the Input.acceleration variable does not equal sampling the hardware. Put simply, Unity samples the hardware at a frequency of 60Hz and stores the result into the variable. In reality, things are a little bit more complicated -- accelerometer sampling doesn't occur at consistent time intervals, if under significant CPU loads. As a result, the system might report 2 samples during one frame, then 1 sample during the next frame.
You can access all measurements executed by accelerometer during the frame. The following code will illustrate a simple average of all the accelerometer events that were collected within the last frame:
var period : float = 0.0;
var acc : Vector3 = Vector3.zero;
for (var evnt : iPhoneAccelerationEvent in iPhoneInput.accelerationEvents) {
acc += evnt.acceleration * evnt.deltaTime;
period += evnt.deltaTime;
}
if (period > 0)
acc *= 1.0/period;
return acc;
Further Reading
The Unity mobile input API is originally based on Apple's API. It may help to learn more about the native API to better understand Unity's Input API. You can find the Apple input API documentation here:
- Programming Guide: Event Handling (Apple iPhone SDK documentation)
- UITouch Class Reference (Apple iOS SDK documentation)
Note: The above links reference your locally installed iPhone SDK Reference Documentation and will contain native ObjectiveC code. It is not necessary to understand these documents for using Unity on mobile devices, but may be helpful to some!
iOS
Device geographical location
Device geographical location can be obtained via the iPhoneInput.lastLocation property. Before calling this property you should start location service updates using iPhoneSettings.StartLocationServiceUpdates() and check the service status via iPhoneSettings.locationServiceStatus. See the scripting reference for details.
Android-Keyboard
In most cases, Unity will handle keyboard input automatically for GUI elements but it is also easy to show the keyboard on demand from a script.
iOS
Using the Keyboard
GUI Elements
The keyboard will appear automatically when a user taps on editable GUI elements. Currently, GUI.TextField, GUI.TextArea and GUI.PasswordField will display the keyboard; see the GUI class documentation for further details.
Manual Keyboard Handling
Use the iPhoneKeyboard.Open function to open the keyboard. Please see the iPhoneKeyboard scripting reference for the parameters that this function takes.
Keyboard Type Summary
The Keyboard supports the following types:
| iPhoneKeyboardType.Default | Letters. Can be switched to keyboard with numbers and punctuation. |
| iPhoneKeyboardType.ASCIICapable | Letters. Can be switched to keyboard with numbers and punctuation. |
| iPhoneKeyboardType.NumbersAndPunctuation | Numbers and punctuation. Can be switched to keyboard with letters. |
| iPhoneKeyboardType.URL | Letters with slash and .com buttons. Can be switched to keyboard with numbers and punctuation. |
| iPhoneKeyboardType.NumberPad | Only numbers from 0 to 9. |
| iPhoneKeyboardType.PhonePad | Keyboard used to enter phone numbers. |
| iPhoneKeyboardType.NamePhonePad | Letters. Can be switched to phone keyboard. |
| iPhoneKeyboardType.EmailAddress | Letters with @ sign. Can be switched to keyboard with numbers and punctuation. |
Text Preview
By default, an edit box will be created and placed on top of the keyboard after it appears. This works as preview of the text that user is typing, so the text is always visible for the user. However, you can disable text preview by setting iPhoneKeyboard.hideInput to true. Note that this works only for certain keyboard types and input modes. For example, it will not work for phone keypads and multi-line text input. In such cases, the edit box will always appear. iPhoneKeyboard.hideInput is a global variable and will affect all keyboards.
Keyboard Orientation
By default, the keyboard automatically follows the device orientation. To disable or enable rotation to a certain orientation, use the following properties available in iPhoneKeyboard:
| autorotateToPortrait | Enable or disable autorotation to portrait orientation (button at the bottom). |
| autorotateToPortraitUpsideDown | Enable or disable autorotation to portrait orientation (button at top). |
| autorotateToLandscapeLeft | Enable or disable autorotation to landscape left orientation (button on the right). |
| autorotateToLandscapeRight | Enable or disable autorotation to landscape right orientation (button on the left). |
Visibility and Keyboard Size
There are three keyboard properties in iPhoneKeyboard that determine keyboard visibility status and size on the screen.
| visible | Returns true if the keyboard is fully visible on the screen and can be used to enter characters. |
| area | Returns the position and dimensions of the keyboard. |
| active | Returns true if the keyboard is activated. This property is not static property. You must have a keyboard instance to use this property. |
Note that iPhoneKeyboard.area will return a rect with position and size set to 0 until the keyboard is fully visible on the screen. You should not query this value immediately after iPhoneKeyboard.Open. The sequence of keyboard events is as follows:
- iPhoneKeyboard.Open is called. iPhoneKeyboard.active returns true. iPhoneKeyboard.visible returns false. iPhoneKeyboard.area returns (0, 0, 0, 0).
- Keyboard slides out into the screen. All properties remain the same.
- Keyboard stops sliding. iPhoneKeyboard.active returns true. iPhoneKeyboard.visible returns true. iPhoneKeyboard.area returns real position and size of the keyboard.
Secure Text Input
It is possible to configure the keyboard to hide symbols when typing. This is useful when users are required to enter sensitive information (such as passwords). To manually open keyboard with secure text input enabled, use the following code:
iPhoneKeyboard.Open("", iPhoneKeyboardType.Default, false, false, true);

Hiding text while typing
Alert keyboard
To display the keyboard with a black semi-transparent background instead of the classic opaque, call iPhoneKeyboard.Open as follows:
iPhoneKeyboard.Open("", iPhoneKeyboardType.Default, false, false, true, true);

Classic keyboard

Alert keyboard
Android
Unity Android reuses the iOS API to display system keyboard. Even though Unity Android supports most of the functionality of its iPhone counterpart, there are two aspects which are not supported:
- iPhoneKeyboard.hideInput
- iPhoneKeyboard.area
Please also note that the layout of a iPhoneKeyboardType can differ somewhat between devices.
Android-Advanced
iOS
Advanced iOS scripting
Determining Device Generation
Different device generations support different functionality and widely varying performance. You should query the device for its generation and decide which functionality should be disabled to compensate for slower devices.
You can retrieve device generation by accessing the iPhoneSettings.generation property. Generation can be one of the following:
- iPhone
- iPhone3G
- iPhone3GS
- iPhone4
- iPodTouch1Gen
- iPodTouch2Gen
- iPodTouch3Gen
- iPodTouch4Gen
- iPad1Gen
You can find more information about different device generations, performance and supported functionality in iPhone Hardware Guide.
Device Properties
There are a number of device specific properties that you can access:
| iPhoneSettings.uniqueIdentifier | Unique device identifier. |
| iPhoneSettings.name | User specified name for device. |
| iPhoneSettings.model | Is it iPhone or iPod Touch? |
| iPhoneSettings.systemName | Operating system. |
| SystemInfo.operatingSystem | Operating system version. |
Anti-Piracy Check
It is not uncommon for pirates to hack applications from AppStore by removing Apple DRM protection and redistributing them for free. Unity iOS comes with anti-piracy check which allows you to determine if your application was altered after it was submitted to AppStore.
You can check if your application is genuine (not-hacked) by accessing iPhoneUtils.isApplicationGenuine property. If this property returns false you're free to notify user that he is using hacked application or you can disable access to some functions of your application.
Note: accessing iPhoneUtils.isApplicationGenuine property is reasonably expensive operation and you should never do it on a frame-to-frame basis.
Vibration Support
You can trigger iOS vibration by calling iPhoneUtils.Vibrate. However iPod Touch devices lack vibration hardware and will just ignore this call.
Standard Assets
"Standard Assets" is a folder with special meaning (same as "Plugins" and "Editor) and its content is compiled before all other scripts. You should keep your scripts in folders without special name.
Android
Advanced iOS scripting
Determining Device Generation
Different Android devices support different functionality and widely varying performance. You should target specific devices or device families and decide which functionality should be disabled to compensate for slower devices. There are a number of device specific properties that you can access to figure out the device.
Note: Android Marketplace does some additional compatibility filtering, so you should not bother that your ARMv7 only app optimized for OGLES2 is offered to some old slow devices.
Device Properties
| iPhoneSettings.uniqueIdentifier | Unique device identifier. |
| iPhoneSettings.model | Is it iPhone or iPod Touch? |
| iPhoneSettings.systemName | Operating system. |
| SystemInfo.operatingSystem | Operating system version. |
Anti-Piracy Check
It is not uncommon for pirates to hack applications by removing Apple DRM protection and redistributing them for free. Unity Android comes with anti-piracy check which allows you to determine if your application was altered after it was submitted to AppStore.
You can check if your application is genuine (not-hacked) by accessing iPhoneUtils.isApplicationGenuine property. If this property returns false you're free to notify user that he is using hacked application or you can disable access to some functions of your application.
Note: iPhoneUtils.isApplicationGenuineAvailable should be used along with iPhoneUtils.isApplicationGenuine to verify that application integrity can actually be confirmed.
Note: accessing iPhoneUtils.isApplicationGenuine property is reasonably expensive operation and you should never do it on a frame-to-frame basis.
Vibration Support
You can trigger device vibration by calling iPhoneUtils.Vibrate. However devices lacking vibration hardware will just ignore this call.
Standard Assets
"Standard Assets" is a folder with special meaning (same as "Plugins" and "Editor) and its content is compiled before all other scripts. You should keep your scripts in folders without special name.
Android-DotNet
iOS
Now Unity iOS supports two .NET API compatibility levels: .NET 2.0 and a subset of .NET 2.0 You can select the appropriate level in PlayerSettings.
.NET API 2.0
Unity for iPhone/iPad targets supports the .NET 2.0 API profile; It is close to the full .NET 2.0 API and offers best compatibility with pre-existing .NET code.
Pros:
- Better code compatibility with desktop Unity and third party libraries
- More features in standard the API set
Cons:
- Application build size is bigger
- Slightly worse application startup time
Note: Unity iOS does not support namespaces in the scripts. If you have third party library with the source, then the best practice is to compile this library outside Unity iOS Editor and drop library .dll file into Assets folder.
.NET 2.0 Subset
Unity iOS targets also support the .NET 2.0 Subset API profile. It is closest to the Mono "monotouch" profile, so many limitations that are applicable to the "monotouch" profile are also applicable for Unity iOS implementation of this .NET profile. More information on "monotouch" profile limitations can be found here.
Pros:
- Smaller application distribution size especially when stripping is not used
Cons:
- Worse compatibility with standard and third party libraries
Android
Unity Android supports two .NET API compatibility levels: .NET 2.0 and a subset of .NET 2.0 You can select the appropriate level in PlayerSettings.
.NET API 2.0
Unity Android targets supports the .NET 2.0 API profile; It is close to the full .NET 2.0 API and offers best compatibility with pre-existing .NET code.
Pros:
- Better code compatibility with desktop Unity and third party libraries
- More features in standard the API set
Cons:
- Application build size is bigger
- Slightly worse application startup time
Note: Unity Android does not support namespaces in the scripts. If you have third party library with the source, then the best practice is to compile this library outside Unity Android Editor and drop library .dll file into Assets folder.
.NET 2.0 Subset
Unity Android targets also support the .NET 2.0 Subset API profile. It is closest to the Mono "monotouch" profile, so many limitations that are applicable to the "monotouch" profile are also applicable for Unity Android implementation of this .NET profile. More information on "monotouch" profile limitations can be found here.
Pros:
- Smaller application distribution size especially when stripping is not used
Cons:
- Worse compatibility with standard and third party libraries
Android-Plugins
This page describes Native Code Plugins for Android.
Building a Plugin for Android
To build a plugin for Android, you should first obtain the Android NDK and familiarize yourself with the steps involved in building a shared library.
If you are using C++ (.cpp) to implement the plugin you must ensure the functions are declared with C linkage to avoid name mangling issues.
extern "C" {
float FooPluginFunction ();
}
Using Your Plugin from C#
Once built, the shared library should be copied to the folder. Unity will then find it by name when you define a function like the following in the C# script:-
[DllImport ("PluginName")]
private static extern float FooPluginFunction ();
Please note that PluginName should not include the prefix ('lib') nor the extension ('.so') of the filename. It is advisable to wrap all native code methods with an additional C# code layer. This code should check Application.platform and call native methods only when the app is running on the actual device; dummy values can be returned from the C# code when running in the Editor. You can also use platform defines to control platform dependent code compilation.
Deployment
For cross platform deployment, your project should include plugins for each supported platform (ie, libPlugin.so for Android, Plugin.bundle for Mac and Plugin.dll for Windows). Unity automatically picks the right plugin for the target platform and includes it with the player.
Using Java Plugins
The Android plugin mechanism also allows Java to be used to enable interaction with the Android OS.
Building a Java Plugin for Android
There are several ways to create a Java plugin but the result in each case is that you end up with a .jar file containing the .class files for your plugin. One approach is to download the JDK, then compile your .java files from the command line with javac. This will create .class files which you can then package into a .jar with the jar command line tool. Another option is to use the Eclipse IDE together with the ADT.
Using Your Java Plugin from Native Code
Once you have built your Java plugin (.jar) you should copy it to the folder in the Unity project. Unity will package your .class files together with the rest of the Java code and then access the code using the Java Native Interface (JNI). JNI is used both when calling native code from Java and when interacting with Java (or the JavaVM) from native code.
To find your Java code from the native side you need access to the Java VM. Fortunately, that access can be obtained easily by adding a function like this to your C/C++ code:
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* jni_env = 0;
vm->AttachCurrentThread(&jni_env, 0);
}
This is all that is needed to start using Java from C/C++. It is beyond the scope of this document to explain JNI completely. However, using it usually involves finding the class definition, resolving the constructor (<init>) method and creating a new object instance, as shown in this example:-
jobject createJavaObject(JNIEnv* jni_env) {
jclass cls_JavaClass = jni_env->FindClass("com/your/java/Class"); // find class definition
jmethodID mid_JavaClass = jni_env->GetMethodID (cls_JavaClass, "<init>", "()V"); // find constructor method
jobject obj_JavaClass = jni_env->NewObject(cls_JavaClass, mid_JavaClass); // create object instance
return jni_env->NewGlobalRef(obj_JavaClass); // return object with a global reference
}
Using Your Java Plugin with helper classes
AndroidJNIHelper and AndroidJNI can be used to ease some of the pain with raw JNI.
AndroidJavaObject and AndroidJavaClass automate a lot of tasks and also use cacheing to make calls to Java faster. The combination of AndroidJavaObject and AndroidJavaClass builds on top of AndroidJNI and AndroidJNIHelper, but also has a lot of logic in its own right (to handle the automation). These classes also come in a 'static' version to access static members of Java classes.
You can choose whichever approach you prefer, be it raw JNI through AndroidJNI class methods, or AndroidJNIHelper together with AndroidJNI and eventually AndroidJavaObject/AndroidJavaClass for maximum automation and convenience.
UnityEngine.AndroidJNI is a wrapper for the JNI calls available in C (as described above). All methods in this class are static and have a 1:1 mapping to the Java Native Interface. UnityEngine.AndroidJNIHelper provides helper functionality used by the next level, but is exposed as public methods because they may be useful for some special cases.
Instances of UnityEngine.AndroidJavaObject and UnityEngine.AndroidJavaClass have a 1:1 mapping to an instance of java.lang.Object and java.lang.Class (or subclasses thereof) on the Java side, respectively. They essentially provide 3 types of interaction with the Java side:
- Call a method
- Get the value of a field
- Set the value of a field
The Call is separated into two categories: Call to a 'void' method, and Call to a method with non-void return type. A generic type is used to represent the return type of those methods which return a non-void type. The Get and Set always take a generic type representing the field type.
Example 1
//The comments describe what you would need to do if you were using raw JNI
AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some_string");
// jni.FindClass("java.lang.String");
// jni.GetMethodID(classID, "<init>", "(Ljava/lang/String;)V");
// jni.NewStringUTF("some_string");
// jni.NewObject(classID, methodID, javaString);
int hash = jo.Call<int>("hashCode");
// jni.GetMethodID(classID, "hashCode", "()I");
// jni.CallIntMethod(objectID, methodID);
Here, we're creating an instance of java.lang.String, initialized with a string of our choice and retrieving the hash value for that string.
The AndroidJavaObject constructor takes at least one parameter, the name of class for which we want to construct an instance. Any parameters after the class name are for the constructor call on the object, in this case the string "some_string". The subsequent Call to hashCode() returns an 'int' which is why we use that as the generic type parameter to the Call method.
Note: You cannot instantiate a nested Java class using dotted notation. Inner classes must use the $ separator, and it should work in both dotted and slashed format. So android.view.ViewGroup$LayoutParams or android/view/ViewGroup$LayoutParams can be used, where a LayoutParams class is nested in a ViewGroup class.
Example 2
One of the plugin samples above shows how to get the cache directory for the current application. This is how you would do the same thing from C# without any plugins:-
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
// jni.FindClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
// jni.GetStaticFieldID(classID, "Ljava/lang/Object;");
// jni.GetStaticObjectField(classID, fieldID);
// jni.FindClass("java.lang.Object");
Debug.Log(jo.Call<AndroidJavaObject>("getCacheDir").Call<string>("getCanonicalPath"));
// jni.GetMethodID(classID, "getCacheDir", "()Ljava/io/File;"); // or any baseclass thereof!
// jni.CallObjectMethod(objectID, methodID);
// jni.FindClass("java.io.File");
// jni.GetMethodID(classID, "getCanonicalPath", "()Ljava/lang/String;");
// jni.CallObjectMethod(objectID, methodID);
// jni.GetStringUTFChars(javaString);
In this case, we start with AndroidJavaClass instead of AndroidJavaObject because we want to access a static member of com.unity3d.player.UnityPlayer rather than create a new object (an instance is created automatically by the Android UnityPlayer). Then we access the static field "currentActivity" but this time we use AndroidJavaObject as the generic parameter. This is because the actual field type (android.app.Activity) is a subclass of java.lang.Object, and any non-primitive type must be accessed as AndroidJavaObject. The exceptions to this rule are strings, which can be accessed directly even though they don't represent a primitive type in Java.
After that it is just a matter of traversing the Activity through getCacheDir() to get the File object representing the cache directory, and then calling getCanonicalPath() to get a string representation.
Of course, nowadays you don't need to do that to get the cache directory since Unity provides access to the application's cache and file directory with Application.temporaryCachePath and Application.persistentDataPath.
Example 3
Finally, here is a trick for passing data from Java to script code using UnitySendMessage.
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour {
void Start () {
JNIHelper.debug = true;
using (JavaClass jc = new JavaClass("com.unity3d.player.UnityPlayer")) {
jc.CallStatic("UnitySendMessage", "Main Camera", "JavaMessage", "whoowhoo");
}
}
void JavaMessage(string message) {
Debug.Log("message from java: " + message);
}
}
The Java class com.unity3d.player.UnityPlayer now has a static method UnitySendMessage, equivalent to the iOS UnitySendMessage on the native side. It can be used in Java to pass data to script code.
Here though, we call it directly from script code, which essentially relays the message on the Java side. This then calls back to the native/Unity code to deliver the message to the object named "Main Camera". This object has a script attached which contains a method called "JavaMessage".
Best practice when using Java plugins with Unity
As this section is mainly aimed at people who don't have comprehensive JNI, Java and Android experience, we assume that the AndroidJavaObject/AndroidJavaClass approach has been used for interacting with Java code from Unity.
The first thing to note is that any operation you perform on an AndroidJavaObject or AndroidJavaClass is computationally expensive (as is the raw JNI approach). It is highly advisable to keep the number of transitions between managed and native/Java code to a minimum, for the sake of performance and also code clarity.
You could have a Java method to do all the actual work and then use AndroidJavaObject / AndroidJavaClass to communicate with that method and get the result. However, it is worth bearing in mind that the JNI helper classes try to cache as much data as possible to improve performance.
//The first time you call a Java function like
AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some_string"); // somewhat expensive
int hash = jo.Call<int>("hashCode"); // first time - expensive
int hash = jo.Call<int>("hashCode"); // second time - not as expensive as we already know the java method and can call it directly
The Mono garbage collector should release all created instances of AndroidJavaObject and AndroidJavaClass after use, but it is advisable to keep them in a using(){} statement to ensure they are deleted as soon as possible. Without this, you cannot be sure when they will be destroyed. If you set AndroidJNIHelper.debug to true, you will see a record of the garbage collector's activity in the debug output.
//Getting the system language with the safe approach
void Start () {
using (AndroidJavaClass cls = new AndroidJavaClass("java.util.Locale")) {
using(AndroidJavaObject locale = cls.CallStatic<AndroidJavaObject>("getDefault")) {
Debug.Log("current lang = " + locale.Call<string>("getDisplayLanguage"));
}
}
}
You can also call the .Dispose() method directly to ensure there are no Java objects lingering. The actual C# object might live a bit longer, but will be garbage collected by mono eventually.
Extending the UnityPlayerActivity Java Code
With Unity Android it is possible to extend the standard UnityPlayerActivity class (the primary Java class for the Unity Player on Android, similar to AppController.mm on Unity iOS).
An application can override any and all of the basic interaction between Android OS and Unity Android. You can enable this by creating a new Activity which derives from UnityPlayerActivity (UnityPlayerActivity.java can be found at on Mac and usually at on Windows).
To do this, first locate the shipped with Unity Android. It is found in the installation folder (usually (on Windows) or (on Mac)) in a sub-folder called . Then add to the classpath used to compile the new Activity. The resulting .class file(s) should be compressed into a .jar file and placed in the folder. Since the manifest dictates which activity to launch it is also necessary to create a new AndroidManifest.xml. The AndroidManifest.xml file should also be placed in the folder.
The new activity could look like the following example, OverrideExample.java:
package com.company.product;
import com.unity3d.player.UnityPlayerActivity;
import android.os.Bundle;
import android.util.Log;
public class OverrideExample extends UnityPlayerActivity {
protected void onCreate(Bundle savedInstanceState) {
// call UnityPlayerActivity.onCreate()
super.onCreate(savedInstanceState);
// print debug message to logcat
Log.d("OverrideActivity", "onCreate called!");
}
public void onBackPressed()
{
// instead of calling UnityPlayerActivity.onBackPressed() we just ignore the back button event
// super.onBackPressed();
}
}
And this is what the corresponding AndroidManifest.xml would look like:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.product">
<application android:icon="@drawable/app_icon" android:label="@string/app_name">
<activity android:name=".OverrideExample"
android:label="@string/app_name"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
UnitPlayerNativeActivity
It is also possible to extend the UnityPlayerNativeActivity to reduce input latency. But be aware that NativeActivity was introduced in Gingerbread and does not work with older devices. Since touch/motion events are processed in native code java views would normally not see those events. There is however a forwarding mechanism in unity which allows events to be propagated to the DalvikVM. You need to set unityplayer.ForwardNativeEventsToDalvik to true to turn this feature on.
<?xml version="1.0" encoding="utf-8"?> <activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"> <meta-data android:name="android.app.lib_name" android:value="unity" /> <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" /> </activity>
Examples
Native Plugin Sample
A simple example of the use of a native code plugin can be found here
This sample demonstrates how C code can be invoked from a Unity Android application. The package includes a scene which displays the sum of two values as calculated by the native plugin. Please note that you will need the Android NDK to compile the plugin.
Java Plugin Sample
An example of the use of Java code can be found here
This sample demonstrates how Java code can be used to interact with the Android OS and how C++ creates a bridge between C# and Java. The scene in the package displays a button which when clicked fetches the application cache directory, as defined by the Android OS. Please note that you will need both the JDK and the Android NDK to compile the plugins.
Here is a similar example but based on a prebuilt JNI library to wrap the native code into C#.
Page last updated: 2012-01-16Android Splash Screen
iOS
Under iOS Basic, a default splash screen will be displayed while your game loads, oriented according to the Default Screen Orientation option in the Player Settings.
Users with an iOS Pro license can use any texture in the project as a splash screen. The size of the texture depends on the target device (320x480 pixels for 1-3rd gen devices, 1024x768 for iPad, 640x960 for 4th gen devices) and supplied textures will be scaled to fit if necessary. You can set the splash screen textures using the iOS Player Settings.
Android
Under Android Basic, a default splash screen will be displayed while your game loads, oriented according to the Default Screen Orientation option in the Player Settings.
Android Pro users can use any texture in the project as a splash screen. You can set the texture from the Splash Image section of the Android Player Settings. You should also select the Splash scaling method from the following options:-
- Center (only scale down) will draw your image at its natural size unless it is too large, in which case it will be scaled down to fit.
- Scale to fit (letter-boxed) will draw your image so that the longer dimension fits the screen size exactly. Empty space around the sides in the shorter dimension will be filled in black.
- Scale to fill (cropped) will scale your image so that the shorter dimension fits the screen size exactly. The image will be cropped in the longer dimension.
Android-Devices That Have Been Tested
Here is a list of what Android devices we test on and our users have informed us that they are able to develop on. If you are using a device that is not listed here and everything is working for you, then drop us an email at support@unity3d.com and tell us what the device is and what version of Android OS you are running on it. We will then update this list at the next update of unity. You can also find a list on our forum which will be updated more regularly.
|
ARMv7 devices | |
|
Device |
Android OS Versions |
|
Google Nexus One |
OS 2.1 and newer |
|
Google Nexus S |
OS 2.3 and newer |
|
Motorola Droid X |
OS 2.1 and newer |
|
Motorola Droid |
OS 2.1 and newer |
|
Motorola XT701 |
OS 2.1 |
|
HTC EVO 4G |
OS 2.1 and newer |
|
HTC Droid Incredible |
OS 2.1 and newer |
|
HTC Desire HD |
OS 2.1 and newer |
|
HTC Desire Z |
OS 2.1 and newer |
|
HTC Desire |
OS 2.1 and newer |
|
SE X10 |
OS 2.1 and newer |
|
Samsung Galaxy S |
OS 2.2 and newer |
|
Samsung Galaxy S (Fascinate) |
OS 2.1 |
|
Samsung Galaxy Tab |
OS 2.2 |
|
ARMv6 w/ VFP Devices | |
|
Device |
Android OS Versions |
|
Orange San Francisco / ZTE Blade |
OS 2.1 and newer |
|
SE X10 mini |
OS 2.1 and newer |
|
Samsung Galaxy 580 |
OS 2.1 and newer |
nacl-gettingstarted
Native Client (NaCl) is a new technology by Google which allows you to embed native executable code in web pages to allow deployment of very performant web apps without requiring the install of plugins. Currently, NaCl is only supported in Google Chrome on Windows, Mac OS X and Linux (with Chrome OS support being worked on), but the technology is open source, so it could be ported to other browser platforms in the future.
Unity 3.5 offers support to run Unity Web Player content (.unity3d files) using NaCl to allow content to be run without requiring a plugin install in Chrome. This is an early release - it should be stable to use, but it does not yet support all features supported in the Unity Web Player, because NaCl is an evolving platform, and does not support everything we can do in a browser plugin.
Building and Testing games on NaCl
Building and testing games on NaCl is very simple. You need to have Google Chrome installed. Simply choose "Web Player" in Build Settings, and tick the "Enable NaCl" checkbox. This will make sure the generated unity3d file can be run on NaCl (by including GLSL ES shaders needed for NaCl, and by disabling dynamic fonts not supported by NaCl), and install the NaCl runtime and a html file to launch the game in NaCl. If you click Build & Run, Unity will install your player as an app in Chrome and launch it automatically.
Shipping Games with NaCl
In it's current state, NaCl is not enabled for generic web pages in Chrome by default. While you can embed a NaCl player into any web page, and direct your users to manually enable NaCl in chrome://flags, the only way to currently ship NaCl games and have them work out of the box is to deploy them on the Chrome Web Store (for which NaCl is enabled by default). Note that the Chrome Web Store is fairly unrestrictive, and allows you to host content embedded into your own web site, or to use your own payment processing system if you like. The plan is that this restriction will be lifted when Google has finished a new technology called portable NaCl (PNaCl), which lets you ship executables as LLVM bitcode, thus making NaCl apps independent of any specific CPU architectures. Then NaCl should be enabled for any arbitrary web site.
Notes on Build size
When you make a NaCl build, you will probably notice that the unity_nacl_files_3.x.x folder is very large, over 100 MB. If you are wondering, if all this much data needs to be downloaded on each run for NaCl content, the answer is generally "no". There are two ways to serve apps on the Chrome Web Store, as a hosted or packaged app. If you serve your content as a packaged app, all data will be downloaded on install as a compressed archive, which will then be stored on the user's disk. If you serve your content as a hosted app, data will be downloaded from the web each time. But the nacl runtime will only download the relevant architecture (i686 or x86_64) from the unity_nacl_files_3.x.x folder, and when the web server is configured correctly, the data will be compressed on transfer, so the actual amount of data to be transferred should be around 10 MB (less when physics stripping is used). The unity_nacl_files_3.x.x folder contains a .htaccess file to set up Apache to compress the data on transfer. If you are using a different web server, you may have to set this up yourself.
Limitations in NaCl
NaCl does not yet support all the features in the regular Unity Web Player. Support for many of these will be coming in future versions of Chrome and Unity. Currently, NaCl these features are unsupported by NaCl:
- Webcam Textures
- Joystick Input
- Caching
- Dynamic Fonts
- Networking of any kind other then WWW class.
- The Profiler does not work, because it requires a network connection to the Editor.
- As with the standard webplayer plugin, native C/C++ plugins are not currently supported by NaCl.
The following features are supported, but have some limitations:
- Depth textures:
- Other graphics features:
- Cursor locking:
- NullReferenceExceptions:
softexceptions="1" to the embed parameters (set automatically by Unity when building a development player), to tell mono to do checking for NullReferences in software, which results in slower script execution but no crashes.
While Google does not give any system requirements for NaCl other then requiring at least OS X 10.6.7 on the Mac, we've found it to not work very well with old systems - especially when these systems have old GPUs or graphics drivers, or a low amount of installed main memory. If you need to target old hardware, you may find that the Web Player will give you a better experience.
Fullscreen mode:
Fullscreen mode is supported by setting Screen.fullScreen, but you can only enter fullscreen mode in a frame where the user has released the mouse button. NaCl will not actually change the hardware screen resolution, which is why Screen.resolutions will only ever return the current desktop resolution. However, Chrome supports rendering into smaller back buffers, and scaling those up when blitting to the screen. So, requesting smaller resolutions then the desktop resolution is generally supported for fullscreen mode, but will result in GPU based scaling, instead of changing the screen mode.
WWW class:
The WWW class is supported in NaCl, but follows different security policies then the Unity Web Player. While the Unity Web Player uses crossdomain.xml policy files, similar to flash, Unity NaCl has to follow the cross-origin security model followed by NaCl, documented here. Basically, in order to access html documents on a different domain then the player is hosted, you need to configure your web server to send a Access-Control-Allow-Origin respond header for the requests, which allows the domain hosting the player.
Communicating with browser javascript in NaCl
Interacting with the web page using JavaScript is supported, and is very similar to using the Unity Web Player, with one exception: The syntax for sending messages to Unity from html javascript is different, because it has to go through the NaCl module. When you are using the default Unity-generated html, then this code will work:
document.getElementById('UnityEmbed').postMessage("GameObject.Message(parameter");
Logging
Since NaCl does not allow access to the user file system, it will not write log files. Instead it outputs all logging to stdout. To see the player logs from NaCl:
- Do a Build & Run in the edtior once to make sure your game is installed into Chrome as an app.
- On Mac OS X, start Chrome from a Terminal, and start the app by clicking on it's icon. You should see the Unity player log output in the terminal.
- On Windows it's the same, but you need to set the NACL_EXE_STDOUT and NACL_EXE_STDERR environment variables, and start Chrome with the --no-sandbox option. See Google's documentation.
flash-gettingstarted
What is Unity Flash?
The Flash build option added at Unity 3.5 allows Unity to create swf (ShockWave Flash) files. These swf file can be played by a Flash plugin installed into your browser. Most computers in the world will either have a Flash Player installed, or can have one installed by visiting the Adobe Flash website. Just like a WebPlayer build creates a file with your 3d assets, audio, physics and scripts, Unity can build a SWF file. All the scripts from your game are automatically converted to ActionScript, which is the scripting language that the Flash Player works with.
Note that the Unity Flash build option exports SWF files for playback in your browser. The SWF is not intended for playback on mobile platforms.
Performance Comparison
We do not currently have direct comparisons of Unity webplayer content vs Flash SWF content. Much of our webplayer code is executed as native code, so for example, PhysX runs as native code. By comparison, when building a SWF file all of the physics runtime code (collision detection, newtonian physics) is converted to ActionScript. Typically you should expect the SWF version to run more slowly than the Unity webplayer version. We are, of course, doing everything we can to optimize for Flash.
Further reading:
Page last updated: 2011-12-21flash-setup
Installing Unity for Flash
To view the SWF files that Unity creates, your web browser will need Adobe Flash Player 11, which you can obtain from http://get.adobe.com/flashplayer/. If you have Flash Player already installed, please visit http://kb2.adobe.com/cps/155/tn_15507.html to check that you have at least version 11. Adobe Flash Player 11 introduced the Stage 3D Accelerated Graphics Rendering feature that Unity requires for 3d rendering.
For system requirements see http://www.adobe.com/products/flashplayer/tech-specs.html
Flash Player Switcher
Install Adobe AIR. This will allow you to switch between debug (slow) and regular (fast) versions of the Flash Player. The Flash Player Switcher can be obtained from: https://github.com/jvanoostveen/Flash-Player-Switcher/downloads (select FlashPlayerSwitcher.air). Note: it currently supports only Mac OS X.
Other Adobe Tools/Platforms
No other Adobe tools or platforms are required to develop with Unity and create SWF files. To embed the SWF that Unity builds into your own Flash Application you will need one of Adobe FlashBuilder/PowerFlasher FDT/FlashDeveloper/etc and be an experienced Flash developer. You will need to know:
- Your embedding application needs to be set to -swf-version=13 / fp11
- Your flash embeds wmode needs to be set to direct
flash-building
The following is a step-by-step guide to build and run a new project exported to Flash.
- Create your Unity content.
- Choose File->Build Settings to bring up the Build Settings dialog and add your scene(s).
- Change the Platform to Flash Player
- Tick Development Build. (This causes Unity to not compress the final SWF file. Not compressing will make the build faster, and also, the SWF file will not have to be decompressed before being run in the Flash Player. Note that an empty scene built using the Development Build option will be around 16M in size, compared to around 2M compressed.)
- Press the Build button.
Unity will build a SWF file at the location you choose. Additionally an html and swfobject.js file will be created. To view your Flash-built content open the html file. (Do not open the SWF file directly).
As with other build target there are Player settings that you can specify. Most of the Flash settings are shared with other platforms. Note that the resolution for the content is taken from the Standalone player settings.
Build-and-run will create the SWF file, launch your default browser and load the generated html file. Note that there is a swfobject.js file created with handles the checking for the Flash Player and browser integration.
The build will also give you a swc file, which allows you to load the swf in your own project. Embedding the Unity content in a standard flash project allows you to do GUI in Flash. This type of flash integration will of course not work in any of the other build targets.
We allow for a Flash API that gives you texture handles, which in combination with the swc embedding will give you means to do webcam, video, vector graphics from flash as textures.
Texture Support
We support jpeg textures, as well as RGBA / Truecolor. The compression ratio can be specified in the texture import under 'Override for FlashPlayer' setting. Compressed textures get converted to jpeg with the chosen compression ratio. The compression ratio is worth experimenting with since it can considerably reduce the size of the final SWF.

Texture quality ranges from 0 to 100, with 100 indicating no compression, and 0 the highest amount of compression possible. The maximum supported texture resolution is 2048x2048.
Build Errors and Warnings
The Build Process
The Unity Flash Publisher attempts to convert scripts from UnityScript into ActionScript. In this process, there can be two kinds of conversion errors: errors during conversion of unity code to ActionScript, and errors while compiling the converted code.
Errors during conversion will point to the original will have the familiar UnityScript error messages with file names and line numbers. If there are errors in the ActionScript, the error will take you to the message in the generated ActionScript code (with filenames ending with .as). It is possible that these ActionScript errors will not be easily understood. Just remember that the ActionScript is generated from your game script code, so any changes you need to make will be in your code and not the ActionScript.
Specific Errors and Warnings
1. What does this error message mean?
"Failed assemblies stripper ... Unhandled Exception: Mono.Linker.ResolutionException: Can not resolve reference: System.String UnityEngine.WWW::get_text()"
2. Why do I get:
'TerrainCollider' is not supported when building for FlashPlayer. 'TerrainData' is not supported when building for FlashPlayer. Asset: 'Assets/New Terrain.asset'
3a. Why do I get:
Error: Call to a possibly undefined method RuntimeServices_UnboxSingle_Object through a reference with static type Class.
- This is likely because the conversion between types that is defined on the UnityScript side is not defined for our Flash Publisher. Any time you see an error that refers to
Unboxit means a type conversion is required but cannot be found.
3b. What should I do about this?
- Do not forget to use
#pragma strict, and take care of all "implicit downcast" warning messages. - The rule of thumb is to avoid runtime casts from Object to primitive types (int, float, etc.). Also prefer containers with explicit types to generic ones, for example:
- System.Collections.Generic.List.<float> instead of Array
- Dictionary<string, float> instead of Hashtable
4. Why do I get
Error building Player: UnauthorizedAccessException: Access to the path "Temp/StagingArea/Data/ConvertedDotNetCode/global" is denied.
- If Unity-generated ActionScript files are open in a text editor, Unity may refuse to build issuing this error. To fix this, please close the ActionScript files and allow Unity to overwrite them.
flash-debugging
Where can I find my logfile!?
Make sure you've done all of the following:
1) Install "content debugger" version of the Adobe Flash Player plugin from: http://www.adobe.com/support/flashplayer/downloads.html
2) Go to http://flashplayerversion.com/, and make sure that it says 'Debugger: Yes'
3) Do not use Chrome. (It ships with its own flashplayer)
4) Create a file called mm.cfg which will instruct the Flash Player to create a logfile. mm.cfg file needs to be placed here:
| Macintosh OS X | /Library/Application Support/Macromedia/mm.cfg |
| XP | C:\Documents and Settings\username\mm.cfg |
| Windows Vista/Win7 | C:\Users\username\mm.cfg |
| Linux | /home/username/mm.cfg |
Write this text in the mm.cfg file:
ErrorReportingEnable=1 TraceOutputFileEnable=1
5) Find and open your flashlog.txt here:
| Macintosh OS X | /Users/username/Library/Preferences/Macromedia/Flash Player/Logs/ |
| XP | C:\Documents and Settings\username\Application Data\Macromedia\Flash Player\Logs |
| Windows Vista/Win7 | C:\Users\username\AppData\Roaming\Macromedia\Flash Player\Logs |
| Linux | /home/username/.macromedia/Flash_Player/Logs/ |
Note that whilst your content is running this flashlog.txt will constantly be updated as new debug messages are generated by your script code. You may need to reload the file or use an editor that can reload as the file grows in size.
More details about enabling debug logs when using SWFs is available at: http://livedocs.adobe.com/flex/3/html/help.html?content=logging_04.html.
Page last updated: 2011-12-21flash-whatssupported
Supported
- Lightmapping.
- Occlusion culling
- Editor Scripting (JavaScript / C# / Boo). Note: for JavaScript, use
#pragma strict. - Custom shaders.
- Animation / skinning
- Basic types like int, string, List.
- Basic audio features, such as AudioSource / AudioListener
- Physics
- Navigation Meshes
- Substance Textures, however the textures are baked at build time so cannot be dynamically changed at runtime.
- PlayerPrefs - On Flash PlayerPrefs are stored per SWF per machine.
- UnityGUI classes that do require text input
Limited support - features with potential issues
- Image Effects. Some image effects do not work on Flash.
- Realtime shadows work, but do get affected by bugs in image effects
- Untyped variables in JavaScript and implicit type conversions
- Unity GUI / Immediate mode GUI
- Any .NET specific stuff. Do not use stuff from exotic class libraries.
- GUIText wil have a dramatic impact on performance
Not supported
- Unity profiler
- Asset bundles
- UnityGUI classes that require text input
- WWW classes. Note that you can write your own ActionScript that uses Adobe networking APIs.
- Raknet networking (if you need networking, you can write it in Action Script 3 directly, using flash API)
- Terrain
- Cloth
- VertexLit shaders currently do not support Spot Lights (they are treated just like point lights).
- FileSystemWatcher, BinaryFormatter, HttpWebRequest do not work
- Advanced audio features, such as audio effects
- Deferred rendering
FAQ
The following is a list of common tasks in Unity and how to accomplish them.
- Unity 3.5 upgrade guide
- Upgrading your Unity Projects from 2.x to 3.x
- Activation
- Game Code Questions
- Graphics Questions
- How do I Import Alpha Textures?
- How do I Use Normal Maps?
- How do I use Detail Textures?
- How do I Make a Cubemap Texture?
- How do I Make a Skybox?
- How do I make a Mesh Particle Emitter? (Legacy Particle System)
- How do I make a Splash Screen?
- How do I make a Spot Light Cookie?
- How do I fix the rotation of an imported model?
- How do I use Water?
- HOWTO-exportFBX
- HOWTO-ArtAssetBestPracticeGuide
- How do I import objects from my 3D app?
- Workflow Questions
Upgrade guide for 3.4 to 3.5
If you have an FBX file with a root node marked up as a skeleton, it will be imported with an additional root node in 3.5, compared to 3.4

Unity 3.5 does this because when importing animated characters, the most common setup is to have one root node with all bones below and a skeleton next to it in the hierarchy. When creating additional animations, it is common to remove the skinned mesh from the fbx file. In that case the new import method ensures that the additional root node always exists and thus animations and the skinned mesh actually match.
If the connection between the instance and the FBX file's prefab has been broken in 3.4 the animation will not match in 3.5, and as a result your animation might not play.
In that case it is recommended that you recreate the prefabs or Game Object hierarchies by dragging your FBX file into your scene and recreating it.
Page last updated: 2012-02-03HowToUpgradeFrom2xTo3x
In our regular point releases of Unity, we make sure that projects from previous minor versions of the same major version are automatically upgraded when opened in the new editor for the first time. New properties are given default values, formats are converted and so on. However for major version changes such as 2.x to 3.x, we introduce several backwards-compatibility breaking changes.
While the primary visibility of this is the fact that content authored in the previous version will play back slightly differently when run in the new engine, some changes require more than a few property tweaks to play just like you want them to. These documents outlines those changes from 2.x to 3.x:
- Physics upgrade details
- Mono Upgrade Details
- Rendering upgrade details
- Unity 3.x Shader Conversion Guide
PhysicsUpgradeDetails
For Unity 3.0, we upgraded the NVIDIA PhysX library from version 2.6 to 2.8.3, to give you access to many new features. Generally for existing projects, the behavior should be roughly the same as in Unity 2.x, but there may be slight differences in the outcome of physics simulation, so if your content depends on the exact behavior or on chain reactions of physical events, you may have to re-tweak your setup to work as expected in Unity 3.x.
If you are using Configurable Joints, the JointDrive.maximumForce property will now also be taken into consideration when JointDrive.mode is JointDriveMode.Position. If you have set this value to the default value of zero, the joint will not apply any forces. We will automatically change all JointDrive properties imported from old versions if JointDrive.mode is JointDriveMode.Position, but when you set up a joint from code, you may have to manually change this. Also, note that we have changed the default value for JointDrive.maximumForce to infinity.
Page last updated: 2010-09-25MonoUpgradeDetails
In Unity 3 we upgraded the mono runtime from 1.2.5 to 2.6 and on top of that, there are some JavaScript and Boo improvements. Aside from all bug fixes and improvements to mono between the two versions, this page lists some of the highlights.
C# Improvements
Basically the differences betweeen C# 3.5 and C# 2.0, including:
JavaScript Improvements
- Compiler is now 4x faster;
- 'extends' no longer can be used with interfaces, unityscript now have 'implements' for that purpose (see below);
- Added support for consuming generic types such as generic collections:
var list = new System.Collections.Generic.List.<String>();
list.Add("foo");
- Added support for anonymous functions/closures:
list.Sort(function(x:String, y:String) {
return x.CompareTo(y);
});
- Which include a simplified lambda expression form with type inference for the parameters and return value:
list.Sort(function(x, y) x.CompareTo(y));
- Function types:
function forEach(items, action: function(Object)) {
for (var item in items) action(item);
}
- Type inferred javascript array comprehensions:
function printArray(a: int[]) {
print("[" + String.Join(", ", [i.ToString() for (i in a)]) + "]");
}
var doubles = [i*2 for (i in range(0, 3))];
var odds = [i for (i in range(0, 6)) if (i % 2 != 0)];
printArray(doubles);
printArray(odds);
- Added support for declaring and implementing interfaces:
interface IFoo {
function bar();
}
class Foo implements IFoo {
function bar() {
Console.WriteLine("Foo.bar");
}
}
- All functions are now implicitly virtual, as a result the 'virtual' keyword has been deprecated and the 'final' keyword has been introduced to allow for non virtual methods to be defined as:
final function foo() {
}
- Value types (structs) can be defined as classes inheriting from System.ValueType:
class Pair extends System.ValueType {
var First: Object;
var Second: Object;
function Pair(fst, snd) {
First = fst;
Second = snd;
}
override function ToString() {
return "Pair(" + First + ", " + Second + ")";
}
}
Boo Improvements
- Boo upgrade to version 0.9.4.
RenderingUpgradeDetails
Unity 3 brings a lot of graphics related changes, and some things might need to be tweaked when you upgrade existing Unity 2.x projects. For changes related to shaders, see Shader Upgrade Guide.
Forward Rendering Path changes
Unity 2.x had one rendering path, which is called Forward in Unity 3. Major changes in it compared to Unity 2.x:
- Most common case (one directional per-pixel light) is drawn in one pass now! (used to be two passes)
- Point & Spot light shadows are not supported. Only one Directional light can cast shadows. Use Deferred Lighting path if you need more shadows.
- Most "Vertex" lights replaced with Spherical Harmonics lighting.
- Forward rendering path is purely shader based now, so it works on OpenGL ES 2.0, Xbox 360, PS3 (i.e. platforms that don't support fixed function rendering).
Shader changes
See Shader Upgrade Guide for more details. Largest change is: if you want to write shaders that interact with lighting, you should use Surface Shaders.
Obscure Graphics Changes That No One Will Probably Notice TM
- Removed Mac Radeon 9200 pixel shader support (
!!ATIfsassembly shaders). - Removed support for per-pixel lighting on pre-ShaderModel2.0 hardware. As a result, Diffuse Fast shader is just VertexLit now.
- Removed non-attenuated lights. All point and spot lights are attenuated now.
- Removed script callbacks:
OnPreCullObjectandRenderBeforeQueuesattribute. - Removed p-buffer based RenderTextures. RenderTextures on OpenGL require FBO support now.
- Most Pass LightMode tags are gone, and replaced with new tags. You should generally be using Surface Shaders for that stuff anyway.
- Texture instanceIDs are not OpenGL texture names anymore. Might affect C++ Plugins that were relying on that; use
texture.GetNativeTextureID()instead. - Rename shader keywords SHADOWS_NATIVE to SHADOWS_DEPTH; SHADOWS_PCF4 to SHADOWS_SOFT.
- Removed ambient boost on objects that were affected by more than 8 vertex lights.
- Removed
_ObjectSpaceCameraPosand_ObjectSpaceLightPos0(added_WorldSpaceCameraPosand_WorldSpaceLightPos0). LightmapModetag in shader texture property does nothing now.- Skybox shaders do not write into depth buffer.
GrabPass(i.e. refractive glass shader) now always grabs texture of the size of the screen.#pragma multi_compile_vertexand#pragma multi_compile_fragmentare gone.- Polygon offset in ShaderLab can't reference variables anymore (like
Offset [_Var1], [_Var2]). - Renamed
TRANSFER_EYEDEPTH/OUTPUT_EYEDEPTHtoUNITY_TRANSFER_DEPTH/UNITY_OUTPUT_DEPTH. They also work on a float2 in Unity 3. - Removed special shader pass types: R2TPass, OffscreenPass.
- Removed
_Light2World0,_World2Light0built-in shader matrices. - Removed _SceneAmbient, _MultiModelAmbient, _MultiAmbient, _ModelAmbient, _MultiplyFog, _LightHackedDiffuse0, _ObjectCenterModelLightColor0 built-in shader vectors.
- Removed
_FirstPassbuilt-in shader float. - Fog mode in shader files can't come from variable (like
Fog { Mode [_MyFogMode] }). To use global fog mode, writeFog { Mode Global }. - Removed
BlendColorcolor from ShaderLab. - Removed support for declaring texture matrix by-value in shader property.
- Removed support for "static" shader properties.
- Removed support for texture border color (
RenderTexture.SetBorderColor). - Removed
ColorMaterial Ambient, Diffuse, Specularsupport (ColorMaterial AmbientAndDiffuse & Emission left). Support for the removed ones varied a lot depending on the platform causing confusion; and they didn't seem to be very useful anyway. - Built-in
_CameraToWorldand_WorldToCameramatrices now do what you'd expect them to do. Previously they only contained the rotation part, and camera-to-world was flipped on Y axis. Yeah, we don't know how that happened either :) - Removed
Shader.ClearAll(). Was deprecated since 2007, time to let it go. - Vertex shaders are compiled to Shader Model 2.0 now (before was 1.1). If you want to compile to SM1.1, add
#pragma target 1.1in the shader.
SL-V3Conversion
Unity 3 has many new features and changes to its rendering system, and ShaderLab did update accordingly. Some advanced shaders that were used in Unity 2.x, especially the ones that used per-pixel lighting, will need update for Unity 3. If you have trouble updating them - just ask for our help!
For general graphics related Unity 3 upgrade details, see Rendering Upgrade Details.
When you open your Unity 2.x project in Unity 3.x, it will automatically upgrade your shader files as much as possible. The document below lists all the changes that were made to shaders, and what to do when you need manual shader upgrade.
Per-pixel lit shaders
In Unity 2.x, writing shaders that were lit per-pixel was quite complicated. Those shaders would have multiple passes, with LightMode tags on each (usually PixelOrNone, Vertex and Pixel). With addition of Deferred Lighting in Unity 3.0 and changes in old forward rendering, we needed an easier, more robust and future proof way of writing shaders that interact with lighting. All old per-pixel lit shaders need to be rewritten to be Surface Shaders.
Cg shader changes
Built-in "glstate" variable renames
In Unity 2.x, accessing some built-in variables (like model*view*projection matrix) was possible through built-in Cg names like glstate.matrix.mvp. However, that does not work on some platforms, so in Unity 3.0 we renamed those built-in variables. All these replacements will be done automatically when upgrading your project:
glstate.matrix.mvpto UNITY_MATRIX_MVPglstate.matrix.modelview[0]to UNITY_MATRIX_MVglstate.matrix.projectionto UNITY_MATRIX_Pglstate.matrix.transpose.modelview[0]to UNITY_MATRIX_T_MVglstate.matrix.invtrans.modelview[0]to UNITY_MATRIX_IT_MVglstate.matrix.texture[0]to UNITY_MATRIX_TEXTURE0glstate.matrix.texture[1]to UNITY_MATRIX_TEXTURE1glstate.matrix.texture[2]to UNITY_MATRIX_TEXTURE2glstate.matrix.texture[3]to UNITY_MATRIX_TEXTURE3glstate.lightmodel.ambientto UNITY_LIGHTMODEL_AMBIENTglstate.matrix.textureto UNITY_MATRIX_TEXTURE
Semantics changes
Additionally, it is recommended to use SV_POSITION (instead of POSITION) semantic for position in vertex-to-fragment structures.
More strict error checking
Depending on platform, shaders might be compiled using a different compiler than Cg (e.g. HLSL on Windows) that has more strict error checking. Most common cases are:
- All vertex/fragment shader inputs and outputs need to have "semantics" assigned to them. Unity 2.x allowed to not assign any semantics (in which case some TEXCOORD would be used); in Unity 3.0 semantic is required.
- All shader output variables need to be written into. For example, if you have a
float4 color : COLORas your vertex shader output, you can't just write intorgband leave alpha uninitialized.
Other Changes
RECT textures are gone
In Unity 2.x, RenderTextures could be not power of two in size, so called "RECT" textures. They were designated by "RECT" texture type in shader properties and used as samplerRECT, texRECT and so on in Cg shaders. Texture coordinates for RECT textures were a special case in OpenGL: they were in pixels. In all other platforms, texture coordinates were just like for any other texture: they went from 0.0 to 1.0 over the texture.
In Unity 3.0 we have decided to remove this OpenGL special case, and treat non power of two RenderTextures the same everywhere. It is recommended to replace samplerRECT, texRECT and similar uses with regular sampler2D and tex2D. Also, if you were doing any special pixel adressing for OpenGL case, you need to remove that from your shader, i.e. just keep the non-OpenGL part (look for SHADER_API_D3D9 or SHADER_API_OPENGL macros in your shaders).
Activation
The Unity application requires activation before it can be used. The version you download contains both Unity and Unity Pro. Upon launching Unity, you will be take to our online activation, where you can choose to get Unity, or do a 30 day Unity Pro Trial. No personal information is needed.
If you've bought Unity, you will receive a serial number by email. This code is unique to each customer, and should not be lost or shared with others. An serial number is a string of characters and looks like XY-ABCD-1234-EFGH-5678-IJ90. When you activate Unity you need to enter this number. The licensing system will take a finger-print of your hardware and system software and send this finger-print to our servers. This locks your computer to your serial number. The end-user license agreement typically permits you to install Unity on up to two computers. If you attempt to activate Unity on a third computer you will be told that your activation limit has been exceeded. (Note that academic and/or discounted versions of Unity may be restricted to a single computer. Please check before purchasing what restrictions will apply to you.)
Note: The finger-printing is affected by many things. For example, if you were to re-install your operating system, or re-format a hard drive, or change the network card, these things will cause the unique finger-print of your computer to change.
When you attempt to re-activate Unity you may find that you are told you are unable to reactivate because your activation limit has been exceeded. This is not an error but reflects the fact that our server sees that your computer has changed. To help customers who have suffered from catastrophic computer failure we offer a Unity migration service. To take advantage of this service please email support@unity3d.com and provide as much information as possible about what has happened to your computer. Please also provide your Serial Number. We will then help you with the migration.
Common Questions
My computer cannot talk to your activation server. What can I do?
We have created a webpage to allow customers who have had difficulty activating online or wish to activate on a machine that is not connected to the internet, to create the activation file for themselves. The page is:
https://store.unity3d.com/manual/
If you are using Unity (the free version) click the Free activation tickbox and upload your ILR file, then click Activate Unity. Otherwise type in your serial number in the field provided. Within a second or two an ILF file should be downloaded to your computer.
When you restart Unity, please go to the Activation window (either it will start up on launch, or choose Help>Enter Serial Number (win) or Unity>Enter Serial Number (osx)). Select Manual Activation, click Next, then click "Read License" and choose the license file you downloaded above. Click Next, and Unity will read the file, and your activation should be complete!
Please activate Unity using manual activation. To do this, please contact support who will guide you through the process.
I need to migrate Unity from one machine to another. What do I need to do? Firstly, uninstall Unity from your "old" machine. Then contact support asking for assistance with migration. If you are mid-way through a critical period in your game development, please plan carefully for this migration. In addition to moving your project from your old machine to your new one, re-installing applications and so on, plan ahead for contacting support. Bear in mind that you can use Unity on two machines, so there should be no time when you are unable to continue development. The email will need to include the following:
- The Serial number you are using
- The name of the machine you are migrating from
- The name of the machine you are migrating to
- The name of the individual the Serial has been assigned to
My hard drive has died. What do I need to do? If you cannot uninstall Unity because your hard drive has failed write and tell the support team who will try to help. Please remember that we can't back up your project and we can only help you installing Unity on a working computer :)
How many activations can I make? Your serial number is good for 2 (two) activations.
I have received an activation code when I upgraded to Unity iOS. Why does the old one no longer work? The iOS products are an extension to your Unity or Unity Pro license. When you upgrade to Unity iOS the serial number you receive replaces your original activation code. The new serial number will work for your existing Unity installation.
Can I use the same serial number on a PC and a Mac? Yes, the same serial number can be used on a PC or a Mac. As per your end-user license agreement you can use Unity on two machines that you own and have exclusive use of. These two machines could be two Macs, two PCs or one PC and one Mac, whatever works best for you.
Can I use the same serial number on a laptop and a desktop? Yes, the serial number will work on laptops and desktops.
Will uninstalling Unity from an old machine automatically allow for activation on my new machine? No, The Unity Support Team will have to allow for migration of your license, meaning you can then proceed to activate on your new machine.
Can I use Unity3 with a 2.x Serial? No, in order to use Unity 3, youd need to upgrade to a 3.x license. You can do this Online, via our Website store. https://store.unity3d.com/shop/
My license wont activate using the online activation procedure! This may be due to one of many things. The easiest way around this, is to activate using the Manual Activation procedure. You can find out how by following the link below: http://answers.unity3d.com/questions/205/manual-offline-activation-of-unity
I have replaced an item of Hardware, now my copy of Unity needs to be re-registered. Unity creates a licensing file that takes information from a number of places within your machine, making the file unique. When an item of Hardware is replaced, our Licensing servers will see this as a request from a new machine. As with the migration procedure, you'll need to email the Support Team (support@unity3d.com) in order for them to reactivate your license.
The Editor freezes when waiting for a response from the Activation Server. In some cases the Online Activation process seems to 'Hang' and takes a little longer than expected, when waiting for a response from the Activation Server. We advise that you wait it out for 5-10 minutes before exiting the Editor. Give the Manual activation process (Stated above) a try if the Online activation continues to hang!
Please read the FAQ before contacting support@unity3d.com, as most Licensing cases are pretty trivial. Please let me know if you feel something that hasn't been covered here, ought to be.
Page last updated: 2011-07-06Game Code How-to
Page last updated: 2007-11-16HOWTO-First Person Walkthrough
Here's how you can make a simple first person walk-through with your own artwork:
- Import your level. See here on how to import geometry from your art package into Unity.
- Select the imported model file and enable Generate Colliders in the Import Settings in the Inspector.
- Locate the in the Project View and drag it into the Scene View.
- Make sure that the scale of your level is correct. The First Person Controller is exactly 2 meters high, so if your level doesn't fit the size of the controller, you should adjust the scale of the level size within your modeling application. Getting scale right is critical for physical simulation, and other reasons documented at the bottom of this page. Using the wrong scale can make objects feel like they are floating or too heavy. If you can't change the scale in your modeling app, you can change the scale in the Import Settings... of the model file.
- Move the First Person Controller to be at the start location using the Transform handles. It is critical that the first person controller does not intersect any level geometry, when starting the game (otherwise it will be stuck!).
- Remove the default camera "Main Camera" in the hierarchy view. The First person controller already has its own camera.
- Hit Play to walk around in your own level.
Graphics how-tos
The following is a list of common graphics-related questions in Unity and how to accomplish them.
There is an excellent tutorial for creating textures, including color, bump, specular, and reflection mapping here.
- How do I Import Alpha Textures?
- How do I Use Normal Maps?
- How do I use Detail Textures?
- How do I Make a Cubemap Texture?
- How do I Make a Skybox?
- How do I make a Mesh Particle Emitter? (Legacy Particle System)
- How do I make a Splash Screen?
- How do I make a Spot Light Cookie?
- How do I fix the rotation of an imported model?
- How do I use Water?
HOWTO-alphamaps
Unity uses straight alpha blending. Hence, you need to expand the color layers... The alpha channel in Unity will be read from the first alpha channel in the Photoshop file.
Setting Up
Before doing this, install these alpha utility photoshop actions: AlphaUtility.atn.zip
After installing, your Action Palette should contain a folder called AlphaUtility:

Getting Alpha Right
Let's assume you have your alpha texture on a transparent layer inside photoshop. Something like this:

- Duplicate the layer
- Select the lowest layer. This will be source for the dilation of the background.
- Select and apply with the default properties
- Run the "Dilate Many" action a couple of times. This will expand the background into a new layer.
- Select all the dilation layers and merge them with
- Create a solid color layer at the bottom of your image stack. This should match the general color of your document (in this case, greenish).
Now we need to copy the transparency into the alpha layer.
- Set the selection to be the contents of your main layer by Command-clicking on it in the Layer Palette.
- Switch to the channels palette.
- Create a new channel from the transparency.
Save your PSD file - you are now ready to go.
Page last updated: 2010-09-10HOWTO-Normalmap
Normal maps are grayscale images that you use as a height map on your objects in order to give an appearance of raised or recessed surfaces. Assuming you have a model that looks like this:

The 3D Model

The Texture
We want to make the light parts of the object appear raised.
- Draw a grayscale height map of your texture in Photoshop. White is high, black is low. Something like this:
- Save the image next to your main texture.
- In Unity, select the image and select the 24 bit RGB format and enable Generate Normal Map in the Import Settings in the Inspector:
- In the Material Inspector of your model, select 'Bumped Diffuse' from the Shader drop-down:
- Drag your texture from the Project window to the 'Normalmap' texture slot:
Your object now has a normal map applied:

Hints
- To make the bumps more noticable, either use the Bumpyness slider in the Texture Import Settings or blur the texture in Photoshop. Experiment with both approaches to get a feel for it.
HOWTO-UseDetailTexture
A Detail texture is a small, fine pattern which is faded in as you approach a surface, for example wood grain, imperfections in stone, or earthly details on a terrain. They are explicitly used with the Diffuse Detail shader.
Detail textures must tile in all directions. Color values from 0-127 makes the object it's applied to darker, 128 doesn't change anything, and lighter colors make the object lighter. It's very important that the image is centered around 128 - otherwise the object it's applied to will get lighter or darker as you approach.
- Draw or find a grayscale image of the detail texture.

The Detail Texture
The Levels - Save the image next to your main texture.
- In Unity, select the image and under "Generate Mip Maps", enable Fades Out and set the sliders to something like this in the Import Settings in the Inspector.
- The top slider determines how small the texture should before before beginning to fade out, and the bottom determines how far away it is before the detail texture completely disapear.

s. - In the Material Inspector on the right, select from the Shader drop-down:
- Drag your texture from the Project View to the Detail texture slot.
- Set the Tiling values to a high value
HOWTO-MakeCubemap
Cubemaps are used by the Reflective built-in shaders. To build one, you either create six 2D textures and create a new Cubemap asset, or build the Cubemap from a single square texture. More details are in the Cubemap Texture documentation page.
Static and dynamic cubemap reflections can also be rendered from scripts. Code example in Camera.RenderToCubemap page contains a simple wizard script for rendering cubemaps straight from the editor.
Page last updated: 2010-09-10HOWTO-UseSkybox
A Skybox is a 6-sided cube that is drawn behind all graphics in the game. Here are the steps to create one:
- Make 6 textures that correspond to each of the 6 sides of the skybox and put them into your project's Assets folder.
- For each texture you need to change the wrap mode from Repeat to Clamp. If you don't do this colors on the edges will not match up:
- Create a new Material by choosing from the menu bar.
- Select the shader drop-down in the top of the Inspector, choose .
- Assign the 6 textures to each texture slot in the material. You can do this by dragging each texture from the Project View onto the corresponding slots.
To Assign the skybox to the scene you're working on:
- Choose from the menu bar.
- Drag the new Skybox Material to the Skybox Material slot in the Inspector.
Note that Standard Assets package contains several ready-to-use skyboxes - this is the quickest way to get started!
Page last updated: 2007-11-16HOWTO-MeshParticleEmitter
Mesh Particle Emitters are generally used when you need high control over where to emit particles.
For example, when you want to create a flaming sword:
- Drag a mesh into the scene.
- Remove the Mesh Renderer by right-clicking on the Mesh Renderer's Inspector title bar and choose Remove Component.
- Choose from the menu.
- Choose from the menu.
- Choose from the menu.
You should now see particles emitting from the mesh.
Play around with the values in the Mesh Particle Emitter.
Especially enable Interpolate Triangles in the Mesh Particle Emitter Inspector and set Min Normal Velocity and Max Normal Velocity to 1.
To customize the look of the particles that are emitted:
- Choose from the menu bar.
- In the Material Inspector, select from the shader drop-down.
- Drag & drop a texture from the Project view onto the texture slot in the Material Inspector.
- Drag the Material from the Project View onto the Particle System in the Scene View.
You should now see textured particles emitting from the mesh.
See Also
Page last updated: 2012-01-17HOWTO-SplashScreen
Desktop
Here's how to do a splash screen or any other type of full-screen image in Unity. This method works for multiple resolutions and aspect ratios.
- First you need a big texture. Ideally textures should be power of two in size. You might for example use 1024x512 as this fits most screens.
- Make a box using the menubar item.
- Scale it to be in 16:9 format by entering 16 and 9 as the first two value in the Scale:
- Drag the texture onto the cube and make the Camera point at it. Place the camera at such a distance so that the cube is still visible on a 16:9 aspect ratio. Use the Aspect Ratio Selector in the Scene View menu bar to see the end result.
iOS
Android
Page last updated: 2011-02-22
HOWTO-LightCookie
Unity ships with a few Light Cookies in the Standard Assets. When the Standard Assets are imported to your project, they can be found in . This page shows you how to create your own.
A great way to add a lot of visual detail to your scenes is to use cookies - grayscale textures you use to control the precise look of in-game lighting. This is fantastic for making moving clouds and giving an impression of dense foilage. The Light Component Reference page has more info on all this, but the main thing is that for textures to be usable for cookies, the following properties need to be set:
To create a light cookie for a spot light:
- Paint a cookie texture in Photoshop. The image should be greyscale. White pixels means full lighting intensity, black pixels mean no lighting. The borders of the texture need to be completely black, otherwise the light will appear to leak outside of the spotlight.
- In the Texture Inspector change the Repeat Wrap mode to Clamp
- Select the Texture and edit the following Import Settings in the Inspector.
- Enable Border Mipmaps
- Enable Build Alpha From Grayscale (this way you can make a grayscale cookie and Unity converts it to an alpha map automatically)
- Set the Texture Format to Alpha 8 Bit

HOWTO-FixZAxisIsUp
Some 3D art packages export their models so that the z-axis faces upward. Most of the standard scripts in Unity assume that the y-axis represents up in your 3D world. It is usually easier to fix the rotation in Unity than to modify the scripts to make things fit.

Your model with z-axis points upwards
If at all possible it is recommended that you fix the model in your 3D modelling application to have the y-axis face upwards before exporting.
If this is not possible, you can fix it in Unity by adding an extra parent transform:
- Create an empty GameObject using the menu
- Position the new GameObject so that it is at the center of your mesh or whichever point you want your object to rotate around.
- Drag the mesh onto the empty GameObject
You have now made your mesh a Child of an empty GameObject with the correct orientation. Whenever writing scripts that make use of the y-axis as up, attach them to the Parent empty GameObject.

The model with an extra empty transform
Page last updated: 2007-11-16HOWTO-Water
Note: The content on this page applies to the desktop editor mode only.
Unity includes several water prefabs (including needed shaders, scripts and art assets) within the Standard Assets and Pro Standard Assets packages. Unity includes a basic water, while Unity Pro includes water with real-time reflections and refractions, and in both cases those are provided as separate daylight and nighttime water prefabs.

Reflective daylight water (Unity Pro)

Reflective/Refractive daylight water (Unity Pro)
Water setup
In most cases you just need to place one of the existing Prefabs into your scene (make sure to have the Standard Assets installed):
- Unity has Daylight Simple Water and Nighttime Simple Water in .
- Unity Pro has Daylight Water and Nighttime Water in (but it needs some assets from as well). Water mode (Simple, Reflective, Refractive) can be set in the Inspector.
The prefab uses an oval-shaped mesh for the water. If you need to use a different Mesh the easiest way is to simply change it in the Mesh Filter of the water object:

Creating water from scratch (Advanced)
The simple water in Unity requires attaching a script to a plane-like mesh and using the water shader:
- Have mesh for the water. This should be a flat mesh, oriented horizontally. UV coordinates are not required. The water GameObject should use the Water layer, which you can set in the Inspector.
- Attach WaterSimple script (from ) to the object.
- Use shader in the material, or tweak one of provided water materials ( or ).
The reflective/refractive water in Unity Pro requires similar steps to set up from scratch:
- Have mesh for the water. This should be a flat mesh, oriented horizontally. UV coordinates are not required. The water GameObject should use the Water layer, which you can set in the Inspector.
- Attach Water script (from ) to the object.
- Water rendering mode can be set in the Inspector: Simple, Reflective or Refractive.
- Use shader in the material, or tweak one of provided water materials ( or ).
Properties in water materials
These properties are used in Reflective & Refractive water shader. Most of them are used in simple water shader as well.
| Wave scale | Scaling of waves normal map. The smaller the value, the larger water waves. |
| Reflection/refraction distort | How much reflection/refraction is distorted by the waves normal map. |
| Refraction color | Additional tint for refraction. |
| Environment reflection/refraction | Render textures for real-time reflection and refraction. |
| Normalmap | Defines the shape of the waves. The final waves are produced by combining two these normal maps, each scrolling at different direction, scale and speed. The second normal map is half as large as the first one. |
| Wave speed | Scrolling speed for first normal map (1st and 2nd numbers) and the second normal map (3rd and 4th numbers). |
| Fresnel | A texture with alpha channel controlling the Fresnel efffect - how much reflection vs. refraction is visible, based on viewing angle. |
The rest of properties are not used by Reflective & Refractive shader by itself, but need to be set up in case user's video card does not suppor it and must fallback to the simpler shader:
| Reflective color/cube and fresnel | A texture that defines water color (RGB) and Fresnel effect (A) based on viewing angle. |
| Horizon color | The color of the water at horizon. (Used only in the simple water shader) |
| Fallback texture | Texture used to represent the water on really old video cards, if none of better looking shaders can't run on it. |
Hardware support
- Reflective + Refractive water works on graphics cards with pixel shader 2.0 support (GeForce FX and up, Radeon 9500 and up, Intel 9xx). On older cards, Reflective water is used.
- Reflective water works on graphics cards with pixel shader 1.4 support (GeForce FX and up, Radeon 8500 and up, Intel 9xx). On older cards, Simple water is used.
- Simple water works about everywhere, with various levels of detail depending on hardware capabilities.
HOWTO-exportFBX
FBX export guide
Unity supports FBX files which can be generated from many popular 3D applications. Use this guideline to help ensure the most reliable results.
Select > Prepare > Check Settings > Use 2011.3 > Verify > Import
What do you want to export? - be aware of export scope e.g. meshes, cameras, lights, animation rigs, etc.
- Applications often let you export selected objects or a whole scene
- Make sure you are exporting only the objects you want to use from your scene by either exporting selected, or removing unwanted data from your scene.
- Good working practice often means keeping a working file with all lights, guides, control rigs etc. but only export the data you need with export selected, an export preset or even a custom scene exporter.
What do you need to include? - prepare your assets:
- Meshes - Remove construction history, convert to polygons and triangulate or quadrangulate if necessary
- Animation - Select the correct rig, check frame rate, animation length etc.
- Textures - Make sure your textures are sourced already from your Unity project or copied into a folder called \textures in your project
- Smoothing - Check if you want smoothing groups and/or smooth mesh
How do I include those elements? - check the FBX export settings
- Be aware of your settings in the export dialogue so that you know what to expect and can match up the fbx settings In Unity - see figs 1, 2 & 3 below
Which version of FBX are you using? if in doubt use 2011.3
- Autodesk update their FBX installer regularly and it can provide different results with different versions of their own software and other 3rd party 3D apps.
- See Advanced Options > FBX file format
Will it work? - Verify your export
- Check your file size - do a sanity check on the file size (e.g. >10kb?)
- Re-import your FBX into a new scene in the 3D package you use to generate it - is it what you expected?
Import!
- Import into Unity
- Check FBX import settings in inspector : texures, animations, smoothing, etc.
See below for Maya FBX dialogue example:
Fig 1 General & Geometry

Fig 2 Animation and other attributes

Fig 3 Lights, Advanced options and Version

HOWTO-ArtAssetBestPracticeGuide
Unity supports textured 3D models from a variety of programs or sources. This short guide has been put together by games artists with developers at Unity, to help you create assets that work better and more efficiently in your Unity project.
Scale & Units
- Set your system and project units for your software to work consistently with Unity e.g. Metric.
- Working to scale can be important for both lighting and physics simulation;
- Be aware for example; Max system unit default is inches and Maya is centimetres.
- Unity has different scaling for FBX and 3D application files on import, check FBX import scale setting in Inspector.
- If in doubt export a metre cube with your scene to match in Unity.
- Animation frame rate defaults can be different in packages, is a good idea to set consistently across your pipeline – e.g. 30fps for example.
Files & Objects
- Name objects in your scene sensibly and uniquely – this can help you locate and troubleshoot specific meshes in your project:
- Avoid special characters *()?ӣ$n etc.
- Use simple but descriptive names for both objects and files (allow for duplication later).
- Keep your hierarchies as simple as you can.
- With big projects in your 3D application, consider having a working file outside your Unity project directory – this can often avert time consuming updates and importing unnecessary data.

Sensibly named objects help you find stuff quickly
Mesh
- Build with an efficient topology – use polygons only where you need them.
- Optimise your geometry if it has too many polygons – many character models will need to be intelligently optimised or even rebuilt by an artist esp if sourced/built from:
- 3D capture data
- Poser
- Zbrush
- Other hi density Nurbs/Patch models designed for render
- Evenly spaced polygons in buildings, landscape and architecture where you can afford them, will help spread lighting and avoid awkward kinks.
- Avoid really long thin triangles

Stairway to framerate heaven
The method you use to construct objects can have a massive affect on the number of polygons, especially when not optimised. Observe the same shape mesh : 156 triangles (right) vs 726 (left). 726 may not sound like a great deal of polygons, but if this is used 40 times in a level, you will really start to see the savings. A good rule of thumb is often to start simple and add detail where needed. It’s always easier to add polygon than take them away.
Textures
Textures are more efficient and don’t need rescaling at build time if authored to specific texture sizes – e.g a power of two – up to 4096×4096 pixels, e.g. 512×512 or 256×1024 etc. (2048×2048 is the highest on many graphics cards/platforms) there is lots of expertise online for creating good textures, but some of these guidelines can help you get the most efficient results from your project:
- Working with a Hi-res source file outside your unity project can be good working practice (such as a PSD or Gimp file – you can always downsize from source but not the other way round).
- Use the texture resolution output you require in your scene (e.g. save a copy – such as a 256×256 optimised PNG or a TGA file for example) you can make a judgement based on where the texture will be seen and where it is mapped.
- Store your output texture files together in your Unity project for example: \Assets\textures
- Make sure your 3D working file is referring to the same textures for consistency when you save/export.
- Make use of the available space in your texture, but be aware of different materials requiring different parts of the same texture can end up using loading that texture multiple times.
- For alpha (cutout) and elements that may require different shaders, separate the textures. E.g. the single texture below (left) has been replaced by 3 smaller textures below (right)

1 texture (left) vs 3 textures (right)
- Make use of tiling textures (which seamlessly repeat) then you can use better resolution repeating over space.
- Remove easily noticeable repeating elements from your bitmap, and be careful with contrast – if you want to add details use decals and objects to break up the repeats.

Tiling textures ftw
- Unity takes care of compression for the output platform, so unless your source is already a JPG of the correct resolution it’s better to use a lossless format for your textures.
- When creating a texture page from photographs, reduce the page to individual modular sections that can repeat, e.g. you don’t need 12 of the same windows using up texture space. That way you can have more pixel detail for that one window.

Do you need ALL those windows?
Materials
- Organise and name the materials in your scene – this way you can find and edit your materials in Unity more easily when they’ve imported
- You can choose to create materials in Unity from either:
- <modelname>-< material name> or:
- <texture name> – make sure you are aware of which you want.
- Settings for materials in your native package will not all be imported to unity:
- Diffuse Colour, Diffuse texture and Names are usually supported
- Shader model, specular, normal, other secondary textures and substance material settings will not be recognised/imported (coming in 3.5)
Import/Export
Unity can use two types of files: Saved 3D application files and Exported 3D formats – which you decide to use can be quite important:
Saved application files
Unity can import, through conversion: Max, Maya, Blender, Cinema4D, Modo, Lightwave & cheetah3D files, e.g. .MAX, .MB, .MA etc. http://unity3d.com/support/documentation/Manual/HOWTO-importObject.html
Advantages:
- Quick iteration process (save and Unity updates)
- Simple initially
Disadvantages:
- A licensed copy of that software must be installed on all machines using the Unity project
- Files can become bloated with unnecessary data
- Big files can slow Unity updates
- Less Validation – harder to troubleshoot problems
Exported 3D formats
Unity can also read FBX, OBJ, 3DS, DAE & DXF files – for a general export guide you can refer here: http://unity3d.com/support/documentation/Manual/HOWTO-exportFBX.html
Advantages:
- Only export the data you need
- Verify your data (re-import into 3D package) before Unity
- Generally smaller files
- Encourages modular approach
Disadvantages:
- Can be slower pipeline or prototyping and iterations
- Easier to lose track of versions between source(working file) and game data (exported FBX)
HOWTO-importObject
Unity supports importing from most popular 3D applications. Choose the one you're working with below:
Other applications
Unity can read .FBX, .dae, .3DS, .dxf and .obj files, so if your program can export to this format you're home free. FBX exporters for popular 3D packages can be found here. Many packages also have a Collada exporter available.
Hints
- Store textures in a folder called Textures next to the exported mesh. This will guarantee that Unity will always be able to find the Texture and automatically connect the Texture to the Material. For more information, see the Textures reference.
See Also
- Modeling Optimized Characters
- How do I use normal maps?
- Mesh Import Settings
- How do I fix the rotation of an imported model?
HOWTO-ImportObjectMaya
Unity natively imports Maya files. To get started, simply place your .mb or .ma file in your project's Assets folder. When you switch back into Unity, the scene is imported automatically and will show up in the Project view.
To see your model in Unity, simply drag it from the Project View into the Scene View or Hierarchy View.
Unity currently imports from Maya:
- All nodes with position, rotation and scale. Pivot points and Names are also imported.
- Meshes with vertex colors, normals and up to 2 UV sets.
- Materials with Texture and diffuse color. Multiple materials per mesh.
- Animations FK & IK
- Bone-based animations
Unity does not import blend shapes. Use Bone-based animations instead. Unity automatically triangulates polygonal meshes when importing, thus there is no need to do this manually in Maya.
If you are using IK to animate characters you have to select the imported .mb file in Project View and choose Bake IK & Simulation in the Import Settings dialog in the Inspector.
Requirements
In order to import Maya .mb and .ma files, you need to have Maya installed on the machine you are using Unity to import the .mb/.ma file. Maya 8.0 and up is supported.
Behind the import process (Advanced)
When Unity imports a Maya file it will launch Maya in the background. Unity then communicates with Maya to convert the .mb file into a format Unity can read. The first time you import a Maya file in Unity, Maya has to launch in a command line process, this can take around 20 seconds, but subsequent imports will be very quick.
Troubleshooting
- Keep your scene simple, try and work with a file which only contains the objects you need in Unity
- If your meshes cause problems, make sure you have converted any patches, nurbs surface etc into Polygons (Modify > Convert + also Mesh > Quadragulate/Triangulate) Unity only support Polygons.
- Maya in some rare cases messes up the node history, which sometimes results in models not exporting correctly. Fortunately you can very easily fix this by selecting .
- Unity likes to keep up with the latest FBX where possible so if you have any issues with importing some models, check Autodesk latest version, or for fail-safe install 2011.3
- Animation baking in Maya is now done with FBX instead of natively, which allows for more complex animations to be baked properly to FBX format. If you are using driven keys, then make sure to set at least one key on your drivers for the animation to bake properly
HOWTO-ImportObjectCinema4D
Unity natively imports Cinema 4D files. To get started, simply place your .c4d file in your project's Assets folder. When you switch back into Unity, the scene is imported automatically and will show up in the Project View.
To see your model in Unity, simply drag it from the Project View into the Scene View.
If you modify your .c4d file, Unity will automatically update whenever you save.
Unity currently imports
- All objects with position, rotation and scale. Pivot points and Names are also imported.
- Meshes with UVs and normals.
- Materials with Texture and diffuse color. Multiple materials per mesh.
- Animations FK (IK needs to be manually baked).
- Bone-based animations.
Unity does not import Point Level Animations (PLA) at the moment. Use Bone-based animations instead.
Animated Characters using IK
If you are using IK to animate your characters in Cinema 4D, you have to bake the IK before exporting using the menu. If you don't bake your IK prior to importing into Unity, you will most likely only get animated locators but no animated bones.
Requirements
- You need to have at least Cinema 4D version 8.5 installed to import .c4d files.
If you don't have Cinema 4D installed on your machine but want to import a Cinema 4D file from another machine, you can export to the FBX format, which Unity imports natively:
- Open the Cinema 4D file
- In Cinema 4D choose
- Place the exported fbx file in the Unity project's Assets folder. Unity will now automatically import the fbx file.
Hints
- To maximize import speed when importing Cinema 4D files: go to the Cinema 4D preferences () and select the FBX 6.0 preferences. Now uncheck Embed Textures.
Behind the import process (Advanced)
When Unity imports a Cinema 4D file it will automatically install a Cinema 4D plugin and launch Cinema 4D in the background. Unity then communicates with Cinema 4D to convert the .c4d file into a format Unity can read. The first time you import a .c4d file and Cinema 4D is not open yet it will take a short while to launch it but afterwards importing .c4d files will be very quick.
Cinema 4D 10 support
When importing .c4d files directly, Unity behind the scenes lets Cinema 4D convert its files to FBX. When Maxon shipped Cinema 4D 10.0, the FBX exporter was severly broken. With Cinema 4D 10.1 a lot of the issues have been fixed. Thus we strongly recommend everyone using Cinema 4D 10 to upgrade to 10.1.
Now there are still some issues left in Maxons FBX exporter. It seems that currently there is no reliable way of exporting animated characters that use the Joint's introduced in Cinema 4D 10. However the old bone system available in 9.6 exports perfectly fine. Thus when creating animated characters it is critical that you use the old bone system instead of joints.
Page last updated: 2007-11-16HOWTO-ImportObjectMax
If you make your 3D objects in 3dsMax, you can save your .max files directly into your Project or export them into Unity using the Autodesk .FBX format. Saving them in the original .max format is recommended.
Unity currently imports from 3ds Max
- All nodes with position, rotation and scale. Pivot points and Names are also imported.
- Meshes with vertex colors, normals and one or two UV sets.
- Materials with diffuse texture and color. Multiple materials per mesh.
- Animations.
- Bone based animations.
To manually export to FBX from 3DS Max
- Download the latest fbx exporter from Autodesk website and install it.
- Export your scene ( or ) in .fbx format. Using default export options should be okay.
- Move the exported fbx file into your Unity project folder.
- When you switch back into Unity, the .fbx file is imported automatically.
- Drag the file from the Project View into the Scene View.
Exporter options
Using default FBX exporter options (that basically export everything) should be okay in all cases.

Default FBX exporter options (for fbx plugin version 2009.3)
Exporting Bone-based Animations
There is a procedure you should follow when you want to export bone-based animations:
- Set up the bone structure as you please.
- Create the animations you want, using FK and/or IK
- Select all bones and/or IK solvers
- Go to and press . Unity makes a key filter, so the amount of keys you export is irrelevant
- "Export" or "Export selected" as newest FBX format
- Drop the FBX file into Assets as usual
- In Unity you must reassign the Texture to the Material in the root bone
When exporting a bone hierarchy with mesh and animations from 3ds Max to Unity, the GameObject hierarchy produced will correspond to the hierarchy you can see in "Schematic view" in 3ds Max. One difference is Unity will place a GameObject as the new root, containing the animations, and will place the mesh and material information in the root bone.
If you prefer to have animation and mesh information in the same Unity GameObject, go to the Hierarchy view in 3ds Max, and parent the mesh node to a bone in the bone hierarchy.
Exporting Two UV Sets for Lightmapping
3ds Max' Render To Texture and automatic unwrapping functionality can be used to create lightmaps. Note that Unity has built-in lightmapper, but you might prefer using 3dsmax if that fits your workflow better. Usually one UV set is used for main texture and/or normal maps, and another UV set is used for the lightmap texture. For both UV sets to come through properly, the material in 3ds Max has to be Standard and both Diffuse (for main texture) and Self-Illumination (for lightmap) map slots have to be set up:

Material setup for Lightmapping in 3ds Max, using self-illumination map
Note that if object uses a Shell material type, then current Autodesk's FBX exporter will not export UVs correctly.
Alternatively, you can use Multi/Sub Object material type and setup two sub-materials, using the main texture and the lightmap in their diffuse map slots, like shown below. However, if faces in your model use different sub-material IDs, this will result in multiple materials being imported, which is not optimal for performance.

Alternate Material setup for Lightmapping in 3ds Max, using multi/sub object material
Troubleshooting
If you have any issues with importing some models: ensure that you have the latest FBX plugin installed. It can be downloaded Autodesk website.
Page last updated: 2010-09-16HOWTO-ImportObjectCheetah3D
Unity natively imports Cheetah3D files. To get started, simply place your .jas file in your project's Assets folder. When you switch back into Unity, the scene is imported automatically and will show up in the Project View.
To see your model in Unity, simply drag it from the Project View into the Scene View.
If you modify your .jas file, Unity will automatically update whenever you save.
Unity currently imports from Cheetah3D
- All nodes with position, rotation and scale. Pivot points and Names are also imported.
- Meshes with vertices, polygons, triangles, UV's and Normals.
- Animations.
- Materials with diffuse color and textures.
Requirements
- You need to have at least Cheetah3D 2.6 installed.
HOWTO-ImportObjectModo
Unity natively imports modo files. This works under the hood by using the modo COLLADA exporter. Modo version 501 and later use this approach. To get started, save your .lxo file in the project's Assets folder. When you switch back into Unity, the file is imported automatically and will show up in the Project View.
For older modo versions prior to 501, simply save your Modo scene as an FBX or COLLADA file into the Unity project folder. When you switch back into Unity, the scene is imported automatically and will show up in the Project View.
To see your model in Unity, drag it from the Project View into the Scene View.
If you modify the lxo file, Unity will automatically update whenever you save.
Unity currently imports
- All nodes with position, rotation and scale. Pivot points and names are also imported.
- Meshes with vertices, normals and UVs.
- Materials with Texture and diffuse color. Multiple materials per mesh.
- Animations
Requirements
- modo 501 or later is required for native import of *.lxo files.
HOWTO-importObjectLightwave
You can import meshes and animations from Lightwave using the FBX plugin for Lightwave.
Unity currently imports
- All nodes with position, rotation and scale. Pivot points and Names are also imported.
- Meshes with UVs and normals.
- Materials with Texture and diffuse color. Multiple materials per mesh.
- Animations.
- Bone-based animations.
Installation
Download the latest Lightwave FBX exporter from:
- OS X lighwave 8.2 and 9.0 plugin
- OS X Lighwave 8.0 plugin
- Windows Lighwave 8.2 and 9.0 plugin
- Windows Lighwave 8.0 plugin
By downloading these plugins you automatically agree to this licence.
There are two versions of the plugin, one for LightWave 8.0 and one for LightWave 8.2 through 9.0. Make sure you install the correct version.
The plugin for Mac comes in an OS X package. If you double-click the package to install it, the installer will try to put it in the correct folder. If it can't find your LightWave plugin folder, it will create its own LightWave folder in your folder and dump it there. If the latter occurs you should move it to your LightWave plugin folder (or any sub-folder). Once there you have to add the plugin to LightWave via the "Edit Plugins" panel () - see the LightWave manual for more details on how to add plugins.

Once added to LightWave, the plugin is acessible via the Generics menu (on the Utiliies) tab. If the Generic menu is not present you will have to add it using the Config Menus panel. In the latter panel it can be found in the Plug-ins category and is called "Generic Plugins". Add it to any convenient menu (see the LightWave manual for more details on how to do this).
More information about installation can also be found in the release notes that can downloaded with the installer.
Exporting
All objects and animations have to be exported from Layout (there is no Modeler FBX exporter).
1. Select Export to FBX from the Generics menu

2. Select the appropriate settings in the fbx export dialog
- Select the fbx file name. Make sure to save the exported fbx file in the Assets folder of your current Unity project.
- In the FBX dialogue panel you MUST select Embed Textures otherwise the exported object will have no UVs. This is a bug in the Lightwave fbx exporter and will be fixed in a future version according to Autodesk.
- If you want to export animations into Unity you must have "Animations" checked. You also need to have "Lights" or "Cameras" checked.
- To change the name of the exported animation clip in Unity, change the name from "LW Take 001" to your liking.

3. Switch to Unity.
- Unity will automatically import the fbx file and generate materials for the textures.
- Drag the imported fbx file from the Project view into the Scene view.
Important notes
- You must select Embed Textures in the FBX panel when exporting or no UVs are exported
- If you want to export animations you must enable Animations and either Camera or Lights.
- It is strongly recommended to always place your textures in a folder called "Textures" next to the fbx file. This will guarantee that Unity can always find the Texture and automatically connect the texture to the material.
HOWTO-ImportObjectBlender
Unity natively imports Blender files. This works under the hood by using the Blender FBX exporter, which was added to Blender in version 2.45. For this reason, you must update to Blender 2.45 or later (but see Requirements below).
To get started, save your .blend file in your project's Assets folder. When you switch back into Unity, the file is imported automatically and will show up in the Project View.
To see your model in Unity, drag it from the Project View into the Scene View.
If you modify your .blend file, Unity will automatically update whenever you save.
Unity currently imports
- All nodes with position, rotation and scale. Pivot points and Names are also imported.
- Meshes with vertices, polygons, triangles, UVs, and normals.
- Bones
- Skinned Meshes
- Animations
Requirements
- You need to have Blender version 2.45-2.49 or 2.58 or later (versions 2.50-2.57 do not work, because FBX export was changed/broken in Blender).
- Textures and diffuse color are not assigned automatically. Manually assign them by dragging the texture onto the mesh in the Scene View in Unity.
Workflow
- Getting started with Mono Develop
- How do I reuse assets between projects?
- How do I install or upgrade Standard Assets?
HOWTO-MonoDevelop
Mono Develop comes now with Unity 3.x, this IDE will help you out taking care of the scripting part of your game and the debugging o it.
Setting Up Mono Develop.
To set up Mono Develop to work with with Unity you just have to go to Unity Preferences and set it as your default editor.

Setting Mono Develop as the Default Editor
After this, create or open an existing project and make sure your project is synced with Mono Develop by clicking on .

Mono Develop Sync.
This will open your project (Only The scripting files, no Assets) in Mono Develop. Now you are ready to start debugging.
Also you might want to visit the troubleshooting page in case you have any problem setting your project.
Page last updated: 2010-09-24HOWTO-exportpackage
As you build your game, Unity stores a lot of metadata about your assets (import settings, links to other assets, etc.). If you want to take your assets into a different project, there is a specific way to do that. Here's how to easily move assets between projects and still preserve all this info.
- In the Project View, select all the asset files you want to export.
- Choose from the menubar.
- Name and save the package anywhere you like.
- Open the project you want to bring the assets into.
- Choose from the menubar.
- Select your package file saved in step 3.
Hints
- When exporting a package Unity can export all dependencies as well. So for example if you select a Scene and export a package with all dependencies, then all models, textures and other assets that appear in the scene will be exported as well. This can be a quick way of exporting a bunch of assets without manually locating them all.
- If you store your Exported Package in the Standard Packages folder next to your Unity application, they will appear in the Create New Project dialog.
HOWTO-InstallStandardAssets
Unity ships with multiple Standard Assets packages. These are collections of assets that are widely used by most Unity customers. When you create a new project from the Project Wizard you can optionally include these asset collections. These assets are copied from the Unity install folder into your new project. This means that if you upgrade Unity to a new version you will not get the new version of these assets and so upgrading them is needed. Also, consider that a newer version of e.g. an effect might behave differently for performance or quality reasons and thus requires retweaking of parameters. It's important to consider this before upgrading if you don't want your game to suddenly look or behave differently. Check with the package contents and Unity's release notes.
Standard Assets contain useful things like a first person controller, skyboxes, lens flares, Water prefabs, Image Effects and so on.

The Standard Assets packages listed when creating new project
Upgrading
Sometimes you might want to upgrade your Standard Assets, for example because a new version of Unity ships with new Standard Assets:
- Open your project.
- Choose package you want to update from submenu.
- A list of new or replaced assets will be presented, click .
For the cleanest possible upgrade, it should be considered to remove the old package contents first, as some scripts, effects or prefabs might have become deprecated or unneeded and Unity packages don't have a way of deleting (unneeded) files (but make sure to have a security copy of the old version available).
Page last updated: 2011-06-09Advanced
- Vector Cookbook
- AssetBundles (Pro only)
- AssetDatabase
- Build Player Pipeline
- Rendering Paths
- Profiler (Pro only)
- Lightmapping Quickstart
- HDR (High Dynamic Range)
- Linear Lighting (Pro Only)
- Occlusion Culling (Pro only)
- Level of Detail (Pro Only)
- Camera Tricks
- Loading Resources at Runtime
- Modifying Source Assets Through Scripting
- Generating Mesh Geometry Procedurally
- Using Mono DLLs in a Unity Project
- Execution Order of Event Functions
- Optimizing Graphics Performance
- Reducing File Size
- Understanding Automatic Memory Management
- Platform Dependent Compilation
- Generic Functions
- Debugging
- Plugins (Pro/Mobile-Only Feature)
- Textual Scene File Format (Pro-only Feature)
- Streaming Assets
- Command line arguments
- Running Editor Script Code on Launch
- Shaders
- Graphics Emulation
- Network Emulation
- Security Sandbox of the Webplayer
- Overview of available .NET Class Libraries
- Visual Studio C# Integration
- Using External Version Control Systems with Unity
- Analytics
- Check For Updates
- Trouble Shooting
Vector Cookbook
Vector Cookbook
Although vector operations are easy to easy to describe, they are surprisingly subtle and powerful and have many uses in games programming. The following pages offer some suggestions about using vectors effectively in your code.
- Understanding Vector Arithmetic
- Direction and Distance from One Object to Another
- Computing a Normal/Perpendicular vector
- The Amount of One Vector's Magnitude that Lies in Another Vector's Direction
UnderstandingVectorArithmetic
Vector arithmetic is fundamental to 3D graphics, physics and animation and it is useful to understand it in depth to get the most out of Unity. Below are descriptions of the main operations and some suggestions about the many things they can be used for.
Addition
When two vectors are added together, the result is equivalent to taking the original vectors as "steps", one after the other. Note that the order of the two parameters doesn't matter, since the result is the same either way.

If the first vector is taken as a point in space then the second can be interpreted as an offset or "jump" from that position. For example, to find a point 5 units above a location on the ground, you could use the following calculation:-
var pointInAir = pointOnGround + new Vector3(0, 5, 0);
If the vectors represent forces then it is more intuitive to think of them in terms of their direction and magnitude (the magnitude indicates the size of the force). Adding two force vectors results in a new vector equivalent to the combination of the forces. This concept is often useful when applying forces with several separate components acting at once (eg, a rocket being propelled forward may also be affected by a crosswind).
Subtraction
Vector subtraction is most often used to get the direction and distance from one object to another. Note that the order of the two parameters does matter with subtraction:-

// The vector d has the same magnitude as c but points in the opposite direction. var c = b - a; var d = a - b;
As with numbers, adding the negative of a vector is the same as subtracting the positive.
// These both give the same result. var c = a - b; var c = a + -b;
The negative of a vector has the same magnitude as the original and points along the same line but in the exact opposite direction.
Scalar Multiplication and Division
When discussing vectors, it is common to refer to an ordinary number (eg, a float value) as a scalar. The meaning of this is that a scalar only has "scale" or magnitude whereas a vector has both magnitude and direction.
Multiplying a vector by a scalar results in a vector that points in the same direction as the original. However, the new vector's magnitude is equal to the original magnitude multiplied by the scalar value.
Likewise, scalar division divides the original vector's magnitude by the scalar.
These operations are useful when the vector represents a movement offset or a force. They allow you to change the magnitude of the vector without affecting its direction.
When any vector is divided by its own magnitude, the result is a vector with a magnitude of 1, which is known as a normalized vector. If a normalized vector is multiplied by a scalar then the magnitude of the result will be equal to that scalar value. This is useful when the direction of a force is constant but the strength is controllable (eg, the force from a car's wheel always pushes forwards but the power is controlled by the driver).
Dot Product
The dot product takes two vectors and returns a scalar. This scalar is equal to the magnitudes of the two vectors multiplied together and the result multiplied by the cosine of the angle between the vectors. When both vectors are normalized, the cosine essentially states how far the first vector extends in the second's direction (or vice-versa - the order of the parameters doesn't matter).

It is easy enough to think in terms of angles and then find the corresponding cosines using a calculator. However, it is useful to get an intuitive understanding of some of the main cosine values as shown in the diagram below:-

The dot product is a very simple operation that can be used in place of the Mathf.Cos function or the vector magnitude operation in some circumstances (it doesn't do exactly the same thing but sometimes the effect is equivalent). However, calculating the dot product function takes much less CPU time and so it can be a valuable optimization.
Cross Product
The other operations are defined for 2D and 3D vectors and indeed vectors with any number of dimensions. The cross product, by contrast, is only meaningful for 3D vectors. It takes two vectors as input and returns another vector as its result.
The result vector is perpendicular to the two input vectors. The "left hand rule" can be used to remember the direction of the output vector from the ordering of the input vectors. If the first parameter is matched up to the thumb of the hand and the second parameter to the forefinger, then the result will point in the direction of the middle finger. If the order of the parameters is reversed then the resulting vector will point in the exact opposite direction but will have the same magnitude.

The magnitude of the result is equal to the magnitudes of the input vectors multiplied together and then that value multiplied by the sine of the angle between them. Some useful values of the sine function are shown below:-

The cross product can seem complicated since it combines several useful pieces of information in its return value. However, like the dot product, it is very efficient mathematically and can be used to optimize code that would otherwise depend on slow transcendental functions.
Page last updated: 2011-08-26DirectionDistanceFromOneObjectToAnother
If one point in space is subtracted from another then the result is a vector that "points" from one object to the other:
// Gets a vector that points from the player's position to the target's. var heading = target.position - player.position;
As well as pointing in the direction of the target object, this vector's magnitude is equal to the distance between the two positions. It is common to need a normalized vector giving the direction to the target and also the distance to the target (say for directing a projectile). The distance between the objects is equal to the magnitude of the heading vector and this vector can be normalized by dividing it by its magnitude:-
var distance = heading.magnitude; var direction = heading / distance; // This is now the normalized direction.
This approach is preferable to using the both the magnitude and normalized properties separately, since they are both quite CPU-hungry (they both involve calculating a square root).
If you only need to use the distance for comparison (for a proximity check, say) then you can avoid the magnitude calculation altogether. The sqrMagnitude property gives the square of the magnitude value, and is calculated like the magnitude but without the time-consuming square root operation. Rather than compare the magnitude against a known distance, you can compare the squared magnitude against the squared distance:-
if (heading.sqrMagnitude < maxRange * maxRange) {
// Target is within range.
}
This is much more efficient than using the true magnitude in the comparison.
Sometimes, the overground heading to a target is required. For example, imagine a player standing on the ground who needs to approach a target floating in the air. If you subtract the player's position from the target's then the resulting vector will point upwards towards the target. This is not suitable for orienting the player's transform since he will also point upwards; what is really needed is a vector from the player's position to the position on the ground directly below the target. This is easily obtained by taking the result of the subtraction and setting the Y coordinate to zero:-
var heading = target.position - player.position; heading.y = 0; // This is the overground heading.Page last updated: 2011-08-26
ComputingNormalPerpendicularVector
A normal vector (ie, a vector perpendicular to a plane) is required frequently during mesh generation and may also be useful in path following and other situations. Given three points in the plane, say the corner points of a mesh triangle, it is easy to find the normal. Pick any of the three points and then subtract it from each of the two other points separately to give two vectors:-

var a: Vector3; var b: Vector3; var c: Vector3; var side1: Vector3 = b - a; var side2: Vector3 = c - a;
The cross product of these two vectors will give a third vector which is perpendicular to the surface. The "left hand rule" can be used to decide the order in which the two vectors should be passed to the cross product function. As you look down at the top side of the surface (from which the normal will point outwards) the first vector should sweep around clockwise to the second:-
var perp: Vector3 = Vector3.Cross(side1, side2);
The result will point in exactly the opposite direction if the order of the input vectors is reversed.
For meshes, the normal vector must also be normalized. This can be done with the normalized property, but there is another trick which is occasionally useful. You can also normalize the perpendicular vector by dividing it by its magnitude:-
var perpLength = perp.magnitude; perp /= perpLength;
It turns out that the area of the triangle is equal to perpLength / 2. This is useful if you need to find the surface area of the whole mesh or want to choose triangles randomly with probability based on their relative areas.
Page last updated: 2011-08-26AmountVectorMagnitudeInAnotherDirection
A car's speedometer typically works by measuring the rotational speed of one of the unpowered wheels. The car may not be moving directly forward (it may be skidding sideways, for example) in which case part of the motion will not be in the direction the speedometer can measure. The magnitude of an object's rigidbody.velocity vector will give the speed in its direction of overall motion but to isolate the speed in the forward direction, you should use the dot product:-
var fwdSpeed = Vector3.Dot(rigidbody.velocity, transform.forward);
Naturally, the direction can be anything you like but the direction vector must always be normalized for this calculation. Not only is the result more correct than the magnitude of the velocity, it also avoids the slow square root operation involved in finding the magnitude.
Page last updated: 2011-08-26AssetBundles
AssetBundles are files which you can export from Unity to contain assets of your choice. These files use a proprietary compressed format and can be loaded on demand in your application. This allows you to stream content like models, textures, audio clips and even entire scenes separately from the scene in which they will be used. They have been designed to make it easy to download content to your application.
AssetBundles can contain any kind of asset type recognized by Unity, as determined by the filename extension. If you want to include files with custom binary data, then you must rename those files to have ".bytes" as the extension. Unity will import these files as TextAssets.
For some sample code showing how to use asset bundles, see the AssetBundles Example Project
Creating AssetBundles
There are three class methods you can use to build AssetBundles: BuildPipeline.BuildAssetBundle, BuildPipeline.BuildStreamedSceneAssetBundle and BuildPipeline.BuildAssetBundleExplicitAssetNames..
- BuildPipeline.BuildAssetBundle allows you to build AssetBundles of any type of asset.
- BuildPipeline.BuildStreamedSceneAssetBundle is used when you want to include only scenes to be streamed and loaded as the data becomes available.
- BuildPipeline.BuildAssetBundleExplicitAssetNames is the same as BuildPipeline.BuildAssetBundle but has an extra parameter to specify a custom string identifier (name) for each object.
Downloading AssetBundles
The recommended way to download AssetBundles is to use WWW.LoadFromCacheOrDownload. Once the download is complete you can retrieve the AssetBundle with the assetBundle property. For example:
string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
// Start a download of the given URL
WWW www = WWW.LoadFromCacheOrDownload (url, 1);
// Wait for download to complete
yield return www;
// Load and retrieve the AssetBundle
AssetBundle bundle = www.assetBundle;
}
When you access the .assetBundle property the downloaded data is extracted and the AssetBundle object is created. At this point, you are ready to load the objects contained in the bundle. The second parameter passed to LoadFromCacheOrDownload specifies which version of the AssetBundle to download. LoadFromCacheOrDownload will download the AssetBundle if it doesn't exist in the cache or if it exists but is associated with a version that is lower than the one requested. Otherwise the AssetBundle will be loaded from cache.
Loading and unloading objects from an AssetBundle
Having created an AssetBundle object from the downloaded data, you can load the objects contained in it using three different methods: AssetBundle.Load, AssetBundle.LoadAsync and AssetBundle.LoadAll.
- AssetBundle.Load will load an object using its name identifier as a parameter. The name is the one visible in the Project view. You can optionally pass an object type as an argument to the Load method to make sure the object loaded is of a specific type.
- AssetBundle.LoadAsync works the same as the Load method described above but it will not block the main thread while the asset is loaded. This is useful when loading large assets or many assets at once to avoid pauses in your application.
- AssetBundle.LoadAll will load all the objects contained in your AssetBundle. As with AssetBundle.Load, you can optionally filter objects by their type.
To unload assets you need to use AssetBundle.Unload. This method takes a boolean parameter which tells Unity whether to unload all data (including the loaded asset objects) or only the compressed data from the downloaded bundle. If your application is using some objects from the AssetBundle and you want to free some memory you can pass false to unload the compressed data from memory. If you want to completely unload everything from the AssetBundle you should pass true which will destroy the Assets loaded from the AssetBundle.
Listing objects in an AssetBundle
You can use AssetBundle.LoadAll to retrieve an array containing all objects from the AssetBundle. It is not possible to get a list of the identifiers directly. A common workaround is to keep a separate TextAsset with a known name to hold the names of the assets in the AssetBundle.
Instantiating objects from AssetBundles
Once you have loaded an object from your AssetBundle, you can instantiate it in your scene with the Instantiate function.
string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
// Start a download of the given URL
WWW www = WWW.LoadFromCacheOrDownload (url, 1);
// Wait for download to complete
yield return www;
// Load and retrieve the AssetBundle
AssetBundle bundle = www.assetBundle;
// Load the GameObject
GameObject go = bundle.Load("myGameObject", typeof(GameObject)) as GameObject;
// Instantiate the GameObject
Instantiate(go);
}
Keeping track of downloaded AssetBundles
Unity doesn't provide an automatic way to retrieve a list of AssetBundles that have been downloaded. You can keep track of this information from a script by storing references to the AssetBundle objects and their URLs, say.
Storing and loading binary data in an AssetBundle
The first step is to save your binary data file with the ".bytes" extension. Unity will treat this file as a TextAsset. As a TextAsset the file can be included when you build your AssetBundle. Once you have downloaded the AssetBundle in your application and loaded the TextAsset object, you can use the .bytes property of the TextAsset to retrieve your binary data.
string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
// Start a download of the given URL
WWW www = WWW.LoadFromCacheOrDownload (url, 1);
// Wait for download to complete
yield return www;
// Load and retrieve the AssetBundle
AssetBundle bundle = www.assetBundle;
// Load the TextAsset object
TextAsset txt = bundle.Load("myBinaryAsText", typeof(TextAsset)) as TextAsset;
// Retrieve the binary data as an array of bytes
byte[] bytes = txt.bytes;
}
Including scripts in AssetBundles
AssetBundles can contain scripts as TextAssets but as such they will not be actual executable code. If you want to include code in your AssetBundles that can be executed in your application it needs to be pre-compiled into an assembly and loaded using the Mono Reflection class (Note: Reflection is not available on iOS). You can create your assemblies in any normal C# IDE (e.g. Monodevelop, Visual Studio) or any text editor using the mono/.net compilers.
string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
// Start a download of the given URL
WWW www = WWW.LoadFromCacheOrDownload (url, 1);
// Wait for download to complete
yield return www;
// Load and retrieve the AssetBundle
AssetBundle bundle = www.assetBundle;
// Load the TextAsset object
TextAsset txt = bundle.Load("myBinaryAsText", typeof(TextAsset)) as TextAsset;
// Load the assembly and get a type (class) from it
var assembly = System.Reflection.Assembly.Load(txt.bytes);
var type = assembly.GetType("MyClassDerivedFromMonoBehaviour");
// Instantiate a GameObject and add a component with the loaded class
GameObject go = new GameObject();
go.AddComponent(type);
}
Managing asset dependencies
Any given asset in a bundle may depend on other assets. For example, a model may incorporate materials which in turn make use of textures and shaders. It is possible to include all an asset's dependencies along with it in its bundle. However, several assets from different bundles may all depend on a common set of other assets (eg, several different models of buildings may use the same brick texture). If a separate copy of a shared dependency is included in each bundle that has objects using it, then redundant instances of the assets will be created when the bundles are loaded. This will result in wasted memory.
To avoid such wastage, it is possible to separate shared dependencies out into a separate bundle and simply reference them from any bundles with assets that need them. First, the referencing feature needs to be enabled with a call to BuildPipeline.PushAssetDependencies. Then, the bundle containing the referenced dependencies needs to be built. Next, another call to PushAssetDependencies should be made before building the bundles that reference the assets from the first bundle. Additional levels of dependency can be introduced using further calls to PushAssetDependencies. The levels of reference are stored on a stack, so it is possible to go back a level using the corresponding BuildPipeline.PopAssetDependencies function. The push and pop calls need to be balanced including the initial push that happens before building.
At runtime, you need to load a bundle containing dependencies before any other bundle that references them. For example, you would need to load a bundle of shared textures before loading a separate bundle of materials that reference those textures.
Note that if you anticipate needing to rebuild asset bundles that are part of a dependency chain then you should build them with the BuildAssetBundleOptions.DeterministicAssetBundle option enabled. This guarantees that the internal ID values used to identify assets will be the same each time the bundle is rebuilt.
Can I reuse my AssetBundles in another game?
AssetBundles allow you to share content between different games. The requirement is that any Assets which are referenced by GameObjects in your AssetBundle must either be included in the AssetBundle or exist in the application (loaded in the current scene). To make sure the referenced Assets are included in the AssetBundle when they are built you can pass the BuildAssetBundleOptions.CollectDependencies option.
Will an Asset Bundle built now be usable with future versions of Unity?
Asset bundles can contain a structure called a type tree which allows information about asset types to be understood correctly between different versions of Unity. On desktop platforms, the type tree is included by default but can be disabled by passing the BuildAssetBundleOptions.DisableWriteTypeTree to the BuildAssetBundle function. Webplayers intrinsically rely on the type tree and so it is always included (ie, the DisableWriteTypeTree option has no effect). Type trees are never included for mobile and console asset bundles and so you will need to rebuild these bundles for each new version of Unity.
How are assets in AssetBundles identified?
When you build AssetBundles the assets are identified internally by their filename without the extension. For example a Texture located in your Project folder at "Assets/Textures/myTexture.jpg" is identified and loaded using "myTexture" if you use the default method. You can have more control over this by supplying your own array of ids (strings) for each object when Building your AssetBundle with BuildPipeline.BuildAssetBundleExplicitAssetNames.
Loading objects from an AssetBundles asynchronously
You can use the AssetBundle.LoadAsync method to load objects Asynchronously and reduce the likelihood of having hiccups in your application.
using UnityEngine;
IEnumerator Start () {
// Start a download of the given URL
WWW www = WWW.LoadFromCacheOrDownload (url, 1);
// Wait for download to complete
yield return www;
// Load and retrieve the AssetBundle
AssetBundle bundle = www.assetBundle;
// Load the object asynchronously
AssetBundleRequest request = bundle.LoadAsync ("myObject", typeof(GameObject));
// Wait for completion
yield return request;
// Get the reference to the loaded object
GameObject obj = request.asset as GameObject;
}
Are AssetBundles cross-platform?
AssetBundles are compatible between some platforms. Use the following table as a guideline.
| Platform compatibility for AssetBundles | |||||
| Standalone | Webplayer | iOS | Android | ||
| Editor | Y | Y | Y | Y | |
| Standalone | Y | Y | |||
| Webplayer | Y | Y | |||
| iOS | Y | ||||
| Android | Y | ||||
For example, a bundle created while the Webplayer build target was active would be compatible with the editor and with standalone builds. However, it would not be compatible with apps built for the iOS or Android platforms.
How do I cache AssetBundles?
You can use WWW.LoadFromCacheOrDownload which automatically takes care of saving your AssetBundles to disk. Be aware that on the Webplayer you are limited to 50MB in total (shared between all webplayers). You can buy a separate caching license for your game if you require more space.
Protecting content
Unity allows you to create an AssetBundle object from a byte[] array with AssetBundle.CreateFromMemory. You can use this as a way to enhance the security by encrypting your assetbundles before transmission and decrypt them at runtime.
string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
// Start a download of the encrypted assetbundle
WWW www = new WWW (url);
// Wait for download to complete
yield return www;
// Get the byte data
byte[] encryptedData = www.bytes;
// Decrypt the AssetBundle data
byte[] decryptedData = YourDecryptionMethod(encryptedData);
// Create an AssetBundle from the bytes array
AssetBundle bundle = AssetBundle.CreateFromMemory(decryptedData);
// You can now use your AssetBundle
}
Page last updated: 2011-12-09
AssetDatabase
AssetDatabase is an API which allows you to access the assets contained in your project. Among other things, it provides methods to find and load assets and also to create, delete and modify them. The Unity Editor uses the AssetDatabase internally to keep track of asset files and maintain the linkage between assets and objects that reference them. Since Unity needs to keep track of all changes to the project folder, you should always use the AssetDatabase API rather than the filesystem if you want to access or modify asset data.
The AssetDatabase interface is only available in the editor and has no function in the built player. Like all other editor classes, it is only available to scripts placed in the Editor folder (just create a folder named “Editor” in the main Assets folder of your project if there isn't one already).
Importing an Asset
Unity normally imports assets automatically when they are dragged into the project but it is also possible to import them under script control. To do this you can use the AssetDatabase.ImportAsset method as in the example below.
using UnityEngine;
using UnityEditor;
public class ImportAsset {
[MenuItem ("AssetDatabase/ImportExample")]
static void ImportExample ()
{
AssetDatabase.ImportAsset("Assets/Textures/texture.jpg", ImportAssetOptions.Default);
}
}
You can also pass an extra parameter of type AssetDatabase.ImportAssetOptions to the AssetDatabase.ImportAsset call. The scripting reference page documents the different options and their effects on the function's behaviour.
Loading an Asset
The editor loads assets only as needed, say if they are added to the scene or edited from the Inspector panel. However, you can load and access assets from a script using AssetDatabase.LoadAssetAtPath, AssetDatabase.LoadMainAssetAtPath, AssetDatabase.LoadAllAssetRepresentationsAtPath and AssetDatabase.LoadAllAssetsAtPath. See the scripting documentation for further details.
using UnityEngine;
using UnityEditor;
public class ImportAsset {
[MenuItem ("AssetDatabase/LoadAssetExample")]
static void ImportExample ()
{
Texture2D t = AssetDatabase.LoadAssetAtPath("Assets/Textures/texture.jpg", typeof(Texture2D)) as Texture2D;
}
}
File Operations using the AssetDatabase
Since Unity keeps metadata about asset files, you should never create, move or delete them using the filesystem. Instead, you can use AssetDatabase.Contains, AssetDatabase.CreateAsset, AssetDatabase.CreateFolder, AssetDatabase.RenameAsset, AssetDatabase.CopyAsset, AssetDatabase.MoveAsset, AssetDatabase.MoveAssetToTrash and AssetDatabase.DeleteAsset.
public class AssetDatabaseIOExample {
[MenuItem ("AssetDatabase/FileOperationsExample")]
static void Example ()
{
string ret;
// Create
Material material = new Material (Shader.Find("Specular"));
AssetDatabase.CreateAsset(material, "Assets/MyMaterial.mat");
if(AssetDatabase.Contains(material))
Debug.Log("Material asset created");
// Rename
ret = AssetDatabase.RenameAsset("Assets/MyMaterial.mat", "MyMaterialNew");
if(ret == "")
Debug.Log("Material asset renamed to MyMaterialNew");
else
Debug.Log(ret);
// Create a Folder
ret = AssetDatabase.CreateFolder("Assets", "NewFolder");
if(AssetDatabase.GUIDToAssetPath(ret) != "")
Debug.Log("Folder asset created");
else
Debug.Log("Couldn't find the GUID for the path");
// Move
ret = AssetDatabase.MoveAsset(AssetDatabase.GetAssetPath(material), "Assets/NewFolder/MyMaterialNew.mat");
if(ret == "")
Debug.Log("Material asset moved to NewFolder/MyMaterialNew.mat");
else
Debug.Log(ret);
// Copy
if(AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(material), "Assets/MyMaterialNew.mat"))
Debug.Log("Material asset copied as Assets/MyMaterialNew.mat");
else
Debug.Log("Couldn't copy the material");
// Manually refresh the Database to inform of a change
AssetDatabase.Refresh();
Material MaterialCopy = AssetDatabase.LoadAssetAtPath("Assets/MyMaterialNew.mat", typeof(Material)) as Material;
// Move to Trash
if(AssetDatabase.MoveAssetToTrash(AssetDatabase.GetAssetPath(MaterialCopy)))
Debug.Log("MaterialCopy asset moved to trash");
// Delete
if(AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(material)))
Debug.Log("Material asset deleted");
if(AssetDatabase.DeleteAsset("Assets/NewFolder"))
Debug.Log("NewFolder deleted");
// Refresh the AssetDatabase after all the changes
AssetDatabase.Refresh();
}
}
Using AssetDatabase.Refresh
When you have finished modifying assets, you should call AssetDatabase.Refresh to commit your changes to the database and make them visible in the project.
Page last updated: 2011-06-14BuildPlayerPipeline
When building a player, you sometimes want to modify the built player in some way. For example you might want to add a custom icon, copy some documentation next to the player or build an Installer. Doing this manually can become tedious and if you know how to write sh or perl scripts you can automate this task.
Mac OSX
After building a player Unity automatically looks for a sh or perl script called PostprocessBuildPlayer (without any extension) in your Project's Assets/Editor folder. If the file is found, it is invoked when the player finishes building.
In this script you can post process the player in any way you like. For example build an installer out of the player.
You can use perl, sh or any other commandline compatible language.
Unity passes some useful command line arguments to the script, so you know what kind of player it is and where it is stored.
The current directory will be set to be the project folder, that is the folder containing the Assets folder.
#!/usr/bin/perl
my $installPath = $ARGV[0];
# The type of player built:
# "dashboard", "standaloneWin32", "standaloneOSXIntel", "standaloneOSXPPC", "standaloneOSXUniversal", "webplayer"
my $target = $ARGV[1];
# What optimizations are applied. At the moment either "" or "strip" when Strip debug symbols is selected.
my $optimization = $ARGV[2];
# The name of the company set in the project settings
my $companyName = $ARGV[3];
# The name of the product set in the project settings
my $productName = $ARGV[4];
# The default screen width of the player.
my $width = $ARGV[5];
# The default screen height of the player
my $height = $ARGV[6];
print ("\n*** Building at '$installPath' with target: $target \n");
In order to see this feature in action please visit the Example Projects page on our website and download the PostprocessBuildPlayer example package file and import it for use into your own project. It uses the Build Player Pipeline feature to offer customized post-processing of web player builds in order to demonstrate the types of custom build behavior you can implement in your own PostprocessBuildPlayer script.
Windows
On Windows, the PostprocessBuildPlayer script is not supported, but you can use editor scripting to achieve the same effect. You can use BuildPipeline.BuildPlayer to run the build and then follow it with whatever postprocessing code you need:-
using UnityEditor;
using System.Diagnostics;
public class ScriptBatch : MonoBehaviour
{
[MenuItem("MyTools/Windows Build With Postprocess")]
public static void BuildGame ()
{
// Get filename.
string path = EditorUtility.SaveFolderPanel("Choose Location of Built Game", "");
// Build player.
BuildPipeline.BuildPlayer(levels, path + "BuiltGame.exe", BuildTarget.StandaloneWindows, BuildOptions.None);
// Copy a file from the project folder to the build folder, alongside the built game.
FileUtil.CopyFileOrDirectory("Assets/WebPlayerTemplates/Readme.txt", path + "Readme.txt");
// Run the game (Process class from System.Diagnostics).
Process proc = new Process();
proc.StartInfo.FileName = path + "BuiltGame.exe";
proc.Start();
}
}
Page last updated: 2012-01-25
RenderingPaths
Unity supports different Rendering Paths. You should choose which one you use depending on your game content and target platform / hardware. Different rendering paths have different features and performance characteristics that mostly affect Lights and Shadows.
The rendering Path used by your project is chosen in Player Settings. Additionally, you can override it for each Camera.
If the graphics card can't handle a selected rendering path, Unity will automatically use a lower fidelity one. So on a GPU that can't handle Deferred Lighting, Forward Rendering will be used. If Forward Rendering is not supported, Vertex Lit will be used.
Deferred Lighting
Deferred Lighting is the rendering path with the most lighting and shadow fidelity. It is best used if you have many realtime lights. It requires a certain level of hardware support, is for Unity Pro only and is not supported on Mobile Devices.
For more details see the Deferred Lighting page.
Forward Rendering
Forward is a shader-based rendering path. It supports per-pixel lighting (including normal maps & light Cookies) and realtime shadows from one directional light. In the default settings, a small number of the brightest lights are rendered in per-pixel lighting mode. The rest of the lights are calculated at object vertices.
For more details see the Forward Rendering page.
Vertex Lit
Vertex Lit is the rendering path with the lowest lighting fidelity and no support for realtime shadows. It is best used on old machines or limited mobile platforms.
For more details see the Vertex Lit page.
Rendering Paths Comparison
| Deferred Lighting | Forward Rendering | Vertex Lit | |
| Features | |||
| Per-pixel lighting (normal maps, light cookies) | Yes | Yes | - |
| Realtime shadows | Yes | 1 Directional Light | - |
| Dual Lightmaps | Yes | - | - |
| Depth&Normals Buffers | Yes | Additional render passes | - |
| Soft Particles | Yes | - | - |
| Semitransparent objects | - | Yes | Yes |
| Anti-Aliasing | - | Yes | Yes |
| Light Culling Masks | Limited | Yes | Yes |
| Lighting Fidelity | All per-pixel | Some per-pixel | All per-vertex |
| Performance | |||
| Cost of a per-pixel Light | Number of pixels it illuminates | Number of pixels * Number of objects it illuminates | - |
| Platform Support | |||
| PC (Windows/Mac) | Shader Model 3.0+ | Shader Model 2.0+ | Anything |
| Mobile (iOS/Android) | - | OpenGL ES 2.0 | OpenGL ES 2.0 & 1.1 |
| Consoles | 360, PS3 | 360, PS3 | - |
Profiler
The Unity Profiler helps you to optimize your game. It reports for you how much time is spent in the various areas of your game. For example, it can report the percentage of time spent rendering, animating or in your game logic.
You can play your game in the Editor with Profiling on, and it will record performance data. The Profiler window then displays the data in a timeline, so you can see the frames or areas that spike (take more time) than others. By clicking anywhere in the timeline, the bottom section of the Profiler window will display detailed information for the selected frame.
Note that profiling has to instrument your code. This instrumentation has a small impact on the performance of your game. Typically this overhead is small enough to not affect the game framerate. When using profiling it is typical to consider only the ratio (or percentage) of time spent in certain areas. Also, to improve performance focus on those parts of the game that consume the most time. Compare profiling results before and after code changes and determine the improvements you measure. Sometimes changes you make to improve performance might have a negative effect on frame rate; unexpected consequences of code optimization should be expected.

Profiler window
Attaching to Unity players
To profile your game running on an other device or a player running on another computer, it is possible to connect the editor to that other player. The dropdown Active Profiler will show all players running on the local network. These players are identified by player type and the host name running the player "iPhonePlayer (Toms iPhone)". To be able to connect to a player, the player must be launched with the Development Build checkbox found in the Build Settings dialog. From here it is also possible to tick a checkbox to make the Editor and Player Autoconnect at startup.
Profiler Controls

Profiler controls are in the toolbar at the top of the window. Use these to turn profiling on and off, navigate through profiled frames and so on. The transport controls are at the far right end of the toolbar. Note that when the game is running and the profiler is collecting data clicking on any of these transport controls will pause the game. The controls go to the first recorded frame, step one frame back, step one frame forward and go to the last frame respectively. The profiler does not keep all recorded frames, so the notion of the first frame should really be though of as the oldest frame that is still kept in memory. The "current" transport button causes the profile statistics window to display data collected in real-time. The Active Profiler popup menu allows you to select whether profiling should be done in the editor or a separate player (for example, a game running on an attached iOS device).
Deep Profiling
When you turn on Deep Profile, all your script code is profiled - that is, all function calls are recorded. This is useful to know where exactly time is spent in your game code.
Note that Deep Profiling incurs a very large overhead and uses a lot of memory, and as a result your game will run significantly slower while profiling. If you are using complex script code, Deep Profiling might not be possible at all. Deep profiling should work fast enough for small games with simple scripting. If you find that Deep Profiling for your entire game causes the frame rate to drop so much that the game barely runs, you should consider not using this approach, and instead use the approach described below. You may find deep profiling more helpful as you are designing your game and deciding how to best implement key features. Note that for large games deep profiling may cause Unity to run out of memory and so for this reason deep profiling may not be possible.
Manually profiling blocks of your script code will have a smaller overhead than using Deep Profiling. Use Profiler.BeginSample and Profiler.EndSample scripting functions to enable and disable profiling around sections of code.
View SyncTime
When running at a fixed framerate or running in sync with the vertical blank, Unity records the waiting time in "Wait For Target FPS". By default this amount of time is not shown in the profiler. To view how much time is spent waiting, you can toggle "View SyncTime". This is also a measure of how much headroom you have before losing frames.
Profiler Timeline

The upper part of the Profiler window displays performance data over time. When you run a game, data is recorded each frame, and the history of the last several hundred frames is displayed. Clicking on a particular frame will display it's details in the lower part of the window. Different details are displayed depending on which timeline area is currently selected.
The vertical scale of the timeline is managed automatically and will attempt to fill the vertical space of the window. Note that to get more detail in say the CPU Usage area you can remove the Memory and Rendering areas. Also, the splitter between the timeline and the statistics area can be selected and dragged downward to increase the screen area used for the timeline chart.
The timeline consists of several areas: CPU Usage, Rendering and Memory. These areas can be removed by clicking the close button in the panel, and re-added again using the Add Area drop down in the Profile Controls bar.
CPU Usage Area

The CPU Usage area displays where time is spent in your game. When it is selected, the lower pane displays hierarchical time data for the selected frame.
- Hierarchy mode: Displays hierarchical time data.
- Group Hierarchy mode: Groups time data into logical groups (Rendering, Physics, Scripts etc.). Because children of any group can be in different group (e.g. some script might call rendering functions), the percentages of group times often add up to more than 100%. (This is not a bug.)
The way the CPU chart is stacked can be reordered by simply dragging chart labels up & down.
When an item is selected in the lower pane, it's contribution to the CPU chart is highlighted (and the rest are dimmed). Clicking on an item again de-selects it.

Shader.SetPass is selected and it's contribution is highlighted in the chart.
In the hierarchical time data the self time refers to the amount of time spent in a particular function not including the time spent calling sub-functions. In the screenshot above, for example 51.2% of time is spent in the Camera.Render function. This function does a lot of work and calls the various drawing and culling functions. Excluding all these functions only 0.8% of time is spent actually in the Camera.Render function.
Rendering Area

The Rendering area displays rendering statistics. The Number of Draw Calls, Triangles and Vertices rendered is displayed graphical in the timeline. The Lower pane displays more rendering statistics and these more closely match the ones shown in the GameView Rendering Statistics window.
Memory Area

The Memory area displays some memory usage data:
- Total Allocated is the total RAM used by the application. Note that in the Unity Editor this is memory used by everything in the editor; game builds will use much less.
- Texture Memory is the amount of video memory used by the textures in the current frame.
- Object Count is the total number of Objects that are created. If this number rises over time then it means your game is creating some objects that are never destroyed.
Audio Area

The Audio area displays audio statistics:
- Playing Sources is the total playing sources in the scene at a specific frame. Monitor this to see if audio is overloaded.
- Paused Sources is the total paused sources in the scene at a specific frame.
- Audio Voice is the actually number of audio (FMOD channels) voices used. PlayOneShot is using voices not shown in Playing Sources.
- Audio Memory is the total RAM used by the audio engine.
CPU usage can be seen in the bottom. Monitor this to see if Audio alone is taking up too much CPU.
Physics Area

The Physics area shows the following statistics about the physics in the scene:-
- Active Rigidbodies is the number of rigidbodies that are not currently sleeping (ie, they are moving or just coming to rest).
- Sleeping Rigidbodies is the number of rigidbodies that are completely at rest and therefore don't need to be updated actively by the physics engine (see Rigidbody Sleeping for further details).
- Number of Contacts is the total number of points of contact between all colliders in the scene.
- Static Colliders is the number of colliders attached to non-rigidbody objects (ie, objects which never move under physics).
- Dynamic Colliders is the number of colliders attached to rigidbody objects (ie, objects which do move under physics).
GPU Area

The GPU profiler is similar to the CPU profiler with the various contributions to rendering time shown as a hierarchy in the bottom panel. Selecting an item from the hierarchy will show a breakdown in the panel to the right.
Please note that on the Mac, GPU profiling is only available under OSX 10.7 Lion and later versions.
See Also
iOS
Remote profiling can be enabled on iOS devices by following these steps:
- Connect your iOS device to your WiFi network (local/adhoc WiFi network is used by profiler to send profiling data from device to the Unity Editor).
- Check "Autoconnect Profiler" checkbox in Unity's build settings dialog.
- Attach your device to your Mac via cable and hit "Build & Run" in Unity Editor.
- When app launches on device open profiler window in Unity Editor (Window->Profiler)
If you are using a firewall, you need to make sure that ports 54998 to 55511 are open in the firewall's outbound rules - these are the ports used by Unity for remote profiling.
Note: Sometimes Unity Editor might not autoconnect to the device. In such cases profiler connection might be initiated from Profiler Window Active Profiler drop down menu by select appropriate device.
Android
Remote profiling can be enabled on Android devices through two different paths : WiFi or ADB.
For WiFi profiling, follow these steps:
- Make sure to disable Mobile Data on your Android device.
- Connect your Android device to your WiFi network.
- Check the "Autoconnect Profiler" checkbox in Unity's build settings dialog.
- Attach your device to your Mac/PC via cable and hit "Build & Run" in Unity Editor.
- When the app launches on the device, open the profiler window in Unity Editor (Window->Profiler)
- If the Unity Editor fails to autoconnect to the device, select the appropriate device from the Profiler Window Active Profiler drop down menu.
Note: The Android device and host computer (running the Unity Editor) must both be on the same subnet for the device detection to work.
For ADB profiling, follow these steps:
- Attach your device to your Mac/PC via cable and make sure ADB recognizes the device (i.e. it shows in adb devices list).
- Open a Terminal window / CMD prompt and enter
adb forward tcp:54999 localabstract:Unity-<insert bundle identifier here>
- Check the "Development Build" checkbox in Unity's build settings dialog, and hit "Build & Run".
- When the app launches on the device, open the profiler window in Unity Editor (Window->Profiler)
- Select the AndroidProfiler(ADB@127.0.0.1:54999) from the Profiler Window Active Profiler drop down menu.
Note: The entry in the drop down menu is only visible when the selected target is Android.
If you are using a firewall, you need to make sure that ports 54998 to 55511 are open in the firewall's outbound rules - these are the ports used by Unity for remote profiling.
Lightmapping
This an introductory description of lightmapping in Unity. For more advanced topics see in-depth description of lightmapping in Unity
Unity has a built-in lightmapper: it's Beast by Illuminate Labs. Lightmapping is fully integrated in Unity. This means that Beast will bake lightmaps for your scene based on how your scene is set up within Unity, taking into account meshes, materials, textures and lights. It also means that lightmapping is now an integral part of the rendering engine - once your lightmaps are created you don't need to do anything else, they will be automatically picked up by the objects.

Preparing the scene and baking the lightmaps
Selecting – from the menu will open the Lightmapping window:
- Make sure any mesh you want to be lightmapped has proper UVs for lightmapping. The easiest way is to choose the option in mesh import settings.
- In the pane mark any Mesh Renderer or Terrain as – this will tell Unity, that those objects won't move nor change and they can be lightmapped.
- To control the resolution of the lightmaps, go to the pane and adjust the value. (To have a better understanding on how you spend your lightmap texels, look at the small window within the and select ).
- Press
- A progress bar appears in Unity Editor's status bar, in the bottom right corner.
- When baking is done, you can see all the baked lightmaps at the bottom of the Lightmap Editor window.
Scene and game views will update - your scene is now lightmapped!
Tweaking Bake Settings
Final look of your scene depends a lot on your lighting setup and bake settings. Let's take a look at an example of some basic settings that can improve lighting quality.
This is a basic scene with a couple of cubes and one point light in the centre. The light is casting hard shadows and the effect is quite dull and artificial.
Selecting the light and opening the pane of the window exposes Shadow Radius and Shadow Samples properties. Setting Shadow Radius to 1.2, Shadow Samples to 100 and re-baking produces soft shadows with wide penumbra - our image already looks much better.
With Unity Pro we can take the scene one step further by enabling Global Illumination and adding a Sky Light. In the pane we set the number of Bounces to 1 and the Sky Light Intensity to 0.5. The result is much softer lighting with subtle diffuse interreflection effects (color bleeding from the green and blue cubes) - much nicer and it's still only 3 cubes and a light!

Lightmapping In-Depth
For more information about the various lightmapping-related settings, please refer to the in-depth description of lightmapping in Unity.
Page last updated: 2010-11-02LightmappingInDepth
If you are about to lightmap your first scene in Unity, this Quickstart Guide might help you out.
Lightmapping is fully integrated in Unity, so that you can build entire levels from within the Editor, lightmap them and have your materials automatically pick up the lightmaps without you having to worry about it. Lightmapping in Unity means that all your lights' properties will be mapped directly to the Beast lightmapper and baked into textures for great performance. Unity Pro extends this functionality by Global Illumination, allowing for baking realistic and beautiful lighting, that would otherwise be impossible in realtime. Additionally Unity Pro brings you sky lights and emissive materials for even more interesting scene lighting.
In this page you will find a more in-depth description of all the attributes that you can find in the Lightmapping window. To open the Lightmapping window select – .

Object
Per-object bake settings for lights, mesh renderers and terrains - depending on the current selection.
Mesh Renderers and Terrains:
| Static | Mesh Renderers and Terrains have to marked as static to be lightmapped. |
| Scale In Lightmap | (Mesh Renderers only) Bigger value will result in more resolution to be dedicated to the give mesh renderer. The final resolution will be proportional (Scale in lightmap)*(Object's word-space surface area)*(Global bake settings Resolution value). A value of 0 will result in the object not being lightmapped (it will still affect other lightmapped objects). |
| Lightmap Size | (Terrains only) Lightmap size for this terrain instance. Terrains are not atlased as other objects - they get their individual lightmaps instead. |
| Atlas | Atlasing information – will be updated automatically, if Lock Atlas is disabled. If Lock Atlas is enabled, those parameters won't be modified automatically and can be edited manually. |
| Lightmap Index | An index into the lightmap array. |
| Tiling | (Mesh Renderers only) Tiling of object's lightmap UVs. |
| Offset | (Mesh Renderers only) Offset of object's lightmap UVs. |
Lights:
| Lightmapping | The Lightmapping mode: Realtime Only, Auto or Baked Only. See Dual Lightmaps description below. |
| Color | The color of the light. Same property is used for realtime rendering. |
| Intensity | The intensity of the light. Same property is used for realtime rendering. |
| Bounce Intensity | A multiplier to the intensity of indirect light emitted from this particular light source. |
| Baked Shadows | Controls whether shadows are casted from objects lit by this light (controls realtime shadows at the same time in case of Auto lights). |
| Shadow Radius | (Point and Spot lights only) Increase this value for soft direct shadows - it increases the size of the light for the shadowing (but not lighting) calculations. |
| Shadow Angle | (Directional lights only) Increase this value for soft direct shadows - it increases the angular coverage of the light for the shadowing (but not lighting) calculations. |
| Shadow Samples | If you've set Shadow Radius or Angle above zero, increase the number of Shadow Samples as well. Higher sample numbers remove noise from the shadow penumbra, but might increase rendering times. |
Bake
Global bake settings.
| Mode | Controls both offline lightmap baking and runtime lightmap rendering modes. In Dual Lightmaps mode both near and far lightmaps will be baked; only deferred rendering path supports rendering dual lightmaps. Single Lightmaps mode results in only the far lightmap being baked; can also be used to force single lightmaps mode for the deferred rendering path. |
| Use in forward rendering | (Dual lightmaps only) Enables dual lightmaps in forward rendering. Note that this will require you to create your own shaders for the purpose. |
| Quality | Presets for high (good-looking) and low (but fast) quality bakes. They affect the number of final gather rays, contrast threshold and some other final gather and anti-aliasing settings. |
| Bounces | The number of light bounces in the Global Illumination simulation. At least one bounce is needed to give a soft, realistic indirect lighting. 0 means only direct light will be computed. |
| Sky Light Color | Sky light simulates light emitted from the sky from all the directions - great for outdoor scenes. |
| Sky Light Intensity | The intensity of the sky light - a value of 0 disables the sky light. |
| Bounce Boost | Boosts indirect light, can be used to increase the amount of bounced light within the scene without burning out the render too quickly. |
| Bounce Intensity | A multiplier to the intensity of the indirect light. |
| Final Gather Rays | The number of rays shot from every final gather point - higher values give better quality. |
| Contrast Threshold | Color contrast threshold, above which new final gather points will be created by the adaptive sampling algorithm. Higher values make Beast be more tolerant about illumination changes on the surface, thus producing smoother but less-detailed lightmaps. Lower numbers of final gather rays might need higher contrast threshold values not to force additional final gather points to be created. |
| Interpolation | Controls the way the color from final gather points will be interpolated. 0 for linear interpolation, 1 for advanced, gradient-based interpolation. In some cases the latter might introduce artifacts. |
| Interpolation Points | The number of final gather points to interpolate between. Higher values give more smooth results, but can also smooth out details in the lighting. |
| Ambient Occlusion | The amount of ambient occlusion to be baked into the lightmaps. Ambient occlusion is the visibility function integrated over the local hemisphere of size Max Distance, so doesn't take into account any lighting information. |
| Max Distance | Beyond this distance a ray is considered to be unoccluded. 0 stands for infinitely long rays. |
| Contrast | Controls the transition between fully occluded to not occluded. |
| Lock Atlas | When Lock Atlas is enabled, automatic atlasing won't be run and lightmap index, tiling and offset on the objects won't be modified. |
| Resolution | The resolution of the lightmaps in texels per world unit, so a value of 50 and a 10unit by 10unit plane will result in the plane occupying 500x500 pixels in the lightmap. |
Maps
The editable array of all the lightmaps.
| Compressed | Toggles compression on all lightmap assets for this scene. |
| Array Size | Size of the lightmaps array (0 to 254). |
| Lightmaps Array | The editable array of all the lightmaps in the current scene. Unassigned slots are treated as black lightmaps. Indices correspond to the Lightmap Index value on Mesh Renderers and Terrains. Unless Lock Atlas is enabled, this array will get auto-resized and populated whenever you bake lightmaps. |
Lightmap Display
Utilities for controlling how lightmaps are displayed in the editor. Lightmap Display is a sub window of the Scene View, visible whenever the Lightmapping window is visible.
| Use Lightmaps | Whether to use the lightmaps during the rendering or not. |
| Shadow Distance | The distance at which Auto lights and Close By lightmaps fade out to just Far Away lightmaps. This setting overrides but not overwrites the QualitySettings.shadowDistance setting. |
| Show Resolution | Toggles the scene view Lightmap Resolution mode, which allows you to preview how you spend your lightmap texels on objects marked as static. |
Details
Dual Lightmaps
Dual lightmaps is Unity's approach to make lightmapping work with specular, normal mapping and proper blending of baked and realtime shadows. It's also a way to make your lightmaps look good even if the lightmap resolution is low.
Dual lightmaps by default can only be used in the Deferred Lighting rendering path. In Forward rendering path, it's possible to enable Dual Lightmaps by writing custom shaders (use dualforward surface shader directive).
Dual lightmaps use two sets of lightmaps:
- Far: Contains full illumination
- Near: Contains indirect illumination from lights marked as Auto, full illumination from lights marked as Bake Only, emissive materials and sky lights.
Realtime Only lights are never baked. The Near lightmap set is used within the distance from the camera smaller than the Shadow Distance quality setting.
Within this distance Auto lights are rendered as realtime lights with specular bump and realtime shadows (this makes their shadows blend correctly with shadows from Realtime Only lights) and their indirect light is taken from the lightmap. Outside Shadow Distance Auto lights no longer render in realtime and full illumination is taken from the Far lightmap (Realtime Only lights are still there, but with disabled shadows).
The scene below contains one directional light with lightmapping mode set to the default Auto, a number of static lightmapped objects (buildings, obstacles, immovable details) and some dynamic moving or movable objects (dummies with guns, barrels). The scene is baked and rendered in dual lightmaps mode: behind the shadow distance buildings are fully lit only by lightmaps, while the two dummies are dynamically lit but don't cast shadows anymore; in front of the shadow distance both the dummy and static lightmapped buildings and ground are lit in realtime and cast realtime shadows, but the soft indirect light comes from the near lightmap.


Single Lightmaps
Single Lightmaps is a much simpler technique, but it can be used in any rendering path. All static illumination (i.e. from baked only and auto lights, sky lights and emissive materials) gets baked into one set of lightmaps. These lightmaps are used on all lightmapped objects regardless of shadow distance.
To match the strength of dynamic shadows to baked shadows, you need to manually adjust the Shadow Strength property of your light:

Adjusting Shadow Strength of a light from the original value of 1.0 to 0.7.
Lightmapped Materials
Unity doesn't require you to select special materials to use lightmaps. Any shader from the built-in shaders (and any Surface Shader you write, for that matter) already supports lightmaps out of box, without you having to worry about it - it just works.
Lightmap Resolution
With the Resolution bake setting you control how many texels per unit are needed for your scene to look good. If there's a 1x1 unit plane in your scene and the resolution is set to 10 texels per unit, your plane will take up 10x10 texels in the lightmap. Resolution bake setting is a global setting. If you want to modify it for a special object (make it very small or very big in the lightmap) you can use Scale in Lightmap property of Mesh Renderers. Setting Scale in Lightmap to 0 will result in the object not being lightmapped at all (it will still influence lightmaps on other objects). Use the Lightmap Resolution scene view render mode to preview how you spend your lightmap texels.

Lightmap Resolution scene view mode visualising how the lightmap texels are spent (each square is one texel).
UVs
A mesh that you're about to lightmap needs to have UVs suitable for lightmapping. The easiest way to ensure that is to enable the Generate Lightmap UVs option in Mesh Import Settings for a given mesh.
For more information see the Lightmap UVs page.
Material Properties
The following material properties are mapped to Beast's internal scene representation:
- Color
- Main Texture
- Specular Color
- Shininess
- Transparency
- Alpha-based: when using a transparent shader, main texture's alpha channel will control the transparency
- Color-based: Beast's RGB transparency can be enabled by adding a texture property called _TransparencyLM to the shader. Bear in mind that this transparency is defined in the opposite way compared to the alpha-based transparency: here a pixel with value (1, 0, 0) will be fully transparent to red light component and fully opaque to green and blue component, which will result in a red shadow; for the same reason white texture will be fully transparent, while black texture - fully opaque.
- Emission
- Self Illuminated materials will emit light tinted by the Color and Main Texture and masked by the Illum texture. The intensity of emitted light is proportional to the Emission property (0 disables emission).
- Generally large and dim light sources can be modeled as objects with emissive materials. For small and intense lights normal light types should be used, since emissive materials might introduce noise in the rendering.
Note: When mapping materials to Beast, Unity detects the 'kind' of the shader by the shader's properties and path/name keywords such as: 'Specular', 'Transparent', 'Self-Illumin', etc.
Advanced
Automatic Atlasing
Atlasing (UV-packing) is performed automatically every time you perform a bake and normally you don't have to worry about it - it just works.
Object's world-space surface area is multiplied by the per-object Scale In Lightmap value and by the global Resolution and the result determines the size of the object's UV set (more precisely: the size of the [0,1]x[0,1] UV square) in the lightmap. Next, all objects are packed into as few lightmaps as possible, while making sure each of them occupies the amount of space calculated in the previous step. If a UV set for a given object occupies only part of the [0,1]x[0,1] square, in many cases atlasing will move neighboring UV sets closer, to make use of the empty space.
As a result of atlasing, every object to be lightmapped has it's place in one of the lightmaps and that space doesn't overlap with any other object's space. The atlasing information is stored as three values: Lightmap Index, Tiling (scale) and Offset in Mesh Renderers and as one value: Lightmap Index in Terrains and can be viewed and modified via the Object pane of the lightmapping window.

Right-clicking a lightmap allows to select all game objects, that are using the chosen lightmap. Lightmaps of the active object from the current selection will be highlighted in yellow.
Atlasing can only modify per-object data which is Lightmap Index, Tiling and Offset and can not modify the UV set of an object, as the UV set is stored as part of the shared mesh. Lightmap UVs for a mesh can only be created at import time using Unity's built-in auto-unwrapper or in an external 3D package before importing to Unity.
Lock Atlas
When Lock Atlas is enabled, automatic atlasing won't be run and Lightmap Index, Tiling and Offset on the objects won't be modified. Beast will rely on whatever is the current atlasing, so it's the user's responsibility to maintain correct atlasing (e.g. no overlapping objects in the lightmaps, no objects referencing a lightmap slot past the lightmap array end, etc.).
Lock Atlas opens up the possibility for alternative workflows when sending your object's for lightmapping. You can then perform atlasing manually or via scripting to fit you specific needs; you can also lock the automatically generated atlasing if you are happy with the current atlasing, have baked more sets of lightmaps for your scene and want to make sure, that after adding one more object to the scene the atlasing won't change making the scene incompatible with other lightmap sets.
Remember that Lock Atlas locks only atlasing, not the mesh UVs. If you change your source mesh and the mesh importer is set to generate lightmap UVs, the UVs might be generated differently and your current lightmap will look incorrectly on the object - to fix this you will need to re-bake the lightmap.
Custom Beast bake settings
If you need even more control over the bake process, see the custom Beast settings page.
Page last updated: 2011-10-25LightmappingCustomSettings
If you need a different baking setup than the one Unity is using by default, you can specify it by using custom Beast settings.
Beast reads bake settings defined in xml format. Normally Unity generates the xml file based on the configuration you have chosen in Bake pane of the Lightmap Editor window and a number of other internal settings. You can override those settings by specifying your own settings in Beast's xml format.
To have Unity automatically generate the xml file for you, click the tab menu in the upper-right corner of the Lightmap Editor window and select Generate Beast settings file. You will notice that the BeastSettings.xml file appeared in the project next to your lightmaps and that the Lightmap Editor informs you, that your xml settings will override Unity's settings during the next bake. Click the open button to edit your custom settings.

Adaptive Sampling
Beast uses an adaptive sampling scheme when sampling light maps. The light must differ more than a user set contrast threshold for Beast to place additional samples in an area. The sample area is defined by a Min and Max sample rate. The user sets the rate in the -4..4 range which means that Beast samples from 1/256 sample per pixel to 256 samples per pixel (the formula is: 4 to the power of samplerate). It is recommended to use at least one sample per pixel for production use (Min sample rate = 0). Undersampling is most useful when doing camera renders or baking textures with big UV-patches. When Beast has taken all necessary samples for an area, the final pixel value is weighed together using a filter. The look the filter produces is dependent on the filter type used and the size of the filter kernel. The available filters are:
- Box: Each sample is treated as equally important. The fastest filter to execute but it gives blurry results.
- Triangle: The filter kernel is a tent which means that distant samples are consideredless important.
- Gauss: Uses the Gauss function as filter kernel. This gives the best results (removes noise, preserves details).
There are more filters available, but these three are the most useful. The kernel (filter) size is given in pixels in the range 1..3. Beast actually uses all sub pixels when filtering, which yields better results than doing it afterwards in Photoshop.
| AASettings | |
| samplingMode | The sampling strategy to use. Default is Adaptive. Adaptive: Adaptive anti-aliasing scheme for under/over sampling (from 1/256 up to 256 samples per pixel). SuperSampling: Anti-aliasing scheme for super sampling (from 1 up to 128 samples per pixel). |
| minSampleRate | Sets the min sample rate, default is 0 (ie one sample per pixel). |
| maxSampleRate | Sets the max sample rate, the formula used is 4^maxSampleRate (1, 4, 16, 64, 256 samples per pixel) |
| contrast | The contrast value which controls if more samples are necessary - a lower value forces more samples. |
| filter | Sets which filter type to use. Most useful ones for Baking are Box, Triangle and Gauss. |
| filterSize | Sets the filter size in pixels, from 1 to 3. |
Texture Bake
These settings help getting rid of any artifacts that are purely related to how lightmaps are rasterized and read from a texture.
| TextureBakeSettings | |
| edgeDilation | Expands the rendered region with the number of pixels specified. This is needed to prevent the artifacts occurring when GPU filters in empty pixels from around the rendered region. |
| bilinearFilter | Is used to make sure that the data in the lightmap is "correct" when the GPU applies bilinear filtering. This is most noticable when the atlases are tightly packed. If there is only one pixel between two different UV patches, the bilinear functionality in Beast will make sure the that pixel is filled with the color from the correct patch. This minimizes light seams. |
| conservativeRasterization | Is used when the UV-chart does not cover the entire pixel. If such a layout is used, Beast may miss the texel by mistake. If conservative rasterization is used Beast will guarantee that it will find a UV-layout if present. Note that Beast will pick any UV-layout in the pixel. Conservative Rasterization often needs to be turned on if the UV atlases are tightly packed in low resolutions or if there are very thin objects present. |
| bgColor | The background color of the lightmap. |
Environment
The environment settings in Beast control what happens if a ray misses all geometry in the scene. The environment can either be a constant color or an HDR image in lat-long format for Image Based Lighting (IBL). Note that environments should only be used for effects that can be considered to be infinitely far away, meaning that only the directional component matters.
Defining an environment is usually a very good way to get very pleasing outdoor illumination results, but might also increase bake times.
| EnvironmentSettings | |
| giEnvironment | The type of Environment: None, Skylight or IBL. |
| giEnvironmentIntensity | A scale factor for the intensity, used for avoiding gamma correction errors and to scale HDR textures to something that fits your scene. (in Unity: Sky Light Intensity) |
| skyLightColor | A constant environment color. Used if type is Skylight. It is often a good idea to keep the color below 1.0 in intensity to avoid boosting by gamma correction. Boost the intensity instead with the giEnvironmentIntensity setting. (in Unity: Sky Light Color) |
| iblImageFile | High-dynamic range IBL background image in Long-Lat format, .HDR or .EXR, absolute path. |
Shadows
Settings for ray-traced shadows.
| RenderSettings | |
| bias | An error threshold to avoid double intersections of shadow rays. For example, a shadow ray should not intersect the same triangle as the primary ray did, but because of limited numerical precision this can happen. The bias value moves the intersection point to eliminate this problem. If set to zero this value is computed automatically depending on the scene size. |
| maxShadowRays | The maximum number of shadow rays per point that will be used to generate a soft shadow for any light source. Use this to shorten render times at the price of soft shadow quality. This will lower the maximum number of rays sent for any light sources that have a shadowSamples setting higher than this value, but will not raise the number if shadowSamples is set to a lower value. |
| maxRayDepth | The maximum amount of bounces a ray can have before being considered done. A bounce can be a reflection or a refraction. Increase the value if a ray goes through many transparent triangles before hitting an opaque object and you get light in areas that should be in the shadow. Common failure case: trees with alpha-tested leaves placed in a shadow of a mountain. |
| giTransparencyDepth | Maximum transparency depth for global illumination rays, i.e. the number of transparent surfaces the ray can go through before it assume it has been absorbed. Lower values speed up rendering in scenes with a lot of dense foliage and the like, but may cause your overlapping transparent object to cast too much shadow. Default is 2. |
Global Illumination
The Global Illumination system allows you to use two separate algorithms to calculate indirect lighting. You can for instance calculate multiple levels of light bounces with a fast algorithm like the Path Tracer, and still calculate the final bounce with Final Gather to get a fast high-quality global illumination render. Both subsystems have individual control of Intensity and Saturation to boost the effects if necessary.
It's recommended to use FinalGather as the primary integrator and either None or PathTracer as the secondary integrator. Unity uses the first option (so final gather only) as the default, since it produces the best quality renders in most cases. Path Tracer should be used if many indirect bounces are needed and Final Gather-only solution with acceptable quality would take to much time to render.
| GISettings | |
| enableGI | Setting to true enables Global Illumination. |
| primaryIntegrator | The integrator used for the final calculations of indirect light. FinalGather is default. |
| secondaryIntegrator | The integrator used for initial bounces of indirect light. Default is None, PathTracer is optional. |
| primaryIntensity | As a post process, converts the color of the primary integrator result from RGB to HSV and scales the V value. (in Unity: Bounce Intensity) |
| primarySaturation | As a post process, converts the color of the primary integrator result from RGB to HSV and scales the S value. |
| secondaryIntensity | As a post process, converts the color of the secondary integrator result from RGB to HSV and scales the V value. |
| secondarySaturation | As a post process, converts the color of the secondary integrator result from RGB to HSV and scales the S value. |
| diffuseBoost | This setting can be used to exaggerate light bouncing in dark scenes. Setting it to a value larger than 1 will push the diffuse color of materials towards 1 for GI computations. The typical use case is scenes authored with dark materials, this happens easily when doing only direct lighting since it is easy to compensate dark materials with strong light sources. Indirect light will be very subtle in these scenes since the bounced light will fade out quickly. Setting a diffuse boost will compensate for this. Note that values between 0 and 1 will decrease the diffuse setting in a similar way making light bounce less than the materials says, values below 0 is invalid. The actual computation taking place is a per component pow(colorComponent, (1.0 / diffuseBoost)). (in Unity: Bounce Boost) |
Final Gather
The settings below control the quality or correctness of the Final Gather solution. The normal usage scenario is this:
- For each baking set up Contrast Threshold and Number of Rays may be adjusted. There are no perfect settings for these since they depend on the complexity of the geometry and light setup.
- Check Visibility and Light Leakage reduction are expensive operations and should only be used to remedy actual light leakage problems. These settings will only help if the light leakage is caused by the Global Illumination calculations. A very common light leakage situation occurs with a wall as a single plane with no thickness. The light leaking through in that situation does not come from GI.
- Gradient threshold should only be changed if there are white halos around corners.
Steps 2 and 3 should not need much tweaking in most scenes.
| GISettings | |
| fgContrastThreshold | Controls how sensitive the final gather should be for contrast differences between the points during precalculation. If the contrast difference is above this threshold for neighbouring points, more points will be created in that area. This tells the algorithmto place points where they are really needed, e.g. at shadow boundaries or in areas where the indirect light changes quickly. Hence this threshold controls the number of points created in the scene adaptively. Note that if a low number of final gather rays are used, the points will have high variance and hence a high contrast difference. In that the case contrast threshold needs to be raised to prevent points from clumping together or using more rays per sample. (in Unity: Contrast Threshold) |
| fgRays | The maximum number of rays taken in each Final Gather sample. More rays gives better results but take longer to evaluate. (in Unity: Final Gather Rays) |
| fgCheckVisibility | Turn this on to reduce light leakage through walls. When points are collected to interpolate between, some of them can be located on the other side of geometry. As a result light will bleed through the geometry. To prevent this Beast can reject points that are not visible. |
| fgCheckVisibilityDepth | Controls for how many bounces the visibility checks should be performed. Adjust this only if experiencing light leakage when using multi bounce Final Gather. |
| fgLightLeakReduction | This setting can be used to reduce light leakage through walls when using final gather as primary GI and path tracing as secondary GI. Leakage, which can happen when e.g. the path tracer filters in values on the other side of a wall, is reduced by using final gather as a secondary GI fallback when sampling close to walls or corners. When this is enabled a final gather depth of 3 will be used automatically, but the higher depths will only be used close to walls or corners. Note that this is only usable when path tracing is used as secondary GI. |
| fgLightLeakRadius | Controls how far away from walls the final gather will be called again, instead of the secondary GI. If 0.0 is used Beast will try to estimate a good value. If this does not eliminate the leakage it can be set to a higher value manually. |
| fgGradientThreshold | Controls how the irradiance gradient is used in the interpolation. Each point stores its irradiance gradient which can be used to improve the interpolation. In some situations using the gradient can result in white "halos" and other artifacts. This threshold can be used to reduce those artifacts (set it low or to 0). (in Unity: Interpolation) |
| fgInterpolationPoints | Sets the number of final gather points to interpolate between. A higher value will give a smoother result, but can also smooth out details. If light leakage is introduced through walls when this value is increased, checking the sample visibility solves that problem. (in Unity: Interpolation Points) |
| fgNormalThreshold | Controls how sensitive the final gather should be for differences in the points normals. A lower value will give more points in areas of high curvature. |
| fgDepth | Controls the number of indirect light bounces. A higher value gives a more correct result, but the cost is increased rendering time. For cheaper multi bounce GI, use Path Tracer as the secondary integrator instead of increasing depth. (in Unity: Bounces) |
| fgAttenuationStart | The distance where attenuation is started. There is no attenuation before this distance. This can be used to add a falloff effect to the final gather lighting. When fgAttenuationStop is set higher than 0.0 this is enabled. |
| fgAttenuationStop | Sets the distance where attenuation is stopped (fades to zero). There is zero intensity beyond this distance. To enable attenuation set this value higher than 0.0. The default value is 0.0. |
| fgFalloffExponent | This can be used to adjust the rate by which lighting falls off by distance. A higher exponent gives a faster falloff. |
| fgAOInfluence | Blend the Final Gather with Ambient Occlusion. Range between 0..1. 0 means no occlusion, 1 is full occlusion. If Final Gather is used with multiple depths or with Path Tracing as Secondary GI the result can become a bit "flat". A great way to get more contrast into the lighting is to factor in a bit of ambient occlusion into the calculation. This Ambient Occlusion algorithm affects only final gather calculations. The Ambient Occlusion exposed in the Lightmapping window is calculated differently - by a separate, geometry-only pass. |
| fgAOMaxDistance | Max distance for the occlusion rays. Beyond this distance a ray is considered to be unoccluded. Can be used to avoid full occlusion for closed scenes such as rooms or to limit the AO contribution to creases. |
| fgAOContrast | Can be used to adjust the contrast for ambient occlusion. |
| fgAOScale | A scaling of the occlusion values. Can be used to increase or decrease the shadowing effect. |
Path Tracer
Use path tracing to get fast multi bounce global illumination. It should not be used as primary integrator for baking since the results are quite noisy which does not look good in light maps. It can be used as primary integrator to adjust the settings, to make sure the cache spacing and accuracy is good. The intended usage is to have it set as secondary integrator and have single bounce final gather as primary integrator. Accuracy and Point Size can be adjusted to make sure that the cache is sufficiently fine grained.
| GISettings | |
| ptAccuracy | Sets the number of paths that are traced for each sample element (pixel, texel or vertex). For preview renderings, a low value like 0.5 to 0.1 can be used. This means that 1/2 to 1/10 of the pixels will generate a path. For production renderings values above 1.0 may be used, if necessary to get good quality. |
| ptPointSize | Sets the maximum distance between the points in the path tracer cache. If set to 0 a value will be calculated automatically based on the size of the scene. The automatic value will be printed out during rendering, which is a good starting value if the point size needs to be adjusted. |
| ptCacheDirectLight | When this is enabled the path tracer will also cache direct lighting from light sources. This increases performance since fewer direct light calculations are needed. It gives an approximate result, and hence can affect the quality of the lighting. For instance indirect light bounces from specular highlights might be lost. |
| ptCheckVisibility | Turn this on to reduce light leakage through walls. When points are collected to interpolate between, some of them can be located on the other side of geometry. As a result light will bleed through the geometry. To prevent this Beast can reject points that are not visible. Note: If using this turn off light leakage reduction for Final Gather. |
LightmappingUV
Unity will use UV2 for lightmaps, if the channel is present. Otherwise it will use primary UVs.
Unity can unwrap your mesh for you to generate lightmap UVs. Just use the Generate Lightmap UVs setting in Mesh Import Settings.
Advanced Options for Generate Lightmap UVs:
| Pack Margin | The margin between neighboring patches, assuming the mesh will take entire 1024x1024 lightmap measured in pixels. That has great effect: to allow filtering, Lightmap will contain lighting information in texels near patch border. So to avoid light bleeding when applying Lightmap there should be some margin between patches. |
| Hard Angle | The angle between neighboring triangles, after which the edge between them will be considered hard edge and seam will be created. If you set it to 180 degrees all edges will be considered smooth: this is useful for organic models. The default value 88 degrees: this is useful for mechanical models |
| Angle Error | Maximum possible deviation of UVs angles from source geometry angles, in percentage. Basically it controls how similar triangles in uv space will be to triangles in original geometry (the value, the more similar triangles will be). Usually you wants it pretty low to avoid artifacts when applying Lightmap. Default is 8 percent. (This value goes from 0 to 100) |
| Area Error | Maximum possible deviation of UVs areas from source geometry areas, in percentage. Basically it controls how good relative triangle areas are preserved. Usually that is not very critical, and moving that up can allow to create less patches; although you should recheck that distortion do not deteriorate Lightmap quality, as that way triangles may have different resolution. Default is 15 percent. (This value goes from 0 to 100) |
If you prefer to provide your own UVs for lightmapping, remember that a good UV set for lightmapping:
- Is contained within the [0,1]x[0,1] space
- Has no overlapping faces.
- Has low angle distortion, that is deviation of angles in UVs and in source geometry.
- Has low area distortion, that is, relative scale of triangles is mostly preserved, unless you really want some areas to have bigger Lightmap Resolution.
- Has enough margin between individual patches.
Some examples of the hints suggested above:
Angle distortion
These screenshots were made for equal resolution, but with different uvs. Look at artefacts, and how the shape of light was slightly changed. There are only 4 triangles, actually, so shape distortion can be far uglier.

Area distortion
There are 2 spotlight with same parameters, the difference being only pointing to areas with different lightmap resolution, due to relative triangle scale being not preserved

LightProbes
Although lightmapping adds greatly to the realism of a scene, it has the disadvantage that non-static objects in the scene are less realistically rendered and can look disconnected as a result. It isn't possible to calculate lightmapping for moving objects in real time but it is possible to get a similar effect using light probes. The idea is that the lighting is sampled at strategic points in the scene, denoted by the positions of the probes. The lighting at any position can then be approximated by interpolating between the samples taken by the nearest probes. The interpolation is fast enough to be used during gameplay and helps avoid the disconnection between the lighting of moving objects and static lightmapped objects in the scene.
Adding Light probes
The Light Probe Group component (menu: ) can be added to any available object in the scene. The inspector can be used to add new probes to the group. The probes appear in the scene as yellow spheres which can be positioned in the same manner as GameObjects. Selected probes can also be duplicated with the usual keyboard shortcut (ctrl+d/cmd+d).

Choosing Light Probe positions
Remember to place probes where you want to sample light or sample darkness. The probes need to form a volume within the scene for the space subdivision to work properly.
The simplest approach to positioning is to arrange them in a regular 3D grid pattern. While this setup is simple and effective, it is likely to consume a lot of memory (each light probe is essentially a spherical, panoramic HDR image of the view from the sample point). It is worth noting that probes are only needed for regions that players, NPCs or other dynamic objects can actually move to. Also, since lighting conditions are interpolated for positions between probes, it is not necessary to use lots of them across areas where the light doesn't change very much. For example, a large area of uniform shadow would not need a large number of probes and neither would a brightly lit area far away from reflective objects. Probes are generally needed where the lighting conditions change abruptly, for instance at the edge of a shadow area or in places where pieces of scenery have different colors.
In some cases, the infrastructure of the game can be useful in choosing light probe positions. For example, a racing game typically uses waypoints around the track for AI and other purposes. These are likely to be good candidates for probe positions and it would likely be straightforward to set these positions from an editor script. Similarly, navigation meshes typically define the areas that can be reached by players and these also lend themselves to automated positioning of probes.
Here light probes have been baked over surfaces where our characters can walk on, but only where there are interesting lighting changes to capture:

Flat 2D levels
As it is now, the light probe system can't bake a completely flat probe cloud. So even if all your characters move only on a plane, you still have to take care to position at least some probes in a higher layer, so that a volume is formed and interpolation can work properly.

Good: This is the original probe placement. The characters can move up the ramps and up onto the boxes, so it's good to sample lighting up there as well.

Good: Here we assume the characters can only move on the plane. Still, there's a couple of probes placed a little bit higher, so that a volume is formed and thin cell are avoided.

Bad: The probes are placed too flat, which creates really long and thin cells and produces unintuitive interpolation results.
Using Light Probes
To allow a mesh to receive lighting from the probe system, you should enable the Use Light Probes option on its MeshRenderer:


The probe interpolation requires a point in space to represent the position of the mesh that is receiving light. By default, the centre of the mesh's bounding box is used but it is possible to override this by dragging a Transform to the MeshRenderer's Light Probe Anchor property (this Transform's position will be used as the interpolation point instead). This may be useful when an object contains two separate adjoining meshes; if both meshes are lit individually according to their bounding box positions then the lighting will be discontinuous at the place where they join. This can be prevented by using the same Transform (for example the parent or a child object) as the interpolation point for both MeshRenderers.
When an object using light probes is the active selected object in the Light Probes Scene View mode, its interpolated probe will be rendered on top of it for preview. The interpolated probe is the one used for rendering the object and is connected with 4 thin blue lines (3 when outside of the probe volume) to the probes it is being interpolated between:

Dual Lightmaps vs. Single Lightmaps mode
In Single Lightmaps mode all static lighting (including lights set to 'Auto' lightmapping mode) is baked into the light probes.
In Dual Lightmaps mode light probes will store lighting in the same configuration as 'Near' lightmaps, i.e. full illumination from sky lights, emissive materials, area lights and 'Baked Only' lights, but only indirect illumination from 'Auto' lights. Thanks to that the object can be lit in real-time with the 'Auto' lights and take advantage of dynamic elements such as real-time shadows, but at the same time receive indirect lighting added to the scene by these lights.
Page last updated: 2012-01-17HDR
In standard rendering, the red, green and blue values for a pixel are each represented by a fraction in the range 0..1, where 0 represents zero intensity and 1 represents the maximum intensity for the display device. While this is straightforward to use, it doesn't accurately reflect the way that lighting works in a real life scene. The human eye tends to adjust to local lighting conditions, so an object that looks white in a dimly lit room may in fact be less bright than an object that looks grey in full daylight. Additionally, the eye is more sensitive to brightness differences at the low end of the range than at the high end.
More convincing visual effects can be achieved if the rendering is adapted to let the ranges of pixel values more accurately reflect the light levels that would be present in a real scene. Although these values will ultimately need to be mapped back to the range available on the display device, any intermediate calculations (such as Unity's image effects) will give more authentic results. Allowing the internal representation of the graphics to use values outside the 0..1 range is the essence of High Dynamic Range (HDR) rendering.
Working with HDR
HDR is enabled separately for each camera using a setting on the Camera component:-

When HDR is active, the scene is rendered into an HDR image buffer which can accommodate pixel values outside the 0..1 range. This buffer is then postprocessed using image effects such as HDR bloom. The tonemapping image effect is what converts the HDR image into the standard low dynamic range (LDR) image to be sent for display. The conversion to LDR must be applied at some point in the image effect pipeline but it need not be the final step if LDR-only image effects are to be applied afterwards. For convenience, some image effects can automatically convert to LDR after applying an HDR effect (see Scripting below).
Tonemapping
Tonemapping is the process of mapping HDR values back into the LDR range. There are many different techniques, and what is good for one project may not be the best for another. A variety of tonemapping image effects have been included in Unity. To use them select Assets -> Import Package -> Image Effects (Pro Only) select the camera in the scene then select Component -> Image Effects ->ToneMapping a detailed description of the tonemapping types can be found in the image effects documentation.

An exceptionally bright seen rendered in HDR. Tonemapping is used to bring the bright intensities back into the displayable range.
HDR Bloom
Using HDR allows for much more control in post processing. LDR bloom has an unfortunate side effect of blurring many areas of a scene even if their pixel intensity is less than 1.0. By using HDR it is possible to only bloom areas where the intensity is greater than one. This leads to a much more desiarable outcome with only super bright elements of a scene bleeding into neighboring pixels. The built in 'Bloom and Lens Flares' image effect now also supports HDR. To attach it to a camera select Assets -> Import Package -> Image Effects (Pro Only) select the camera in the scene then select Component -> Image Effects ->Bloom (Supports HDR and Lens Flare) a detailed description of the 'Bloom and Lens Flares' effect can be found in the image effects documentation.

An exceptionally bright scene where bloom has been applied to intensities greater than 1.0. The bloomed image has also been tonemapped back into the displayable range.
Advantages of HDR
- Colors not being lost in high intensity areas
- Better bloom support
- Reduction of banding in low frequency lighting areas
Disadvantages of HDR
- Uses Floating Point buffers (rendering is slower and requires more VRAM)
- Not supported on all hardware
Usage notes
Forward Rendering
In forward rendering mode HDR is only supported if you have an image effect present. This is due to performance considerations. If you have no image effect present then no tone mapping will exist and intensity truncation will occur. In this situation the scene will be rendered directly to the backbuffer where HDR is not supported.
Deferred Rendering
In HDR mode the light prepass buffer is also allocated as a floating point buffer. This reduces banding in the lighting buffer. HDR is supported in deferred rendering even if no image effects are present.
Scripting
The ImageEffectTransformsToLDR attribute can be added to an image effect script to indicate that the target buffer should be in LDR instead of HDR. Essentially, this means that a script can automatically convert to LDR after applying its HDR image effect.
Page last updated: 2012-01-19Linear Lighting
overview
Linear lighting refers to the process of illuminating a scene with all inputs being linear. Normally textures exist with gamma pre-applied to them this means that when the textures are sampled in a material that they are non linear. If these textures are used in the standard lighting equations it will lead to the result from the equation being incorrect as they expect all input to be linearized before use.
Linear lighting refers to the process of ensuring that both inputs and outputs of a shader are in the correct color space, this results in more correct lighting.
Existing (Gamma) Pipeline
In the existing rendering pipeline all colors and textures are sampled in gamma space, that is gamma correction is not removed from images or colors before they are used in a shader. Due to this a situation arises where the inputs to the shader are in gamma space, the lighting equation uses these inputs as if they were in linear space and finally no gamma correction is applied to the final pixel. Much of the time this looks acceptable as the two wrongs go some way to cancelling each other out. But it is not correct.
Linear Lighting Pipeline
If linear lighting is enabled inputs to the shader program are supplied with the gamma correction removed from them. For colors this conversion is applied implicitly if you are in linear space. Textures are sampled using hardware sRGB reads, the source texture is supplied in gamma space and then on sampling in the graphics hardware the result is converted automatically. These inputs are then supplied to the shader and lighting occurs as it normally would. The resultant value is then written to the framebuffer. This value will either be gamma corrected and written to the framebuffer, of left in linear space for later gamma correction; this depends on the current rendering configuration.
Differences Between Linear and Gamma Lighting
When using linear lighting input values to the lighting equations are different than in gamma space. This means that as lights striking surfaces will have a different response curve to what the existing Unity rendering pipeline has.
Light Falloff
The falloff from distance and normal based lighting is changed in two ways. Firstly when rendering in linear mode the additional gamma correct that is performed will make light radius' appear larger. Secondly lighting edges will also be harsher. This more correctly models lighting intensity falloff on surfaces.

Linear Intensity Response
When you are using gamma space lighting the colors and textures that are supplied to a shader have a gamma correction applied to them. When they are used in a shader the colors of high luminance are actually brighter then they should be for linear lighting. This means that as light intensity increases the surface will get brighter in a non linear way. This leads to lighting that can be too bright in many places, and can also give models and scenes a washed out feel. When you are using linear lighting, as light intensity increases the response from the surface remains linear. This leads to much more realistic surface shading and a much nicer color response in the surface.

Infinite, 3D Head Scan by Lee Perry-Smith is licensed under a Creative Commons Attribution 3.0 Unported License. Available from: http://www.ir-ltd.net/infinite-3d-head-scan-released
Linear and Gamma Blending
When performing blending into the framebuffer the blending occurs in the color space or the framebuffer. When using gamma rendering this means that non linear colors get blended together. This is incorrect. When using linear space rendering blending occurs in linear space, this is correct and leads to expected results.

Using Linear Lighting
Linear lighting results in a different look to the rendered scene. If you author a project for linear lighting it will most likely not look correct if you change to gamma lighting. Because of this if you move to linear lighting from gamma lighting it may take some time to update the project so that it looks as good as before the switch. That being said enabling linear lighting in Unity is quite simple. The feature is implemented on a per project level and is exposed in the Player Settings which can be located at Edit -> Project Settings -> Player -> Other Settings

Lightmapping
When you are using linear lighting all lighting and textures are linearized, this means that the values that are passed to the lightmapper also need to be modified. When you switch between linear lighting and gamma lighting or back you will need to rebake lightmaps. The Unity lightmapping interface will warn you when the lightmaps are in the incorrect color space.
Supported Platforms
Linear rendering is not supported on all platforms. The build targets that currently support the feature are:
- Windows & Mac (editor, standalone, web player)
- Xbox 360
- PlayStation 3
Even though these targets support linear lighting, it is not guaranteed that the graphics hardware on the device will be able to render the scene properly. You can check the desired color space and the active supported color space by looking at QualitySettings.desiredColorSpace and QualitySettings.activeColorSpace if the desired color space is linear but the active color space is gamma then the player has fallen back to gamma space. This can be used to show a warning box telling the user that the application will not look correct for them or to force an exit from the player.
Linear and Non HDR
When not using HDR a special framebuffer type is used that supports sRGB read and sRGB write (Degamma on read, Gamma on write). This means that just like a texture the values in the framebuffer are gamma corrected. When this framebuffer is used for blending or bound as texture the values have the gamma removed before being used. When these buffers are written to the value that is being written is converted from linear space to gamma space. If you are rendering in linear mode, all post process effects will have their source and target buffers created with sRGB read and write enabled so that post process and post process blending occurs in linear space.
Linear and HDR
When using HDR, rendering is performed into floating point buffers. These buffers have enough resolution to not require conversion to an from gamma space whenever the buffer is accessed, this means that when rendering in linear mode the render targets you use will store the colors in linear space. This means that all blending and post process effects will implicitly be performed in linear space. When the the backbuffer is written to, gamma correction is applied.
GUI and Linear Authored Textures
When rendering Unity GUI we do not perform the rendering in linear space. This means that GUI textures should not have their gamma removed on read. This can be achieved in two ways.
- Set the texture type to GUI in the texture importer
- Check the 'Bypass sRGB Sampling' checkbox int the advanced texture importer
It is also important that lookup textures and other textures which are authored to have their RGB values to mean something specific should bypass sRGB sampling.
This will force the sampled texture to not have gamma removed befor





















