When a class is created, the contained instructions are not carried out at the same time. As it’s been explained, each collection of parts in a class is made up of lines of text called statements. Each statement is carried out in order. Where the computer starts is usually dependent on which collection of statements it’s told to start with. You’re in charge of how the code is started.
Unity 3D provides us with a function called Start(), which we’ll go into later. However, this is the preferred place to begin our code using Unity 3D. Once Start() is called, the computer goes to the first line in Start() and begins to carry out the instructions written there. As the computer gets to each statement the computer starts on the left of the statement and works its way to the right. Basically, a computer reads code like you’re reading this sentence. In our examples we’ll add code to the Start() method provided by Unity to run code when a scene is first started. If we want to repeat our code with every frame then we’ll use the Update() method.
This is different from other development environments which often use Main() as their first place to begin running the code. When you start writing software in other environments you’ll most likely start with Main(). We don’t have to get into that right now, but it’s good to know once you’re done with this book.
3.5.3 Thinking in Algorithms
An algorithm is a step-by-step process. This lends itself to being written in an imperative programming language like C#, which executes operations one at a time and in order. Algorithms are written with statements starting at a beginning statement and finishing that statement before moving on to the next.
Just because we know what an algorithm is doesn’t mean it’s any easier to create one. Therefore, how do we go about writing the all-important algorithm? The first thing should be how you might accomplish any given task by hand.
As an example, say we’re a computer surrounded by a mob of zombies. Thankfully, computers are very fast so we can do a lot before the zombies can get to us. With this in mind, we’re going to want to focus on the zombie closest to us. Unfortunately, computers are also very dumb, so there’s nothing which allows us to just guess at which one is the closest.
First, we’re going to need to know how far away every zombie is from our point of view. Therefore, the computer would probably start with measuring the distance from itself to every zombie available to make a measurement to. After that we’re going to have to compare zombies and distances, so we’ll start with the first zombie we found and compare its distance to the next zombie we found.
If the next zombie is closer, we’ll have to remember that one as being the closest one we’ve come across. Otherwise, if the next one is farther away, then we can forget about him and move on to the next zombie and compare numbers again. Once we’ve gone through all the zombies, we should have identified the zombie who is the closest one to us.
The process which we just thought through is an algorithm for finding the zombie closest to us. It’s not complex, but we had to do a few steps to get to it. First, we needed to get a list of all the zombies we needed to sort through. After that it was an iterative process, by which we needed to remember one zombie as the closest one, then compare others against him to decide whether he would retain the status of being the zombie nearest to us. We’ll be going over many of these problem-solving thought processes as we learn how to program.
This algorithm would look something like the following code block:
We won’t cover the entirety of how this code works, as we are yet to discuss the bulk of what’s going on here, but in short, we gather data, then process data. We repeat the pattern of gathering data, then processing it. At the beginning, we gather data; a starting distance, a close game object and all the game objects in the scene. Then we process it with foreach(GameObject g in allGameObjects). This happens again once in the foreach loop. You can see the pattern in this example, but this pattern exists throughout most programming tasks. Gather the data you need, then process it.
Just for a proof of concept we draw a line from the object. Because the script is attached to the object, we draw a line from the object the script is attached to toward the object selected as the closest. The scene will look something like this:
To view this open the StatementsAndExpression_Scene in the Editor and press the Play-in-Editor button, then switch over to the Scene panel. The Debug.DrawLine is not visible in the Game view and is only visible in the Scene editor. You can move some of the objects around the sphere to see the red line switch to different objects as they change distances. We put the code in the Update() method to make sure that the line is always visible, and the closest object can change if you move the objects around.
Programming is a lot more about a thought process than it is about processing. In other words, programming is less about how to do multiplication as it is about what to do with the result of a multiplication. In your everyday life we take for granted the everyday things we do on a regular basis. However, take a moment and really consider the complexity involved with something as simple as breathing.
Your diaphragm is receiving signals from your autonomic nervous system, causing several chemical reactions in the diaphragms muscle tissue, which then pull proteins toward one another causing it to contract. This in turn creates a lowered air pressure in your lungs, which pulls in air. A number of chemical processes allow the oxygen in the atmosphere to enter your blood stream. Thankfully, all of this happens without our thinking of it because of chemistry and physics. In programming, nothing is so automatic.
3.5.3.1 Wash, Rinse, Repeat
In our everyday life we see instructions written everywhere. However, if we follow instructions too closely we’d run into problems. If you interpreted, for example, the instructions on most shampoo labels like a computer we’d run out of shampoo the first time we used it.
To interpret the “wash, rinse, repeat” instructions like a computer we’d wash our hair, rinse it, then wash our hair, then rinse it, then wash our hair, then rinse it, …; you get the picture. You’d continue the process until you run out of shampoo. Because there are no further instructions, once the shampoo has run out, a computer would send out an error of some kind. There wasn’t a number given for how many times the instructions should be followed; there was no way to terminate the process, as a programmer would say. A computer would need to have the “shampooing” process killed to stop washing its hair. Simply put, computers lack common sense.
Here’s a simple scenario: A spouse tells the programmer to go to the grocery store and says “Get some bacon, if there’s milk get three.” The programmer comes home with three packs of bacon, and no milk. If this makes sense, then you’re thinking like a programmer. There are conditions to tell the programmer to get three packs of bacon if milk was available; just the fact that there was milk meant bringing home 3 × bacon.
3.5.4 What We’ve Learned
Programmers are often a group of literal thinkers. A programmer uses a different thought process from the artist. In terms of order of operation, programmers take things one step at a time. An artist tends to start with a broad picture, then refines detail where necessary. This process in programming terms is an imperative procedure, a step-by-step process where operations are carried out in a linear fashion.
As an artist or newcomer to programming, this imperative process can be a bit out of the ordinary. With some time and practice, however, this paradigm of thinking will become second nature. The approaches a programmer and an artist would take to solve a problem often diverge.
To learn how to write code is to learn how to think like a programmer. This may sound a bit awkward, but perhaps after some work, you’ll understand why some programmers seem to think differently than everyone else.
3.6 Keywords
Keywords are special words, or symbols, that tell the compiler to do specific things. For instance, the keyword class at the beginning of a line tells the compiler you are creating a class. A class declaration is the line of code that tells the compiler you’re about to create a new class.
The order in which words appear is important. English requires sentences and grammar to properly convey our thoughts to the reader. In code, C# or otherwise, programming requires statements and syntax to properly convey instructions to the computer.
Every class needs a name; in the above example we named our class ClassName, although we could have easily named the class Charles. When a new class is named the name becomes a new identifier. This also holds true for every variable’s name, though scope limits how long and where the variable’s identifier exists. We’ll learn more about variables and scope soon.
You can’t use keywords for anything other than what C# expects them to be used for. These are called reserved keywords. Some keywords are only used in context with other keywords. There are exceptions, but in general, keywords inform the lexical analyzer of specific commands. Because keywords are reserved for a specific reason, you can’t use them for anything other than the intended purpose. Altogether in C# there are roughly 80 keywords you should be aware of. We don’t need to go over all of them now, so instead we’ll learn them as we come across them.
Because the word abstract is a reserved keyword, you can’t use it as a variable name. The above class contains an error informing you on proper use of the abstract keyword.
3.6.1 The Class Keyword
To create a class named Charles we used the keyword class. The keyword commands C# to expect a word to identify the new class. The following word becomes a new identifier for the class. In this case Charles is used to name the class. Keywords often precede a word, and the computer uses the word following as its identifier.
The contents of Charles are defined between curly braces. After the class definition, the opening curly brace { is followed by any statements that Charles needs to be a proper Charles. When you’re finished defining the contents of Charles, you use the closing curly brace } to indicate you’re done with defining the Charles class.
It’s important to note that keywords start with lowercase letters. C# is a case-sensitive programming language, and as such, Class and class are two different things. In C# there is no keyword Class; only class starting with a lowercase c can be used. The same goes for every keyword in C#.
However, programming works this way: class Charles {} begins with the start of the class indicated with the open curly brace { and the end of the class indicated by the closing curly brace }, after which we go back and add the body later. Not everything works in this way, and it takes a bit of getting used to before you understand the flow. Certainly, however, this will come naturally after some practice.
Now we have a new class called Charles, which has no data and does nothing. This is to be expected since we haven’t added any data or functions yet. You can also use the terminology this class is identified as Charles.
This class can’t be used directly by Unity 3D. It lacks some of the necessary additions needed by the Unity 3D game engine to directly interact with this class. To be specific, this class doesn’t have enough information to allow Unity 3D to know what to do with it. However, there are methods which make a minimal class, such as Charles, quite useful inside of Unity 3D, but we need to cover a great deal of ground before we can do that.
In Section 2.4 we looked at a complete source file, Example.cs, which is ready for use in Unity 3D. However, it’s important to know what creates a minimal class before adding all the rest of the keywords and declarations which make it do anything in Unity 3D, our game engine.
Keep in mind, no two classes can share the same name. We’ll go further into detail about class names and what’s called a namespace later. The contents of the class are contained in the following pair of curly braces. All of the variables and functions that live between the opening curly brace { and the closing brace } become the contents of the class object.
Other keywords that we’ll come across in this chapter include those that indicate a variables type. Some variable keywords which will be covered in the next few chapters are as follows:
int float string
These keywords indicate a type of variable. There are many more, but we’re just going to look at these as an example. An int variable looks something like the following:
A float looks like this:
A string is used to store words like this:
If int and float seem similar, it’s because they both deal with numbers, but as we will see, numbers behave quite differently when computers use them. Keywords are used quite often and they are case sensitive. Therefore, int and Int are different things, and thus using Int i = 0; will not work. Only int is recognized as a keyword, and there has been no definition written to tell C# what Int is. Keywords are also used to indicate special changes in code behavior. The keyword if is what is used to control code execution based on a conditional statement.
As you are introduced to more and more keywords, you’ll be expanding your ability to create new code as well. Keywords make up the complex vocabulary that is required to use C#.
3.6.2 What We’ve Learned
This was a short section, but it covered a fundamental component of a C# construct. Classes are both construction instructions and rules for objects to obey. Writing a complex class takes a step-by-step approach.
Keywords are an important component of any programming language. Some languages have very few keywords. LISP has a mere 18 keywords, C# has about 76, and COBOL has over 400 words reserved for special purposes.
Most programming languages use the same keywords for similar purposes. The var keyword is often used to indicate that a variable is being declared. Because of the similarities between programming languages, once you’ve learned one language, it’s often easy to pick up and learn new languages.
3.7 White Space
Open the WhiteSpace.cs script found in the Assets of the Chapter3 Unity Project. White Space refers to the spaces between words and lines. When typewriters were still in fashion, new lines were entered by pushing on a lever which pushed the roller that held onto the paper to reposition the hammers with letters on them back to the beginning of the next line. This is the origin of the term “Carriage return character” where the mechanism holding the paper was referred to as the carriage. Now, these are called line feed character, next line character line separator, or paragraph separator. It’s also interesting to note that these are unique Unicode characters. On Windows you’ll find the option under Edit → Advanced → View White Space
In OSX with Visual Studio Community you’ll find the option in the Preferences → Markers and Rulers → Show Invisible characters: and select Always
Like letters and numbers, white spaces are also characters entered in your code. In the editor you’ll see faint dots arrows and on OSX you’ll see \n marks spaced throughout your code.
In many cases the new lines and spaces and tabs are there only to help make the code more readable. And depending on what a programmer was taught, the white spaces will be used differently. For instance, adding white space after a function declaration is unnecessary, and the location of the curly braces can pretty much be moved anywhere before or after the contents of the function itself. Leaving the white spaces showing isn’t necessary, but it’s good to know what white space means when talking to a programmer. If none of this makes sense right now, it will later.