Interface and Engine Architecture

As usual this will not be a comprehensive tutorial on how to use Unity 3D. There is such a plethora of resources from both 3rd parties and Unity Technologies itself that this is not needed.

Here are just a few prominent sites that will be of a great help to new Unity developers.

  • Google. Really, don't underestimate it here. Unity has been around in one form or another for many years now and the internet has accumilated many, many forum posts from people who have asked the same questions you'll inevitably ask a thousand times over.
  • The Unity YouTube channel The official YouTube channel for Unity. This channel contains many tutorials on the various system within Unity that will help both novies and professionals alike. Make use of it.
  • The official Unity Online Documentation. This archive will more often then not be one of the first hits you get back a when searching for either unknown terms or definitions of the properties and functions within Unity. Keep in mind you can click on most of the keywords in the site to go to another page with more detailed information on that link you followed.

Below is a typical veiw of the Unity interface. We'll reference parts of the interface in all of the sections below. For now take note of the general areas by tab name: the Hierarchy tab, the Scene tab, the Project tab (with the Asset Library), and the Inspector.

Original objects, Prefabs, and Instances

In Unity it's very important to realize what state an object within the scene is in. Many new developers will create an object for thier game, drop it into the scene, change it in some way, and then wonder why those changes are not being applied to further copies of that object created within the scene.

You can divide all (placeable) objects in Unity into 3 basic categories. The source asset of the object, the prefab based on the source asset, and the instances of that prefab.

Let's try to summarize the qualities of each form that an asset can exist in.

Source Assets

  • ...are found in the Asset Library.
  • ...are not placed directly into the game scene.
  • ...are the basis of Prefabs (which can be placed into the game scene) and can be seen by "extending" the prefab (using the arrow icon seen on the right side of the prefab icon in the library).

Prefabs...

  • ...are found in the Asset Library.
  • ...is the source of each instance of that object within the scene.
  • ...can have their properties changed in the inspector window (which will change all instances that stem from that prefab).

Instances...

  • ...are shown in the scene window and listed in the hierarchy window.
  • ...is the source of each instance of that object within the scene.
  • ...are shown as blue in the Hierarchy window (as opposed to white "unique" objects).

Essentially it's important to realize that instances used within your scene, if changed, will have thier own settings different then the prefab they are based on.

It can be somewhat confusing at first, but just remember to look at the actual words that make up properties in the inspector, should you want to see which properties have been changed. Property names in instances that have become bolded are properties that have been changed for that specific instance. This means that if you go back and change that same property in the original prefab then that instance will retain that particular property.

Let's look at that in order.

  • You create a new object in the Asset Library. Either by dragging in an actual art asset or by dragging a primitive object in from the hierarchy for practice.
  • You drag the object from the Asset Library onto the scene to create two instances of that prefab.
  • You select one of the instances by clicking on it within the scene window .
  • Change a property, such as rotation or scale, of that instance. So one instance in the scene remains unchanged while the other is different in an obvious way.
  • Click on the original prefab listed in the Asset Library.
  • Change the same property in the inspector while the prefab is selected any way you like.

What you should see is that the change you just made to the prefab will appear on the instance that you didn't change while the one you did will retain the modification you made while that instance was selected.

If you want to revert the change you made to an individual instance in the scene so that it uses the property of the prefab that it is based on then the change is simple enough. Select the instance from within the scene view (or the hierarchy window) and locate the property you want to revert in the inspector. Simply Right-Click on the property name in the inspector, then select "Revert Value to Prefab".

At that point both of the instances in your scene should match the settings on the prefab in the Asset Library.

Dragging and Dropping, and you

The design of Unity 3D relies heavily on the relationships between the origin of an object and its current position in the program. When creating a new object in one area of the program the nature of how it can further be changed, copied, and even deleted, is dependent on whether or not it is the first object brought in or a new object derived from that imported object.

The easiest way to dictate the state of an object as either an original asset, a prefab, or an instance, is to keep in mind the rules that are applied when dragging and dropping an object to create a new one.

The table below goes over the various actions and what they do.

Drag from: Drop to: Effect
Desktop / file browser Asset Library Create a new library asset (and copy that file to Unity's "Asset" folder.
Heirarchy window Asset Library Create a new "Prefab" object based on the in-scene object (and saving its components properites in the process).
Asset Library Scene window Place a new instance of a Library object within the game scene.
Asset Library Inspector If a valid component (such as a script), adds that componnet to currently selected object.

Notes for programmers

If you have any prior experience with either C# or JavaScript then Unity 3D will be easy to acclimate to.

Unique qualities found in scripts for Unity3D are mostly going to manifest themselves in the default classes and connections. Just think of it as a library that's always there - that you don't need to define a header for (although it's c#, so you wouldn't be defining headers anyway).

Default "virtual" functions

Probably the main thing to keep in mind is the presence of default functions within each script already defined in the "UnityEngine" space you'll be referencing at the start of each script anyway. Each class that extends the base "MonoBehaviour " class comes with some virtual functions that can either be used simply by invoking their name or completely ignored. In this case you do NOT need to use keywords such as "override" to make use of these inherent functions.

These include more obvious functions such as "Start()" and "Update()", both of which are included by Unity itself when you make a new script from within the editor, but also quiet a few less often used methods.

The entire list can be found at the following address, under the "Messages" section.

Unity MonoBehaviour documentation

So here's an example of one in use...



// Every script made from within unity will include two
// default "using" lines.

using UnityEngine;
using System.Collections;

// As in any C# document inheritence is defined via a ":".
// In this case "MonoBehaviour" is what all Unity objects
// descend from.

public class ExampleClass : MonoBehaviour {
	
	void Start() {
		// You can use "start" to initialize some properties or
		// simply leave it blank.  It will be run once when the
		// object the script component is applied to is added
		// to the scene.
	}
	
	// Here is the one of the possible "virtual" collision check
	// methods.  This function has one default parameter
	// that can be used to gather all collision information
	// in the current tick, for any collisions that happened
	// during that tick.
	
    void OnCollisionEnter(Collision collision) {
	
		// Here we access properties specific to Unity, and
		// specific to the collision object's current state.
		
		// For instance we can check for individual
		// collision points or we can check for the "strength"
		// of the collision.
		
        foreach (ContactPoint contact in collision.contacts) {
             // Perform code to react to the found collision
        }        
        if (collision.relativeVelocity.magnitude > 2){
            // Perform code to react to the found collision
		}
		
    }
	
	// After this collision funciton is called for each object
	// in the scene Unity will go on to the next event in
	// the internal event list such as rendering.  If no
	// rendering functions have been added here then
	// this component will simply not be included in the
	// pass for that event system.
	
}

Miscellaneous Notes and Common Questions

Here are some extra tidbits that new users might not be expecting, but which should be kept in mind, because many people have found themselves losing work by not knowing about them.

When you either import or drag an drop an asset file into the Asset Library Unity3D will *COPY* the file to it's own directory.

This is a fairly simple one but can trip you up easily on those nights wheny you're up late and just "trying to get that last object finished". This is quite an easy mistake to make precisely because most Unity developers probably won't be keeping the same project files for their assets, while they are making that asset, in the same asset folder within the Unity project.

Imagine you are making a simple 3D object to sit in the background of your game. You probably have a folder that contains all of the source elements of that object. There will be the actual 3D project file (for instance a ".max" file if you are using 3D Studio Max), the textures associated with that file, such as color and normal maps, and possibly separate animation files to make that object move it needed. You may even be keeping reference photos to items you are recreating, notes from supervisors or art directors, or different versions of the same file with slight alterations to each one so you can see which one you like the most.

Since Unity does not need the extra files, and has a habit of importing into the Asset Library everything that is in the asset folder, you probably don't want to save and work directly from the asset folder. In fact in large projects comprising multiple people this can be a bad idea.

And so you keep your source files for your model in a different folder entirely and only the required files (the model and texture files) to the Unity asset folder.

What some new users forget is that, if you continue to work on your object, you might be saving to your source file and forget to copy it again after any given change (and then wonder why the model is not updatying in Unity).

Alternately, and worse, you might be tempted to save the file you're working on directly to the asset folder. In this case you now have the most up to date version within the asset folder and accidentally revert to a previous version when you later open the file from the your source project folder. It might also be that others working on the project might think that it's ok to delete files from the Unity asset folder because they think the originals are safely in the artist's source folder.

Either way it's important to; 1. Know where the most recent version of your assets resides on your computer, 2. Make sure all memebers of a team follow the same workflow pipeline, and 3. Keep whatever workflow you use constant and try not to deviate from that habit.

Changes made in "Play" mode are not retained when play is stopped.

At the top of the screen you'll always see the play, pause, and stop buttons. When you press "play" you'll run your game, typically for testing purposes, as if it were the final version. You'll find that you can make changes to the scene and individual object in the scene while in play mode. This is tempting because you can see changes immediately, while the scene is in-game, and how those changes affect the game.

The problem is that any of the changes you make will not be saved and will revert to their previous values upon exit of play mode. This is on purpose as the play mode within Unity is there precisely for the sake of testing. If you like a change you make while in play mode there is something you can do to save changes to a specific component within a specific object.

  1. While in play mode select the object from the hierarchy list that you have changed a property of if it is not already selected.
  2. Find the component in that object that you have modified and click the small "gear" icon that you'll always see in the upper right corner of a component to an extra options menu for that component.
  3. Select "Copy Component".
  4. Exit play mode.
  5. If not still selected find and select the same object again and then click the same "gear" settings option icon you clicked while in play mode.
  6. This time select "Paste Component Values".

The component should now have taken on the same property values that it had while in play mode.

It's possible to align the camera and objects to one another.

It's possible to move and align the game camera (or any object) to your current user viewpoint within the editor window so that you'll see the same view from the game camera as you do in the editor when the game is tested via the play button (or in the "game" view tab).

To align the game camera to your editor camera select the camera object you want to move from within the hierarchy or scene view and then choose "GameObject > Align With View" from the drop down menu.

You'll notice there are other options within the same area. These can be used to do the opposite, to align the editor view to a selected camera, or to move the editor camera closer to an object you might find in the heirarch that has been lost in the scene view.

Here are a few smaller notes about questions that seem to come up with every new project and that it would be helpful to have a little reminder of.

Interface Notes

  • If camera / light icons are cluttering the screen shrink them under the "gizmo" menu at the top of the viewport.
  • Screen Space Ambient Occlusion, Depth of Field, and Color Correction are scripts not found on the default scene camera but which you can add to any camera object. You first have to add the "Effects" assets from the standard library and then apply the script object itself as a component.
  • Lighting Notes

  • Decide upon either ambient lighting or pre-built lighting early in your development. This single choice will dictate many of the qualities of how your scenes are built. Both are found in the lighting menu...
    Window > Lighting
    Just remebmer in pre-built lighting (with Deferred rendering) dynamic objects will not cast shadows.
  • If you are going to use baked lighting then objects / prefabs that will have baked lightmaps need to be set to "Static" (found in the object inspector far upper right corner).
  • If you are unable to use real time shadows change rendering from "forward" to "Deferred" via Edit > Project Settings > Player > Render Path.
  • If you want to expand the shadow distance...
    Edit > Project Settings > Quality > Shadow Distance

Pixel Art in Unity?

After spending an afternoon trying to figure out simple blitting in Unity 4.x I've come to the conclusion that you just can't do it. At least, it's not suited for simple pixel art games. To this author a requirement of blitting pixel art graphics is using rectangles of exact sizes.

The problem is that the only available DrawTexture functions in Unity are executed using texture space coordinates (0-1 floats) instead of finite pixel measurements. Using low resolution textures in such a system will make it impossible to have the pixels of various objects and background imagery align with each on the same pixel grid as they should.

I did not attempt to modify the renderer in any way. If you have skill in coding custom renderers or shader code you may have better luck.

Audio Compression Settings

This article, kindly entitled "Wrong Import Settings are Killing Your Unity Game", has a good summarization of what the main compression settings are and what effect they have on the speed of your game.

The most important passage is the following...

Let’s get this straight. Each Load Type and Compression Format combination can be used and you’re the one who knows best which one should be chosen. There are three Load Types:

  • Compressed In Memory – Audio Clip will be stored in RAM and will be uncompressed when played. Does not require additional memory for playing.
  • Streaming – Audio Clip will be stored on a device persistent memory (hard drive, flash drive etc) and streamed when played. Does not require RAM for storing and playing (at least this value is not significant).
  • Decompress On Load – Audio Clip will be stored in RAM uncompressed. This option requires the most memory but playing it won’t require so much CPU power as the rest.