Variables and Components - Digital Prototyping - Introduction to Game Design, Prototyping, and Development (2015)

Introduction to Game Design, Prototyping, and Development (2015)

Part II: Digital Prototyping

Chapter 19. Variables and Components

This chapter introduces you to the many variable and component types used throughout Unity C# programming. By the end of the chapter, you will understand many of the common types of C# variables and some important variable types that are unique to Unity.

This chapter also introduces you to Unity’s GameObjects and components. Any object in a Unity scene is a GameObject, and the components that comprise them enable everything from the positioning of a GameObject to physics simulation, special effects, displaying a 3D model on screen, and character animation.

Introducing Variables

To recap a bit of Chapter 17, “Introducing our Language: C#,” a variable is just a name that can be defined to be equal to a specific value. This is actually a concept that comes from the study of algebra. In algebra, for instance, you can be given the definition:

x = 5

This defines the variable x to be equal to the value 5. In other words, it assigns the value 5 to the name x. Then, if later, you encounter the definition:

y = x + 2

Then you now know that the value of the variable y is 7 (because x = 5 and 5 + 2 = 7). x and y are called variables because their value can be redefined at any time; however, the order in which these definitions occur does matter. Take a look at these definitions. (Comments are included after two slashes [//] in the following code listing to help explain what the code is doing.)

x = 10 // x is now equal to the value 10
y = x - 4 // y is now 6 because 10-4 = 6
x = 12 // x is now equal to the value 12, but y is still 6
z = x + 3 // z is now 15 because 12+3 = 15

After this sequence of definitions, the values assigned to x, y, and z are 12, 6, and 15, respectively. As you can see, even though x changed value, y was not affected because y is defined as the value 6 before x is assigned the new value 12, and y is not retroactively affected.

Strongly Typed Variables in C#

Instead of being able to be assigned any kind of value, C# variables are strongly typed, meaning that they can only accept a specific type of value. This is necessary because the computer needs to know how much space in memory to allocate to each variable. A large image can take up many megabytes or even gigabytes of space, while a Boolean value (which can only hold either a 1 or a 0) only really requires a single bit. Even just a single megabyte is equivalent to 8,388,608 bits!

Declaring and Defining Variables in C#

In C#, a variable must be both declared and defined for it to have a usable value.

Declaring a variable creates it and gives it a name and type. However, this does not give the variable a value.

bool bravo;
int india;
float foxtrot;
char charlie;

Defining a variable gives that variable a value. Here are some examples using the declared variables:

bravo = true;
india = 8;
foxtrot = 3.14f; // The f makes foxtrot a float, as described later
charlie = 'c';

Literals

Whenever you write a specific value in your code (e.g., true, 8, or ’c’), that specific value is called a literal. In the previous code listing, true is a bool literal, 8 is an int literal, 3.14f is a float literal, and ’c’ is a char literal. By default, MonoDevelop shows these literals in a bright magenta color, and each variable type has certain rules about how its literals are represented. Check out each of the variable types in the following sections for more information on this.

Declaration Before Definition

You must first declare a variable before you can define it, although this is often done on the same line:

string sierra = "Mountain";

In general, Unity will complain and throw a compiler error if you try to access (i.e., read) a variable that has been declared but has not yet been defined.

Important C# Variable Types

Several different types of variables are available to you in C#. Here are a few important ones that you’ll encounter frequently. All of these basic C# variable types begin with a lowercase letter, whereas most Unity data types begin with an uppercase letter. For each, I’ve listed information about the variable type and an example of how to declare and define the variable.

bool: A 1-Bit True or False Value

The term bool is short for Boolean. At their heart, all variables are composed of bits that can either be set to true or false. A bool is 1 bit in length, making it the smallest possible variable.1 Bools are extremely useful for logic operations like if statements and other conditionals, which are covered in the next two chapters. In C#, bool literals are limited to the lowercase keywords true and false:

bool verified = true;

1 Though a bool only requires a single bit of memory for storage, C# actually uses at least 1 byte (which is 8 bits) to store each bool. On a 32-bit system, the smallest possible memory chunk is 32 bits, and on a 64-bit system, it’s 64 bits or 8 bytes.

int: A 32-Bit Integer

Short for integer, an int can store a single integer number (integers are numbers without any fractional value like 5, 2, & -90). Integer math is very accurate and very fast. An int in Unity can store a number between -2,147,483,648 and 2,147,483,647 with 1 bit used for the positive or negative sign of the number and 31 bits used for the numerical value. An int can hold any integer value between these two numbers (inclusive):

int nonFractionalNumber = 12345;

float: A 32-bit Decimal Number

A floating-point number,2 or float, is the most common form of decimal number used in Unity. It is called “floating point” because it is stored using a system similar to scientific notation. Scientific notation is the representation of numbers in the form a•10b (for example, 300 would be written 3•102, and 12,345 would be written 1.2345•104). Floating point numbers are stored in a similar format with a•2b. When storing numbers this way in memory, 1 bit represents whether the number is positive or negative, 23 bits are allocated to the significand (the number itself and the a part above), and 8 are allocated to exponent to which the number is raised or lowered (the b part). This means that there will be significant gaps in the precision of very large numbers and any number between 1 and -1. For instance, there is no way to accurately represent 1/3 using a float.

2 http://en.wikipedia.org/wiki/Floating_point

Most of the time, the imprecise nature of floats doesn’t matter much in your games, but it can cause small errors in things like collision detection; so in general, keeping elements in your game larger than 1 unit and smaller than several thousand units in size will make collisions a little more accurate. Float literals must be either a whole number or a decimal number followed by an f. This is because C# assumes that any decimal literal without a trailing f is a double (which is a float with double the precision) instead of the single-precision floats that Unity uses. Floats are used in all built-in Unity functions instead of doubles to bring about the fastest possible calculation, though this comes at the expense of accuracy:

float notPreciselyOneThird = 1.0f/3.0f;


Tip

If you see the following compile-time error in your code

error CS0664: Literal of type double cannot be implicitly converted to
type 'float'. Add suffix 'f' to create a literal of this type

it means that somewhere you have forgotten to add the f after a float literal.


char: A 16-Bit Single Character

A char is a single character represented by 16 bits of information. Chars use Unicode3 values for storing characters, enabling the representation of over 110,000 different characters from over 100 different character sets and languages (including, for instance, all the characters in Simplified Chinese). A char literal is surrounded by single-quote marks (a.k.a. apostrophes):

3 http://en.wikipedia.org/wiki/Unicode

char theLetterA = 'A';

string: A Series of 16-Bit Characters

A string is used to represent everything from a single character to the text of an entire book. The theoretical maximum length of a string in C# is over 2 billion characters, but most computers will encounter memory allocation issues long before that limit is reached. To give some context, there are a little over 175,000 characters in the full version of Shakespeare’s play Hamlet,4 including stage directions, line breaks, and so on. This means that Hamlet could be repeated over 12,000 times in a single string. A string literal is surrounded by double-quote marks:

4 http://shakespeare.mit.edu/hamlet/full.html

string theFirstLineOfHamlet = "Who's there?";

It’s also possible to access the individual chars of a string using bracket access:

char theCharW = theFirstLineOfHamlet[0]; // W is the 0th char in the string
char theChart = theFirstLineOfHamlet[6]; // t is the 6th char in the string

Placing a number in brackets after the variable name retrieves the character in that position from the string (without affecting the original string). When using bracket access, counting starts with the number 0; so in the preceding code, W is the 0th (pronounced “zeroth”) character of the first line of “Hamlet,” and t is the 6th character. You will encounter bracket access much more in Chapter 22, “Lists and Arrays.”


Tip

If you see any of the following compile-time errors in your code

error CS0029: Cannot implicitly convert type 'string' to 'char'
error CS0029: Cannot implicitly convert type 'char' to 'string'
error CS1012: Too many characters in character literal
error CS1525: Unexpected symbol '<internal>'

it usually means that somewhere you have accidentally used double quotes (" ") for a char literal or single quotes (’ ’) for a string literal. String literals always require double quotes, and char literals always require single quotes.


class: The Definition of a New Variable Type

A class defines a new type of variable that can be best thought of as a collection of both variables and functionality. All the Unity variable types and components listed in the “Important Unity Variable Types” section of this chapter are examples of classes. Chapter 25, “Classes,” covers classes in greater detail.

The Scope of Variables

In addition to variable type, another important concept for variables is scope. The scope of a variable refers to the range of code in which the variable exists and is understood. If you declare a variable in one part of your code, it might not have meaning in another part. This is a complex issue that will be covered throughout this book. If you want to learn about it progressively, just read the book in order. If you want to get a lot more information about variable scope right now, you can read the section “Variable Scope” in Appendix B, “Useful Concepts.”

Naming Conventions

The code in this book follows a number of rules governing the naming of variables, functions, classes, and so on. Although none of these rules are mandatory, following them will make your code more readable not only to others who try to decipher it but also to yourself if you ever need to return to it months later and hope to understand what you wrote. Every coder follows slightly different rules—my personal rules have even changed over the years—but the rules I present here have worked well for both me and my students, and they are consistent with most C# code that I’ve encountered in Unity:

1. Use camelCase for pretty much everything (see the camelCase sidebar).


CamelCase

camelCase is a common way of writing variable names in programming. It allows the programmer or someone reading her code to easily parse long variable names. Here are some examples:

Image aVariableNameStartingWithALowerCaseLetter

Image AClassNameStartingWithACapitalLetter

Image aRealLongNameThatIsEasierToReadBecauseOfCamelCase

The key feature of camelCase is that it allows multiple words to be combined into one with a medial capital letter at the beginning of each original word. It is named camelCase because it looks a bit like the humps on a camel’s back.


2. Variable names should start with a lowercase letter (e.g., someVariableName).

3. Function names should start with an uppercase letter (e.g., Start(), Update()).

4. Class names should start with an uppercase letter (e.g., GameObject, ScopeExample).

5. Private variable names can start with an underscore (e.g., _hiddenVariable).

6. Static variable names can be all caps with snake_case (e.g., NUM_INSTANCES). As you can see, snake_case combines multiple words with an underscore in between them.

For your later reference, this information is repeated in the “Naming Conventions” section of Appendix B.


Class Instances and Static Functions

Just like the prefabs that you saw in Chapter 18, “Hello World: Your First Program,” classes can also have instances. An instance of any class (also known as a member of the class) is a data object that is of the type defined by the class.

For example, you could define a class Human, and everyone you know would be an instance of that class. Several functions are shared by all humans (for example, Eat(), Sleep(), Breathe()).

Just as you differ from all other humans around you, each instance of a class differs from the other instances. Even if two instances have perfectly identical values, they are stored in different locations in computer memory and seen as two distinct objects. (To continue the human analogy, you could think of them as identical twins.) Class instances are referred to by reference, not value. This means that if you are comparing two class instances to see whether they are the same, the thing that is compared is their location in memory, not their values (just as two identical twins have different names).

It is, of course, possible to reference the same class instance using different variables. Just as the person I might call “daughter” would also be called “granddaughter” by my parents, a class instance can be assigned to any number of variable names yet still be the same data object, as is shown in the following code:

1 using UnityEngine;
2 using System.Collections;
3
4 // Defining the class Human
5 public class Human {
6 public string name;
7 public Human partner;
8 }
9
10 public class Family : MonoBehaviour {
11 // public variable declaration
12 public Human husband;
13 public Human wife;
14
15 void Start() {
16 // Initial state
17 husband = new Human();
18 husband.name = "Jeremy Gibson";
19 wife = new Human();
20 wife.name = "Melanie Schuessler";
21
22 // My wife and I get married
23 husband.partner = wife;
24 wife.partner = husband;
25
26 // We change our names
27 husband.name = "Jeremy Gibson Bond";
28 wife.name = "Melanie Schuessler Bond";
29
30 // Because wife.partner refers to the same instance as husband,
31 // the name of wife.partner has also changed
32 print(wife.partner.name);
33 // prints "Jeremy Gibson Bond"
34 }
35 }

It is also possible to create static functions on the class Human that are able to act on one or more instances of the class. The following static function Marry() allows you to set two humans to be each other’s partner with a single function.

35 // This replaces line 35 from the previous code listing
36
37 static public void Marry(Human h0, Human h1) {
38 h0.partner = h1;
39 h1.partner = h0;
40 }
41 }

With this function, it would now be possible to replace lines 23 and 24 from the initial code listing with the single line Human.Marry( wife, husband );. Because Marry() is a static function, it can be used almost anywhere in your code. You will learn more about static functions and variables later in the book.


Important Unity Variable Types

Unity has a number of variable types that you will encounter in nearly every project. All of these variable types are examples of classes and follow Unity’s naming convention that all class types start with an uppercase letter. For each of the Unity variable types, you will see information about how to create a new instance of that class (see the sidebar on class instances) followed by listings of important variables and functions for that data type. For most of the Unity classes listed in this section, the variables and functions are split into two groups:

Image Instance variables and functions: These variables and functions are tied directly to a single instance of the variable type. If you look at the Vector3 information that follows, you will see that x, y, z, and magnitude are all instance variables of Vector3, and each one is accessed viadot syntax, which is the name of a Vector3 variable, a period, and then the name of the instance variable (for example, position.x). Each Vector3 instance can have different values for these variables. Similarly, the Normalize() function acts on a single instance of Vector3 and sets the magnitude of that instance to 1.

Image Static class variables and functions: Static variables are tied to the class definition itself rather than being tied to an individual instance. These are often used to store information that is the same across all instances of the class (for example, Color.red is always the same red color) or to act on multiple instances of the class without affecting either (for example, Vector3.Cross( v3a, v3b ) is used to calculate the cross product of two Vector3s and return that value as a new Vector3 without changing either v3a or v3b).

For more information on any of these Unity types, check out the Unity documentation links referenced in the footnotes.

Vector3: A Collection of Three Floats

Vector35 is a very common data type for working in 3D. It is used most commonly to store the three-dimensional position of objects in Unity. Follow the footnote for more detailed information about Vector3s.

5 http://docs.unity3d.com/Documentation/ScriptReference/Vector3.html

Vector3 position = new Vector3( 0.0f, 3.0f, 4.0f ); // Sets the x, y, & z values

Vector3 Instance Variables and Functions

As a class, each Vector3 instance also contains a number of useful built-in values and functions:

print( position.x ); // 0.0, The x value of the Vector3
print( position.y ); // 3.0, The y value of the Vector3
print( position.z ); // 4.0, The z value of the Vector3
print( position.magnitude ); // 5.0, The distance of the Vector3 from 0,0,0
// Magnitude is another word for "length".
position.Normalize(); // Sets the magnitude of position to 1, meaning that the
// x, y, & z values of position are now [0.0, 0.6, 0.8]

Vector3 Static Class Variables and Functions

In addition, several static class variables and functions are associated with the Vector3 class itself:

print( Vector3.zero ); // (0,0,0), Shorthand for: new Vector3( 0, 0, 0 )
print( Vector3.one ); // (1,1,1), Shorthand for: new Vector3( 1, 1, 1 )
print( Vector3.right ); // (1,0,0), Shorthand for: new Vector3( 1, 0, 0 )
print( Vector3.up ); // (0,1,0), Shorthand for: new Vector3( 0, 1, 0 )
print( Vector3.forward ); // (0,0,1), Shorthand for: new Vector3( 0, 0, 1 )
Vector3.Cross( v3a, v3b );// Computes the cross product of the two Vector3s
Vector3.Dot( v3a, v3b ); // Computes the dot product of the two Vector3s

This is only a sampling of the fields and methods affiliated with Vector3. To find out more, check out the Unity documentation referenced in the footnote.

Color: A Color with Transparency Information

The Color6 variable type can store information about a color and its transparency (alpha value). Colors on computers are mixtures of the three primary colors of light: red, green, and blue. These are different from the primary colors of paint you may have learned as a child (red, yellow, and blue) because color on a computer screen is additive, rather than subtractive. In a subtractive color system like paint, mixing more and more different colors together will move the mixed color toward black (or a really dark, muddy brown). By contrast, in an additive color system (like a computer screen, theatrical lighting design, or HTML colors on the Internet), adding more and more colors together will get brighter and brighter until the final mixed color is eventually white. The red, green, and blue components of a color in C# are stored as floats that range from 0.0f to1.0f with 0.0f representing none of that color channel and 1.0f representing as much of that color channel as possible:7

6 http://docs.unity3d.com/Documentation/ScriptReference/Color.html

7 In the Unity color picker, the four channels of a color are defined as whole numbers between 0 and 255. These numbers match the possible color values of HTML but are automatically converted to a float from 0-1 in Unity.

// Colors are defined by floats for the Red, Green, Blue, Alpha channels
Color darkGreen = new Color( 0f, 0.25f, 0f); // If no alpha info is passed in,
// the alpha value is assumed to
// be 1 (fully opaque)
Color darkRedTransparent = new Color( 0.25f, 0f, 0f, 0.5f );

As you can see, there are two different ways to define a color, one with three parameters (red, green, and blue) and one with four parameters (red, green, blue, and alpha).8 The alpha value sets the transparency of the color. A color with an alpha of 0.0f is fully transparent, and a color with an alpha of 1.0f is fully opaque.

8 The ability of the new Color() function to take different numbers of variables is called function overloading, and you can read more about it in Chapter 23, “Functions and Parameters.”

Color Instance Variables and Functions

Each channel of a color can be referenced through instance variables:

print( Color.yellow.r ); // 1, The red value of the Color
print( Color.yellow.g ); // 0.92f, The green value of the Color
print( Color.yellow.b ); // 0.016f, The blue value of the Color
print( Color.yellow.a ); // 1, The alpha value of the Color

Color Static Class Variables and Functions

Several common colors are predefined in Unity as static class variables:

// Primary Colors: Red, Green, and Blue
Color.red = new Color(1, 0, 0, 1); // Solid red
Color.green = new Color(0, 1, 0, 1); // Solid green
Color.blue = new Color(0, 0, 1, 1); // Solid blue

// Secondary Colors: Cyan, Magenta, and Yellow
Color.cyan = new Color(0, 1, 1, 1); // Cyan, a bright greenish blue
Color.magenta = new Color(1, 0, 1, 1); // Magenta, a pinkish purple
Color.yellow = new Color(1, 0.92f, 0.016f, 1); // A nice-looking yellow
// As you can imagine, a standard yellow would be new Color(1,1,0,1),
// but in Unity's opinion, this yellow looks better.

// Black, White, and Clear
Color.black = new Color(0, 0, 0, 1); // Solid black
Color.white = new Color(1, 1, 1, 1); // Solid white
Color.gray = new Color(0.5f, 0.5f, 0.5f, 1) // Gray
Color.grey = new Color(0.5f, 0.5f, 0.5f, 1) // British spelling of gray
Color.clear = new Color(0, 0, 0, 0); // Completely transparent

Quaternion: Rotation Information

Explaining the inner workings of the Quaternion9 class is far beyond the scope of this book, but you will be using them often to set and adjust the rotation of objects through the quaternion GameObject.transform.rotation, which is part of every GameObject. Quaternions define rotations in a way that avoids gimbal lock, a problem with standard x, y, z (or Euler, pronounced “oiler”) rotations where one axis can align with another and limit rotation possibilities. Most of the time, you will be defining a quaternion by passing in Euler rotations and allowing Unity to convert them into the equivalent quaternion:

9 http://docs.unity3d.com/Documentation/ScriptReference/Quaternion.html

Quaternion lookUp45Deg = Quaternion.Euler( -45f, 0f, 0f );

In cases like this, the three floats passed into Quaternion.Euler() are the number of degrees to rotate around the x, y, and z axes (respectively colored red, green, and blue in Unity). GameObjects, including the Main Camera in a scene, are initially oriented to be looking down the positive z-axis. The rotation in the preceding code would rotate the camera -45 degrees around the red x-axis, causing it to then be looking up at a 45° angle relative to the positive z-axis. If that last sentence was confusing, don’t worry about it too much right now. Later, you can try going into Unity and changing the x, y, and z rotation values in the Transform Inspector for a GameObject and see how it alters the object’s orientation.

Quaternion Instance Variables and Functions

You can also use the instance variable eulerAngles to cause a quaternion to return its rotation information to you in Euler angles:

print( lookUp45Deg.eulerAngles ); // ( -45, 0, 0 ), the Euler rotation

Mathf: A Library of Mathematical Functions

Mathf10 isn’t really a variable type as much as it’s a fantastically useful library of math functions. All of the variables and functions attached to Mathf are static; you cannot create an instance of Mathf. There are far too many useful functions in the Mathf library to list here, but a few include the following:

10 http://docs.unity3d.com/Documentation/ScriptReference/Mathf.html

Mathf.Sin(x); // Computes the sine of x
Mathf.Cos(x); // .Tan(), .Asin(), .Acos(), & .Atan() are also available
Mathf.Atan2( y, x ); // Gives you the angle to rotate around the z-axis to
change something facing along the x-axis to face
instead toward the point x, y.11
print(Mathf.PI); // 3.141593; the ratio of circumference to diameter
Mathf.Min( 2, 3, 1 ); // 1, the smallest of the three numbers (float or int)
Mathf.Max( 2, 3, 1 ); // 3, the largest of the three numbers (float or int)
Mathf.Round( 1.75f ); // 2, rounds up or down to the nearest number
Mathf.Ceil( 1.75f ); // 2, rounds up to the next highest integer number
Mathf.Floor( 1.75f ); // 1, rounds down to the next lowest integer number
Mathf.Abs( -25 ); // 25, the absolute value of -25

11 http://docs.unity3d.com/Documentation/ScriptReference/Mathf.Atan2.html

Screen: Information about the Display

Screen12 is another library like Mathf that can give you information about the specific computer screen that your Unity game is using. This works regardless of device, so screen will give you accurate info whether you’re on a PC, OS X, an iOS device, or an Android tablet:

12 http://docs.unity3d.com/Documentation/ScriptReference/Screen.html

print( Screen.width ); // Prints the width of the screen in pixels
print( Screen.height ); // Prints the height of the screen in pixels
Screen.showCursor = false; // Hides the cursor

SystemInfo: Information about the Device

SystemInfo13 will tell you specific information about the device on which the game is running. It includes information about operating system, number of processors, graphics hardware, and more. I recommend following the link in the footnote to learn more:

13 http://docs.unity3d.com/Documentation/ScriptReference/SystemInfo.html

print( SystemInfo.operatingSystem ); // Mac OS X 10.8.5, for example

GameObject: The Type of Any Object in the Scene

GameObject14 is the base class for all entities in Unity scenes. Anything you see on screen in a Unity game is a subclass of the GameObject class. GameObjects can contain any number of different components, including all of those referenced in the next section: “Unity GameObject Components.” However, GameObjects also have a few important variables beyond what is covered there:

14 http://docs.unity3d.com/Documentation/ScriptReference/GameObject.html

GameObject gObj = new GameObject("MyGO"); // Creates a new GameObject named MyGO
print( gObj.name ); // MyGO, the name of the GameObject gObj
Transform trans = gObj.GetComponent<Transform>(); // Defines trans to be
a reference to the Transform
Component of gObj
Transform trans2 = gObj.transform; // A shortcut to access the same Transform
gObj.SetActive(false); // Makes gObj inactive, rendering it invisible
// and preventing it from running code.

The method15 gObj.GetComponent<Transform>() shown here is of particular importance because it can enable you to access any of the components attached to a GameObject. You will sometimes see methods with angle brackets <> like GetComponent<>(). These are calledgeneric methods because they are designed to be used on many different data types. In the case of GetComponent<Transform>(), the data type is Transform, which tells GetComponent<>() to find the Transform component of the GameObject and return it to you. This can also be used to get any other component of the GameObject by typing that component type inside the angle brackets instead of Transform. Examples include the following:

15 “Function” and “method” have the same basic meaning. The only difference is that “function” is used to describe a standalone function while “method” refers to a function that is part of a class.

Renderer rend = gObj.GetComponent<Renderer>(); // Gets the Renderer Component
Collider coll = gObj.GetComponent<Collider>(); // Gets the Collider Component
HelloWorld hwInstance = gObj.GetComponent<HelloWorld>();

As shown in the third line of the preceding code listing, GetComponent<>() can also be used to return the instance of any C# class that you’ve attached to the GameObject. If there were an instance of the HelloWorld C# script class attached to gObj, thengObj.Getcomponent<HelloWorld>() would return it. This technique is used several times throughout this book.

Unity GameObjects and Components

As mentioned in the previous section, all on-screen elements in Unity are GameObjects, and all GameObjects are composed of components. When you select a GameObject in either the Hierarchy pane or the Scene pane, the components of that GameObject are displayed in the Inspector pane, as shown in Figure 19.1.

image

Figure 19.1 The Inspector pane showing various important components.

Transform: Position, Rotation, and Scale

Transform16 is a mandatory component that is present on all GameObjects. Transform handles critical GameObject information like position (the location of the GameObject), rotation (the orientation of the GameObject), and scale (the size of the GameObject). Though the information is not displayed in the Inspector pane, Transform is also responsible for the parent/child relationships in the Hierarchy pane. When one object is the child of another, it moves with that parent object as if attached to it.

16 http://docs.unity3d.com/Documentation/Components/class-Transform.html

MeshFilter: The Model You See

A MeshFilter17 component attaches a 3D mesh in your Project pane to a GameObject. To see a model on screen, the GameObject must have both a MeshFilter that handles the actual 3D mesh information and a MeshRenderer that combines that mesh with a shader or material and displays the image on screen. The MeshFilter creates a skin or surface for a GameObject, and the MeshRenderer determines the shape, color, and texture of that surface.

17 http://docs.unity3d.com/Documentation/Components/class-MeshFilter.html

Renderer: Allows You to See the GameObject

A Renderer18 component—in most cases, a MeshRenderer—allows you to see the GameObject in the Scene and Game panes. The MeshRenderer requires a MeshFilter to provide 3D mesh data as well as at least one Material if you want it to look like anything other than an ugly magenta blob (Materials apply textures to objects). Renderers bring the MeshFilter, the Material(s), and lighting together to show the GameObject on screen.

18 http://docs.unity3d.com/Documentation/Components/class-MeshRenderer.html

Collider: The Physical Presence of the GameObject

A Collider19 enables a GameObject to have a physical presence in the game world and collide with other objects. There are four different kinds of Collider components in Unity:

19 http://docs.unity3d.com/Documentation/Components/comp-DynamicsGroup.html

Image Sphere Collider:20 The fastest collision shape. A ball or sphere.

20 http://docs.unity3d.com/Documentation/Components/class-SphereCollider.html

Image Capsule Collider:21 A pipe with spheres at each end. The second fastest type.

21 http://docs.unity3d.com/Documentation/Components/class-CapsuleCollider.html

Image Box Collider:22 A rectangular solid. Useful for crates, cars, torsos, and so on.

22 http://docs.unity3d.com/Documentation/Components/class-BoxCollider.html.

Image Mesh Collider:23 A collider formed from a 3D mesh. Although useful and accurate, they are much, much slower than any of the other three. Also, only Mesh Colliders with Convex set to true can collide with other Mesh Colliders.

23 http://docs.unity3d.com/Documentation/Components/class-MeshCollider.html

Physics and collision are handled in Unity via the NVIDIA PhysX engine. Although this does usually provide very fast and accurate collisions, be aware that all physics engines have limitations, and even PhysX will sometimes have issues with fast-moving objects or thin walls.

Colliders are covered in much more depth later in this book, and you can also learn more about them from the Unity documentation.

Rigidbody: The Physics Simulation

The Rigidbody24 component controls the physics simulation of your GameObject. The Rigidbody component simulates acceleration and velocity every FixedUpdate (generally every 50th of a second) to update the position and rotation of the Transform component over time. It also uses the Collider component to handle collisions with other GameObjects. The Rigidbody component can also model things like gravity, drag, and various forces like wind and explosions. Set isKinematic to true if you want to directly set the position of your GameObject without using the physics provided by Rigidbody.

24 http://docs.unity3d.com/Documentation/Components/class-Rigidbody.html

For the position of a Collider component to move with its GameObject, the GameObject must have a Rigidbody. Otherwise, as far as Unity’s PhysX physics simulation is concerned, the collider will not move. In other words, if a Rigidbody is not attached, the GameObject will appear to move across the screen, but in PhysX, the location of the Collider component will not be updated and will therefore remain in the same location.

Script: The C# Scripts That You Write

All C# scripts are also GameObject components. One of the benefits of scripts being components is that you can attach more than one script to each GameObject, a capability that we will take advantage of in some of the tutorials in Part III of this book. Later in the book, you will read much more about Script components and how to access them.


Warning

Variable Names Will Chage in the Inspector In Figure 19.1, you can see that the name of the script is Scope Example (Script), but that breaks the naming rules for classes, because class names cannot have spaces in them.

The actual script name in my code is a single word in camelCase: ScopeExample. I’m not sure why exactly, but in the Inspector, the spelling of class and variable names is changed from their actual spelling in the C# scripts you write by the following rules:

Image The class name ScopeExample becomes Scope Example (Script).

Image The variable trueOrFalse becomes True Or False.

Image The variable graduationAge becomes Graduation Age.

Image The variable goldenRatio becomes Golden Ratio.

This is an important distinction, and it has confused some of my students in the past. Even though the names appear differently in the Inspector, the variable names in your code have not been changed.


Summary

This was a long chapter with a lot of information in it, and you may need to read it again or refer back to it later once you’ve had some more experience with code. However, all of this information will prove invaluable to you as you continue through this book and as you start writing your own code. Once you understand the GameObject/Component structure of Unity and how to take advantage of the Unity Inspector to set and modify variables, you’ll find that your Unity coding moves a lot faster and more smoothly.