Chapter 2
First program and printing

This section is mostly about mechanical stuff – things we need to get out of the way before we can get to the programming part. The first part is setting up Unity3D to where we can run a program. The next is the basic rules and parts of a program.

Then the rest is a little about programming – one command, and rules for computer math.

Many of the rules are obvious, but it’s nice to have them all in one place, written down. So at least skim them if you already know most.

2.1 Hooking up a simple program

I’m going to describe the quickest way to set things up so Unity3D can run a program. If you’ve got it set up, or want to set it up in some other way, that’s fine. Not much later depends on you having things this exact way.

2.1.1 Install/configure Unity3D

One of the nice things about using Unity3D is that there’s been a lot written about getting started. I’m going to list the steps, but not go into detail about the parts that are easy to find a video of.

Obviously, download and run Unity3D. It may direct you to something called UnityHub, or may allow a direct download. The exact version won’t matter, but the latest one is fine. There will options to include various extra Assets – we won’t need any of them, but they won’t hurt. You can always get them later.

Then we’ll need the code editor. One used to come with Unity, but no longer. If you already have MS-Visual Studio, you can use that. If not, Unity prefers something called Visual Studio Code. It’s not really Visual Studio – it’s an open source C# editor called Monodevelope which microsoft modified and put on their site. Getting it all is a pain.

After installing, you should check it’s connected to Unity. With Unity open go to Unity->Preferences->External tools and see it’s set to Code or Visual Studio.

If you haven’t used Unity before, you may want to arrange the panels and play around. In the upper-right corner, where it says Layout, my favorite is “Tall.”

We’ll mostly be typing and running programs, but we’ll need to know a little about the areas in the Unity screen:

2.1.2 Program set-up

To get a program we can run, we need to do three things: make a new program file, open it so we can type stuff, and convince the Unity3D system to run it.

To make the file, find the top bar of the Project panel and click Create->C# script (script means program. It’s supposed to be less scary sounding.) A new item should appear below and ask you to name it. Name it anything with no spaces – testA is fine.

As soon as you name it, you’ll see some code lines in the Inspector side-panel. That’s just a helpful preview – you can’t type anything there.

To bring up the editor, double-click your testA. It may take a while, but eventually a new window with your editor will appear, with your program in it. That’s where we’re going to do all of our typing. We can hide it, for now.

The last step is convincing Unity3D to run it. This is a little funny, so I want to explain the way game engines think:

The system takes care of the 3D world, remembering where everything is, and showing it. If we want a block to move back-and-forth, it expects us to write a back-and-forth program and put it on the block. If we want the light to flicker on and off, we write another mini-program and put it on the light.

That seems funny, writing more than one program, but it’s pretty typical. For example, a web page has a mini-program for each button.

The way the system thinks, if you write a program and don’t put it on anything, you don’t want to run it yet. Even a program that only prints to the Console still has to be on something to run.

Right now, we have two things in the game world we can put our program on. Directional Light has more room, so we may as well use that. Select Directional Light (the one in Hierarchy.) You should see its details in the Inspector. You could safely pop shut the little area with details about how bright it is.

Next drag testA from Project onto the blank space at the bottom of DirectionalLight in the Inspector. If it works, the original testA will still be in Project, and Directional Light will have a new testA section.

2.1.3 Errors in set-up

The system won’t prevent you from having more than one running copy of testA. If you accidentally drag it twice onto the Light, it makes 2 copies. Or you may accidentally drag another copy onto the Camera.

The system will run every copy of your program at the same time. It won’t necessarily cause a problem, but it will print the output twice, possibly in mixed-up order, making it difficult to see if your program worked.

If that happens, you can scroll through Hierarchy and look at the Inspector for each. When you find a duplicate, click the gear on the right side and select RemoveComponent.

The obvious other problem is you can have 0 copies running. Make sure it’s on the Light or the Camera.

When you try to drag it, you might get an error pop-up “Can’t add script.” That’s probably due to a late name change. When you make it, you can keep the name or change it. But if you rename it later the system gets confused (we’ll see why, later). For now, the easiest way to fix “Can’t add script, names don’t match” is to delete the script (right click, Delete from the Project panel) and start over.

2.1.4 A simple program

A normal program starts blank, and you type everything. But it’s also common for a system to give you some starting code, which Unity does. If we bring back the code editor window we should see these program lines. Don’t worry too much about what they mean yet:

using UnityEngine;  
using System.Collections;  
 
public class testA : MonoBehaviour {  
 
  // Use this for initialization  
  void Start () {  
 
  }  
 
  // Update is called once per frame  
  void Update () {  
 
  }  
}

Eventually every symbol will make sense, but for now, we’re going to ignore or delete most of it. But it still helps to have a really rough overview:

To make our first program easier to read, let’s delete down to the bare minimum. We don’t need the Update chunk or the \\ comment lines. We just need this:

using UnityEngine;  
using System.Collections;  
 
public class testA : MonoBehaviour {  
 
    void Start () {  
 
    }  
}

Unity’s special rule is that it runs the chunk named Start. The open and close {}’s mark off the contents, which is currently nothing. So this is the smallest program which runs and does nothing.

We can finally start writing the real program. I’ll have it print three things:

using UnityEngine;  
using System.Collections;  
 
public class testA : MonoBehaviour {  
 
    void Start () {  
        print( "howdy" );  
        print( 4+3*10 );  
        print( "2+5" );  
    }  
 
}

Some details about typing this and the symbols (which will be super-obvious once you get used to them):

Finally, there’s one more install problem that may need solving. The editor should highlight the special Unity commands – Monobehaviour, UnityEngine, print. If those are white or don’t pop up, or hovering doesn’t give a tool tip, it means “intellisense” is broken. The code editor may be asking you to install add-ons. Add anything with Unity in the name. Or search for “Unity Code Intellisense not working”.

Broken pop-ups won’t stop the code from running – Unity can read it even if the code editor can’t. But it will get annoying after a while.

2.1.5 Running it

To run the program, save it, click back to the Unity3D window, and click the Play button on top. We should see 2+5 on the bottom of the window. After a little bit, press the Stop button.

The program printed three lines to the Console window. If you remember, the bottom of the screen helpfully shows us the last line. Double-clicking brings up the Console with lines: howdy, 34 and 2+5, and some junk between them which we can ignore.

The Console window will always pop-up when you double-click. I usually close it when I’m done reading, since it’s so easy to reopen.

Before looking at what those three lines mean, some more notes about the system:

2.2 Statements, print

Computer commands are called statements. Not a big deal, but error messages use the word, so you’ll be seeing it. Statements run one at a time, top to bottom, left to right. Statements end with a semi-colon, which acts like a period in a sentence.

The part of the program we care about is three statements:

      print( "howdy" );  
      print( 4+3*10 );  
      print( "2+5" );

Notice how even the last one needs that semi-colon. It’s like how even the last sentence in a book needs a period.

print is meant for testing, which is why it prints to the Console, with the extra lines.

The ()-parens are part of the print command, and always have to be there. It prints whatever is inside them. In other words, the print statement looks like this:

print( stuffToPrintGoesHere ) ;

The contents of those prints are just to get us started. You might notice there are two types:

The last line "2+5" looks like math, but it’s in quotes, so uses the print-exactly rule. If you took the quotes off, saved and pressed Play, it would print 7.

2.3 Intro to computer math

Computer math works as much as possible the same as real math. The oddest thing is that the star symbol (*) is always used for multiply. In regular math, you can write 3x or 4(3 + 5). In a computer, you’d have 3*x or 4*(3+5).

Precedence works the same as normal math: multiply and divide before plus and minus. The second line 4+3*10, is 34 because 3 times 10 goes first.

Also like regular math, parens go first. print((3+4)*10); gives 70.

Required parens and math parens can be a little confusing. In print((3+4)*10); the outer parens are required parts of the print. The inner ones, around 3+4, are math parens that we added to change the order.

You can add all the math parens you like, even ones you don’t need. For examples print( 3+(4*5) ); or print((2+5)); or even print(((1))+(2));

Here are a few more, with what they print:

print( 5 ); // 5 -- counts as math  
print( "5" ); // 5 -- works differently, but looks the same  
 
print( 12/2 ); // 6 -- same division symbol as normal  
print( 1+1+1+1+1 ); // 5 -- can be as long as you want  
print( "6/3+1"); // 6/3+1 -- not math, because of the quotes  
 
print( 3*2+2*2 ); // 10 -- both multiplies go first, then 6+4

2.4 More writing program details

The part about using Unity is now mostly out of the way, and we can focus on writing a program in the editor for a while. But there are still rules about just program writing in general.

This isn’t too tricky, but I want to be sure you see the terms and the general idea.

2.4.1 White space

Together, all of the indents, blank lines and extra spaces are known as White Space. The short rule is that none of it matters. Statements work like sentences, with semicolons instead of periods. The long rules are mostly obvious, but here they are:

Spacing makes absolutely no difference to the program. The computer actually pre-scans your program, making a version with extra spaces removed. Feel free to use or not use white space however it looks nice.

Some more fun examples:

print( 6 - 3-2 ); is 1. It looks a little like 3-2 goes first, but spaces don’t matter, and math goes left to right. print( 1 * 2+3 * 4); is really 2 plus 12. The confusing spaces don’t matter.

print(  "cat"); prints cat with no spaces in front. The computer scans them out and sees print("cat"). For fun, print(" cat"); does make a space (more on that later.)

2.4.2 Style

The official word for things you do a certain way, even though the computer doesn’t care, is Style. The idea is if you arrange your program to be pretty, it’s much easier to read. And if you know the normal way people arrange programs, its easier to read other people’s code.

A common style rule is how to indent. The usual rule is: everything inside a “chunk” is indented a little extra. That way you can tell what’s inside what. Usually the final curly-brace lines up with the start of the chunk.

Some people like to put the beginning curly on a line by itself, so the { and } line up exactly:

  void Start()  
  {  
    print("A");  
    print("B");  
  }

Moving the { to the end of the Start line is just a style choice. It makes the program shorter, and looks not-too-bad.

Since the indent rules are so common, the editor knows them. When you make a new line, it tries to indent the normal amount. But there’s nothing special about the spaces it makes. You can change the settings if you want.

Blank lines are often added between major parts. In Unity’s starter program, it would look funny if the ending } of Start was right next to the beginning of Update, so a blank line was added. If you had three prints for your name, then three for something else, a blank line between them looks nice.

We rarely write two statements on a line. But sometimes it looks nice if they’re short, and, in your mind, they do one thing . Most people break statements over two lines if they go off the page.

Spaces are added to make it look nice. Some people prefer spaces to make the print-me part stand out: print( "A" ); others don’t: print("A");. In math, spacing can help show the order, like 3 + 2*4.

The funniest thing about style rules is how important they are. They don’t really mean anything, so a lot of people don’t bother making the program look nice. But as soon as you have to track down some error, you get lost. Don’t go nuts, but “proper” indents, spacing and blank lines save more time than they waste.

2.4.3 Comments

Almost all programs have ways to put little notes in them, called comments The comment symbol is a double backslash, //. It counts as one thing, so can’t have a space between.

The rule for comments is: everything after the comment symbol is skipped, until the end of the line. Obviously, comment lines don’t need semi-colons.

Comments can be on lines by themselves, or at the ends of real lines. Some sample comments:

// ==========  
// Program to help cats  
// do their taxes  
// ==========  
 
using UnityEngine;  
using System.Collections;  
 
// this program is named testA  
public class testA : MonoBehaviour {  
   // inside testA  
 
    void Start() {  
        // inside of Start  
        print( "A" ); // prints A  
 
        print         // useless comment in the  
        ("B");        // middle of a silly statement  
 
        //print("C");  
        print("D");  
 
    } // end of Start  
}  // end of testA

Comment blocks like the top 4 lines are common enough. The two lines full of =’s look like they might mean something, but they don’t. They’re just cute borders.

The comment about printing A is useless – never clutter up your program with that junk – but it shows adding a comment at the end of a real line.

Comments like on the split-line printing B are rare, but it shows the rules. The computer really will read those two lines as print("B");.

The line printing C is a trick called commenting out. The program will not print C, since it’s a comment. It’s a neat trick to temporarily take a line out of the program. It’s not a special rule – it’s just a regular comment – but we’re using it in a sneaky way.

The last two “end of” comments were common before editors could quickly auto-display matching curly-braces. They were helpful time-savers reminding us which close-curly-braces were closing which part.

Most of the comments I’m going to write are “teaching” comments – good for me explaining parts, but wastes of space in a real program.

2.5 Errors, Syntax errors

There are two main categories of errors. The second type is when your program is running along just fine, and then crashes. We won’t get any of those for a while. The first type are syntax errors, which are a little like spelling a word wrong. They prevent your program from starting.

2.5.1 Compilers

To understand syntax errors, it helps to know how the computer really runs your program:

The program you typed is officially called the Source Code. The computer doesn’t run it directly. Instead, a compiler scans your source code to turn it into something the computer can run, called the executable. This scanning first skips all the comments and white spaces, then matches all the {}’s to find the chunks, then checks syntax of all the statements (proper semicolons, spelling, proper math, …). There’s more after that. The goal is to get the smallest, fastest possible program for when we distribute it.

All of this is invisible to us. That little pause when you return to Unity is the compiler running.

If there’s even one thing the compiler can’t figure out, it can’t make the executable, so can’t run. For example, you might have ten perfectly good print statements in Start(). Then somewhere down below, not even in Start(), you have one bad one, misspelled priint. The computer will refuse to run anything until you fix that 11th statement.

The compiler lists all syntax errors, with red balls next to them, in the Console. As usual, you only see the last one until you double-click to bring up the window.

Double-clicking an error will bring up the program window and jumps to the line where the computer first noticed it. Reading the error message says what the computer thinks is wrong. The messages use good solid computer terms, which should start to make sense as you learn more about programming.

The compiler mostly scans the program from top to bottom, left to right. This means that the first error is almost always the one to check. The ones after it might have been caused by the first one.

We’re going to be getting a lot of errors, so we may as well cause a bunch now and take a look at the messages. They don’t hurt the computer.

2.5.2 making some errors

Let’s make a missing semi-colon error. Take the semi-colon off the end of the first print, save and go back to Unity:

void Start() {  
  print( "howdy" )   // <- missing  
  print( 4+3*10 );  
  print( "2+5" );  
}  
 
// 2 Errors:  
testA.cs(5,17): error CS1002: Expecting ‘;’  
error CS1525: Unexpected symbol ‘(’, expecting ‘)’, ‘,’, ‘;’, ‘[’, or ‘=’

The first error tells us exactly the problem – expecting a semicolon. If we double-click the message, it takes us right to the line.

Just so you know, the error number (CS1002) isn’t important, and the (5,17) is the line number and how far over.

The second error looks scary, but goes it away when you put the semi-colon back. It’s an example of one mistake causing two error messages. If we always try to fix the first error, we’ll be fine.

Now, change so the only error is the last print missing a semicolon. Save and go back to Unity:

void Start() {  
  print( "howdy" );  
  print( 4+3*10 );  
  print( "2+5" )   // <- missing  
}  
 
// 1 Error:  
unexpected symbol }

Even though it’s the same error, the message is different. And double-clicking jumps to the wrong line (the one after the error.)

Try removing the final double-quote from Howdy:

void Start() {  
  print( "howdy );   // <- missing "  
  print( 4+3*10 );  
  print( "2+5" );  
}  
 
// many Errors:  
newline in constant  
newline in constant  
newline in constant  
 ...  
Unterminated string literal  
Parsing error

That’s one angry computer! It thinks your program is one giant multi-line quote, with no end. And double-clicking the first error jumps to the wrong line again. It goes to the line after where we made the mistake.

Try misspelling print. Try Print:

void Start() {  
  Print( "howdy" );   // print is spelled wrong  
}  
 
// one error:  
The name Print does not exist in the current context

This is the compiler’s way of saying “I don’t know what that word is.” You might think it would try to guess that we meant lower-case-p print, but clearly it doesn’t. But it’s still a useful message, and takes us to the line.

Try leaving out the { after Start.

void Start()  // <- missing {  
  print( "howdy" );  
}  
 
// one error:  
Unexpected symbol ‘print’ in class, struct, or interface member declaration

Again, it gets mad at the line after the error. But I think it makes sense why. void Start() isn’t an error, yet. The open-curly could have been on the next line. The computer is telling us “hey, print isn’t a curly-brace!”

Try leaving out both ()’s for Start:

void Start {  // <- missing ()  
  print( "howdy" );  
}  
 
// one error:  
A get or set accessor expected.

That’s just a totally confusing message – we definitely do not need a get or a set. A double-click takes us one line below the problem. But that’s fine – by now we know to also look at the line above.

Trying adding an extra } after the last line of the entire program. That gives me Parsing error with no line number. Flipping the final } to an open-{ says the same thing. Most errors with messed-up {}s do this. The computer matches them all, then, only when it gets to the end, sees you have too many or too few.

Indenting can help spot missing {}’s. Using the little [+] hide/show boxes on the left can also help (it uses the {}s as a guide.) Putting the cursor on an open or close will highlight the matching one. It’s hard for the computer to always give good messages when {}s are wrong.

Try spelling Start wrong – try Stork. No error! But when you run it, nothing happens! This is the worst kind of error, since it isn’t technically wrong, like misspelling Cat as Car. It turns out you’re allowed to name a chunk anything, but only Start gets run automatically.

To sum up:

You may also see some yellow triangles. Those are officially called Warnings. They won’t stop the program from running. Some of them are important, some aren’t. We can ignore them for now.

2.6 Adding more programs

In the next chapters, I’ll go straight to “now try running this program” or just “try these lines” without saying anything about how to hook it up or play nice with any old programs. There are a few ways to add new programs:

The simplest is to reuse testA. Delete the inside of Start and write new stuff. Don’t worry about losing your work. Pretty much all the programs here are like those worksheets you got in second grade. Once you learn from them, you’ll never need them anymore.

Another way is to make a new script (Create->C# Script) and also put that one on the Light. An object can have any number of scripts on it, and will run them all. But running two printing scripts will jumble the lines. There are two ways to run just the new one:

The most obvious is to take off the old one: use the Gear symbol on the old testA and Remove Component. It won’t hurt the program, and you can always put it back on.

The other is to disable it. In the Inspector, there’s a checkbox to the left of the name. That’s the enabled/disabled box. Just be careful, since once you start enabling/disabling things it’s easy to say “why isn’t this working?!? Oh, right, I disabled it.”

For new programs with more major changes, we can make a new Scene and start fresh. Click Edit->New Scene and you’ll get a fresh Main Camera and Directional Light. Unity runs the current Scene, only.

Unity will ask you to name the old Scene. When you do, it goes in Project as a black&white cube-corner icon. Double-clicking a Scene in Project should switch back to it.

Starting Unity will usually go to the last Scene you were using. But sometimes it will start a fresh one (check the Scene name on the top bar.) If that happens double-click on the correct Scene Icon in Project (or just double-click all the cube-corner icons until you find the one you want.)

For really minor testing and messing around, don’t even make a new program. The comment-out trick is great. For example, this runs one line, but we can get back the old ones if we need them:

// midway through math-testing:  
void Start () {  
    //print( "howdy" );  
    //print( 4+3*10 );  
    //print( "2+5" );  
    print(1+3     *2); // <- testing just this  
    //print( (1 + 3)*2);  
    //print(         "x");  
}

2.7 more math

This is just for fun, we’ll do more with it later:

Division is a little funny. print( 14/5 ); prints 2, instead of the correct 2.8. Back in 2nd grade, I learned 145 is two, with remainder four. If you use whole numbers, the computer does whole number math, dropping the fraction.

A fun fact, % is the remainder symbol (officially called modulo.) 14%5 is 4 (five goes in twice, with 4 left over.) It’s sometimes useful, but also a way to show that computers sometimes care about whole numbers.

We can’t write fractions, only decimals. 3-1/2 is just 3 minus 1 divided by 2, which is 3 minus 0 (since 1/2 rounds down to 0.) But 3.5 is fine. Computers can do real math: 4.2 + 0.72 will print 4.55, like it should.