CTIN 483

Week 2 Tuesday

Drawing

Today

  • Why are we here

  • Vectors

  • Simple movement

  • Homework and builds

  • Components and references

  • State

  • Demo writeup homework (W3)

Why are we here

Fluency

  • You don't need to be good at code or enjoy programming
     
  • But you can!
     
  • Still...

Humility

  • There will always be things you don't know, about code or about Unity
     
  • Learn to enjoy not knowing what you're doing
     
  • This has a lot of benefits for the creative process

Goals

Here is one idea of what skills you'd need to express a range of ideas (co-written with Richard and Peter):
 

Things to know for CTIN 532

Goals

Strongly recommend this book once you have a little Unity knowledge.

 

Third edition coming soon

 

2e also available via the USC Library

along with thousands of other technical books

A Dark Room

(DoubleSpeak Games, 2014)

 

Minimalist text adventure.

Content warning: gore.

Simple Game

Vectors

all you need to know

(almost)

Vectors

A vector is a mathematical object that is the basis of how games represent space. In math, a vector is an arrow.

A math vector has two basic parts:

  • a direction (which way it is pointing)
  • a magnitude (length)

magnitude

Magnitude is just a number.

Direction is represented with several numbers:

  • x and y for 2D vectors
  • x, y and z for 3D vectors

So you can use a Unity Vector to represent a math vector: an arrow pointing off into space.

 

But Unity also uses Vectors for other things, like position and scale, for math reasons. It's better to think of a Unity Vector as just a package of three numbers.

 

Some visuals will make this clearer.

This dot represents a position.

It can be described with two numbers, x and y.

A different point.

An arrow from (0,0) to a point is a vector.

If you want to represent moving from one position to another, it might look like this.

What is the result?

These are two vectors.

What does it mean to add them?

Visually, put the beginning of one at the end of the other. Mathematically, just add the numbers.

It works in the other order too.

What does it mean to subtract two vectors?

To subtract something is to add its opposite.

The opposite of a vector points the opposite direction.

The math works the way you'd expect: subtract x from x and y from y.

What about multiplying by one number?

What about multiplying by a negative number?

The opposite of a vector points the opposite direction.

These are useful shortcuts in code.

Each one is one unit long so you can multiply it by whatever you want.

How about multiplying a vector by another vector?

What would this mean, visually?

This doesn't seem to mean anything.

There are two ways to multiply vectors. But you don't need to know either one in order to get started making games.

Stretch

Builds

A build is a program, a standalone version of your game.

 

So your player doesn't need to open your project in Unity — they can just double-click on your program to run the game.

 

You may also encounter the terms application or executable. It all means the same thing.

You can't run a Windows application on OS X, or a PlayStation game on an iPhone. Each requires its own special format.

 

The operating system your player is using is referred to as a platform or (in Unity) a build target. Some examples are:

  • PS5
  • Windows 10
  • Oculus Quest 2
  • Android 11

For the homework you will only make Windows builds.

 

On Windows a build consists of a file called YourGameName.exe and several folders.

 

They are all necessary to run your game, so you need to zip the folder that contains the exe and folders, and turn that in.

If you ever realize you want to make games for a new platform (for example iOS), you don't have to reinstall Unity.

 

Instead, you can add a new build target using Unity Hub.

  1. Look under Installs on the left.
  2. Choose your version.
  3. Click on the gear icon.
  4. Choose Add Modules. This will show you a list of build targets.
  5. Check the one you want and click Install.

 

Review: Components

GetComponent

GetComponent is an important and powerful bit of code, because it lets you talk to any of the components you can see in the Inspector (including other scripts).

So it is worth all the punctuation!

myLight = gameObject.GetComponent<Light> ();

GetComponent is how you can talk to other components from a script. For example, here's how you can get a reference to a Light component:

GetComponent

myLight = gameObject.GetComponent<Light> ();

How do you know what to put in the <>s? It's almost always the same as the name of the component that you see in the Inspector.

Remember that gameObject refers to the GO that your script is attached to. Later we will see how to talk to other GOs.

Working with Components

So you've got a Light. What can you do with it?

You can talk to its properties, such as color. You can also get to the checkbox that turns it on and off.

As you saw in the homework, one kind of component you can talk to is the Text component built into Unity's UI system.

Example: Text Output

You can make one from the GameObject menu: choose

         UI -> Text

Changing the text of a Text component from code looks like this:

This can get a little confusing with all these uses of the word "text". All you can do is name your variables as clearly as possible.

levelNameText = gameObject.GetComponent<Text>();

levelNameText.text =
     "LEVEL "+currentLevel.ToString();

Perhaps this is clearer, even if it's a little longer to type. Think about what makes sense to you.

levelNameTextComponent = gameObject.GetComponent<Text>();

levelNameTextComponent.text =
     "LEVEL "+currentLevel.ToString();

The first line asks the gameObject (GO) that is running this script to look at its other components and find one that is a Text.

levelNameText =
       gameObject.GetComponent<Text>();

The first line asks the gameObject (GO) that is running this script to look at its other components and find one that is a Text.

levelNameText =
       gameObject.GetComponent<Text>();
gameObject

the gameObject that is running this script

In this example, the script called UI Manager is attached to the gameObject called Level UI.

gameObject
   .GetComponent<Text>();

the function that asks the GO to look through its components and return a reference to the one with the type you want.

gameObject
   .GetComponent<Text>();

In this example, the gameObject called Level UI has a Text component.

 

So this piece of code will return a reference (way to talk to) the Text component.

The second line talks to the Text component and sets its "text" property to a new value.

levelNameText.text =
     "LEVEL "+currentLevel.ToString();

Just like the Light component, the Text component has lots of different properties; its text is just one of them.

 

You can also change the text size, font, color, etc. by setting those properties.

Stretch

References

In the Unity editor you can make all the GameObjects, components, materials, scripts, etc. that you want.

 

You can see them. The engine can "see" them. But your scripts can't.

Each script is an island unto itself. To talk to or change anything else, you need a reference.

 

A reference is (conceptually) an arrow that points to the GameObject, component, or file you want.

In a MonoBehaviour script, Unity gives you a few built-in references. The most important one is

 

             gameObject

 

which means the GO that this script is attached to.

When you use

 

   GetComponent<ComponentName>()

 

what is really happening is

 

   gameObject.GetComponent<ComponentName>()

 

So Unity looks on the same GameObject as your script.

This is the pattern to get a reference to a component. Declare a variable with the type of component we want, and then go find it in the Start function.

Rigidbody rb;
Collider myCollider;

void Start() {
  rb = gameObject.GetComponent<Rigidbody>();
  myCollider = gameObject.GetComponent<Collider>();
} 

We'll see this pattern over and over in the scripts we write in class.

But notice you don't have to GetComponent to talk to a transform.

 

Transform is special, because every GameObject has a transform, even empty ones. Every other component will be on some GOs and not others.

someGameObject.transform 

If you want access to another GameObject, you have to set that up yourself. We'll see many different ways to do that this semester.

 

The simplest one is this:

 

    [SerializeField]
    GameObject theOtherGameObject;

 

This makes a slot on the script in the editor where you can just drag in another GO.

Once you have a reference to that other GO you can do all the GameObject-y things with it:

 

theOtherGameObject.name

theOtherGameObject.transform

theOtherGameObject.GetComponent<Light>()

 

and so on.

Stretch

Demo: Simple Race

Asset credits

Racing game sprites: Kenney.nl

Yay sound: FreeSound

Choose someone near you to do this mini-lab with.

 

Find the demo project on our shared drive. Open it and take a look at the scripts (there are only two).

 

Then press Play and see if you can spot the bug.

What we think will happen

What the code actually says to do

vs

Draw What

You Want

Events and State

A pattern for thinking about code

Because Unity calls the code in Update every frame, your code needs to be ready to handle any possible situation.

 

This is hard. But you can break it down.

 

The computer science name for "situation" is state.

State includes any information you care about while the game is running.

 

Unity keeps track of some of it for you. For example, Time.time updates constantly and you can just ask Unity when you need it.

But Unity doesn't know anything about your game, so you need to track a lot of things yourself, including things that are so obvious they're invisible.

 

This is often going to be a boolean (true/false) value, like whether the game is over.

So you often want your game to behave differently when it is in different states: tutorial, game running, level over animation, game over.

 

But often you want to respond, just once, to the moment when the state changes, which we will call an event.

 

(Programmers would use the word transition. Use the word that makes sense to you.)

The demo project offers an example of one pattern for responding to an event (transition) once and only once.

 

Briefly, you need a way to remember whether you already responded. "A way to remember" is the same thing as a variable. Here it is either true or false, so you need a bool.

  1. Make a bool to remember whether you have already responded to the event. For example, by showing particles or playing a sound.
     
  2. Every frame, check whether the state you care about has changed.
     
  3. In the frame where it changes:
    1. Check whether you already responded.
    2. If so, do nothing. If not, respond to the event show your particles and
    3. Set the bool so you know you responded.

Draw Diagrams

Example Slides for CTIN 483 - Class 3

By Margaret Moser

Example Slides for CTIN 483 - Class 3

Vectors. Components and references. State and events. Keyboard race demo.

  • 191