Matt Bird writes all sorts of nonsense, but he dedicates a large chunk of his time to writing game walkthroughs.
In many cases, the functionality you'll need to create a game is baked right into Unity via components. Found on every GameObject, components cover many of the basic things a GameObject might need - hit detection, appearance, physics, animations, etc. - with no need for further programming. This is not always the case, though, and when you need your game to do something that components can't provide, you'll need to create a script.
Scripts are C# programming documents that provide one or more extra bits of functionality to your game. A script might be as small as two or three lines and count down a number to zero... or a script might be thousands of lines long and create an entire battle system. Scripts serve all needs, and knowing how to create and use a script is essential to game creation in Unity.
Creating a Script
There are three ways to create a script in Unity, and unlike just about everything else to do with scripts, they're all pretty simple. First up is creating the script directly in the Project view at the bottom of the screen. Right click in an appropriate folder in the Project view, preferably one that you want to use for scripts...
... and this window will pop up. Highlight Create at the top and choose C# Script in the next window. You'll then be asked to name your script and it will appear in the Project view. You can then select it like any other component when messing with a GameObject, or simply drag-and-drop the script directly onto the GameObject to add it.
Easy enough. What if you want to create the script directly on the GameObject? It's the same as adding a component, just with an extra step.
Click on Add Component at the bottom of your selected GameObject. Regardless of what you enter as a Search parameter there will always be a New Script option at the bottom of the window. Choose that and name your script. The script will appear in the Assets folder of your Project.
The final method for creating a script is to create it via the menu.
Choose Assets at the top of the screen, then Create, then C# Script. Again, the new script will appear in the Assets folder.
Creating the script is the easy part. Now we need to learn how to use the script when making games. Scripts in Unity use C# - and can support other languages, but that's beyond the scope of this article - so you'll need to learn some C# if you want to make the most of Unity.
When you create a new script you'll need a secondary program to open it up and make changes. This writer uses Microsoft Visual Studio, though there are other options available as well. Once you have a script editor available, you can double-click on the script and open it in the editor. You'll see the following code on your screen.
Let's go through each of the lines so you understand what you're looking at before we get started on anything else.
First up we have three 'using' statements. These are known as namespaces. Namespaces are collections of related classes which you can include in your scripts to add functionality to your game. If you want to add additional classes you add a new namespace to this list at the top of your script. We will get to these more in a bit, but suffice it to say that you don't want to mess with the namespaces if you're a beginner.
Our first example of a class comes next in Monobehaviour. In this case we have a public class called 'ExampleScript', which is the user-entered name when the script was created. Monobehaviour is a Unity-created class that contains most of the functionality you need to make your games. Monobehaviour is essential for using scripts in Unity, because scripts that do not contain Monobehaviour as a class cannot be attached to GameObjects.
When coding in Unity, the vast majority of your script needs to fall within the Monobehaviour curly brackets. Anything outside those brackets will likely be seen as an error.
After Monobehaviour we see a bit of documentation. '// Use this for initialization' is not read as code thanks to the two slashes at the beginning of the line, and so will not result in an error. Using // to leave yourself notes is highly recommended, as you can easily forget the function of a chunk of code and lose time reminding yourself. Document your progress often!
Pro Tip: // only omits that one line from being read by your compiler. If you want to omit multiple lines, you can use /* and */ to cover a chunk of text, like so.
Anything that falls between /* and */ is not read by the compiler. This is handy for separating code that isn't working or needs further testing from the rest of your script without deleting the lines. Just make sure /* comes first and */ comes last or it won't work!
Back to the starter script. Next up we have two functions.
Functions are single-use snippets of code, called by Unity, that carry out a specific task. Most functions need to be called by scripting, but Unity itself calls Start() and Update() automatically, hence their inclusion as the building blocks of a new script.
First up is Start(). Any code used in Start() executes automatically when the script is first put into use, and only runs once. Here is an example.
Here we grab the Transform of the GameObject the script is attached to and set the values to something different with a Vector3. These new coordinates will execute automatically when the GameObject the script is attached to is created, and the GameObject will move to coordinates 1x, 1y, and 0z.
Remember, you can manipulate anything you like in the script via Start(), but you can only do so once. After the code in Start() is completed it isn't called again during the lifespan of the GameObject. For any further calls you're going to need a different function, and that function is Update().
True to the documentation, Update() is a function that is called by Unity once per frame. If any of the coding in Update() applies at a given time, Unity will carry out the code. Here is an example.
Here we have detection code for a key press. If at any point while the GameObject is active the player presses the V button, the GameObject to which this script is attached will be destroyed. Unity checks for key presses constantly, with the effect that the destruction will be carried out more or less instantaneously when the V key is pressed.
Unity checks a GameObject's Update() function every frame, which typically equates to somewhere between 30 and 60 times per second. For this reason you need to be careful with what you throw between Update()'s curly brackets, as poorly-constructed code will be executed constantly. This can lead to lag and crashes. if() statements that check whether or not a code should be executed at a given time are your best friends when dealing with Update().
You may notice 'void' in front of both Start() and Update(). This spot is reserved for functions that return a value when they're called. For example, if you wanted a function to return an integer, you would create a new function with the code 'int ReturnNum()'. The code within the function would be expected to return an integer when called. If a function has 'void' in front of it, however, no return value is expected by Unity.
Scripts can be devilishly simple or endlessly complicated, but a good script will typically zero in on achieving a single objective. We will start on the simple side so you get an idea how a basic script is constructed.
Below is a sample script that moves a GameObject around randomly.
Let's go through this bit by bit.
First we have our namespaces. We don't need any additional functionality, so these remain the same as before. The same goes for Monobehaviour, and we've hijacked ExampleScript again for this sample.
Next up is a variable declaration. We haven't dealt with variables yet, but they're pretty simple in this context. Variables are placeholders where you can stick a predetermined value for use later in your script. In this case we use 'GameObject thisObject' to create a placeholder for a GameObject called thisObject, which we will fill momentarily. You can declare all kinds of variables - int, float, string, etc. - and those declarations should go up top, just before Start().
Next is Start(). Here we will give thisObject a value right off the bat, and that value is the gameObject to which the script is attached. Normally you wouldn't bother giving the parent GameObject a name (just typing 'gameObject' to detect it is enough) but for this example we will shove it in thisObject.
After the variable declaration we immediately manipulate the position of thisObject using a call to the ReturnVector() function. We'll get into what this means fully in a minute, but the result here is that thisObject's coordinates are randomly changed. Remember, this code only happens once, so all other coordinate changes will need to be done manually.
Next we will jump down to the meat of the script. As with a previous example, Update() here checks for a key press before it executes anything. The moment you hit the V key Update() will execute the if() statement's code, which is identical to what happened in Start() - it jumps down to ReturnVector().
ReturnVector() is a custom function added to randomly choose new coordinates for thisObject. Since we want a returned value we add 'Vector3' in front of ReturnVector() in place of 'void'. Unity will thereafter expect a returned value in the form of a Vector3 before it will compile.
To start off we define two new variables, both integers (int), called firstNum and secondNum. These are local variables, and can only be used within ReturnVector. We've assigned both of these variables a Random.Range value between 0 and 20. We then create a third local variable, newVector, and apply firstNum and secondNum to the Vector3. The result is a newVector with an x value equal to firstNum, a y value equal to secondNum, and a z value of 0.
ReturnVector() requires a return value, so we plug in newVector at the bottom. This new Vector3 gets passed back up to the if() statement in Update(), and thisObject's Transform values (its coordinates) are changed to reflect the random numbers chosen in ReturnVector(). thisObject then changes places in the game, and will continue to change places every time you hit the V key.
Code written. Now save your script and try it out in Unity by hitting the play button in the top-middle of the Inspector. If everything went according to plan the GameObject will move once, and when you hit the V key it will move again, and again, and again.
There. That wasn't so bad, was it? The code was more bloated than it needed to be, but the effect is achieved. And that should be your goal when starting out in scripting: Get the script to work. It may look messy and it may prove inefficient, but a functional script is a functional script. You can worry about efficiency when you're a more experienced programmer.
My Script Won't Compile! What now?
Scripts virtually never correctly work the first time you try them out, and if there are big enough problems Unity will pass an error code and refuse to compile. Here are some tips for getting your program up and running:
- Check the Console view in Unity. It appears by default beside the Project window in Unity, and provides a listing of all errors before you even try to compile your project. This can help narrow down your issue. Coding errors also appear in red at the very bottom of the screen.
- Check for highlighted errors in the code. In Microsoft Visual Studio errors will be underlined in red, and there is an Error List in the View menu that provides more detail for each detected error. (There are also errors / notifications underlined in green which are less grievous and will not result in a compile error, but which may still require your attention.)
- Check your brackets. Unity is very, very finicky about its brackets, and as your code gets more complex you'll have statements within statements within statements on a regular basis. If you don't have all your brackets lined up properly you'll get an error. This applies to normal and curly brackets alike.
- Check your semicolons. Most lines of code in C# require a semicolon to indicate the end of a line. Without that semicolon the program assumes that one line is part of another, and things start to fall apart.
- Check your spelling. Typos in variable names lead to errors. Unity is also case-sensitive, so if you failed to capitalize the O in thisObject the program would assume you're referencing a different, undeclared variable.
In short, fiddle with your script. Many programming errors - most programming errors - are the result of a simple typo or misplaced symbol. You may have to stare at your script for a while to find the error, but so long as you keep the tips above in mind you shouldn't have too much trouble identifying the problem and getting back on track.
C# is a massive programming language, and you can do all manner of things in Unity with your scripts. There is no way we can possibly describe everything you can do in a single article. The best path forward is to create simple scripts and work your way up, learning Unity's many statements and functions as you go. The internet is replete with examples of good script that you can study and learn from, and advice on how to tackle problems is legion. The more you study these scripts the better you'll get at your own coding.
And remember: There are virtually always multiple ways to tackle a problem in Unity. If your script isn't working, you may want to start over with a different approach. The chances are good your second attempt at the problem will go better than the first, and you'll learn a lot in the process.