5

Introduction to C# and Visual Scripting

Unity has a lot of great built-in tools to solve the most common problems in game development, such as the ones we have seen so far. Even two games of the same genre have their own little differences that make the game unique, and Unity cannot foresee that, so that’s why we have scripting. Through coding, we can extend Unity’s capabilities in several ways to achieve the exact behavior we need, all through a well-known language—C#. But aside from C#, Unity also has Visual Scripting, a way to generate code through a node graph tool. This means you can create scripts without writing code but by dragging nodes, boxes that represent actions that can be chained:

Figure 5.1: Example of a Visual Scripting graph

While essentially both ways can achieve the same result, we can use them for different things. Usually, the core logic of the game is written in C# due to it being usually huge and very performance sensitive. But sometimes using visual scripts instead allows non-programmer team members, like artists or game designers, to have more freedom to edit minor changes in the game, especially regarding balancing or visual effects.

Another example would be game designers prototyping ideas through visual scripts that later programmers will convert to C# scripts when the idea is approved. Also, C# programmers can create nodes for Visual Script programmers to use.

The way to mix these tools varies widely between teams, so while in the next chapters we are going to focus mainly on C#, we are going to also see the Visual Scripting equivalent version of the scripts we are going to create. This way you will have the opportunity to experiment when convenient to use one or the other according to your team structure.

In this chapter, we will examine the following scripting concepts:

  • Creating scripts
  • Using events and instructions

We are going to create our own Unity components, learning the basic structure of a script and the way that we can execute actions and expose properties to be configured, both with C# and Visual Scripting. We are not going to create any of our actual game codes here, just some example scripts to set the ground to start doing that in the next chapter. Let’s start by discussing the basics of script creation.

Creating scripts

The first step to creating behavior is to create script assets; these are files that will contain the logic behind the behavior of our components. Both C# and Visual Scripting have their own type of asset to achieve that, so let’s explore how to do that in both tools.

Having some programming knowledge is required in this book. However, in this first section, we are going to discuss a basic script structure to make sure you have a strong foundation to follow when we code the behaviors of our game in the following chapters. Even if you are familiar with C#, try not to skip this section because we will cover Unity-specific structures of the code.

In this section, we will examine the following script creation concepts:

  • Initial setup
  • Creating a C# script
  • Adding fields
  • Creating a Visual Script graph

We are going to create our first script, which will serve to create our component, discussing the tools needed to do so and exploring how to expose our class fields to the editor. Let’s start with the basics of script creation.

Initial setup

Support for Visual Scripting is added by installing the Visual Scripting package in the Package Manager as we did with other packages in previous chapters, but as Unity does that automatically for us when we create the project, we don’t need any further setup. That means the rest of this section will take care of setting up the tools needed to work with C#.

One thing to consider before creating our first C# script is how Unity compiles the code. While coding, we are used to having an Integrated Development Environment (IDE), which is a program to create our code and compile or execute it. In Unity, we will just use an IDE as a tool to create the scripts easily with coloring and auto-completion because Unity doesn’t have a custom code editor (if you have never coded before, these are valuable tools for beginners). The scripts will be created inside the Unity project and Unity will detect and compile them if any changes are made, so you won’t compile them in the IDE. Don’t worry, even if not compiling and running the code in the IDE, it is possible to debug, add breakpoints, and check the data on the variables and structures using the IDE and Unity together.

We can use Visual Studio, Visual Studio Code, Rider, or whatever C# IDE you’d like to use, but when you install Unity, you will probably see an option to install Visual Studio automatically, which allows you to have a default IDE. This installs the free version of Visual Studio, so don’t worry about the licenses here. If you don’t have an IDE on your computer and didn’t check the Visual Studio option while installing Unity, you can do the following:

  1. Open Unity Hub.
  2. Go to the Installs section.
  3. Click on the wheel button in the top-right area of the Unity version you are using and click on Add Modules:

Figure 5.2: Adding a module to the Unity installation

  1. Check the option that says Visual Studio; the description of the option will vary depending on the version of Unity and the platform you are using.
  2. Hit the Continue button at the bottom-right:

Figure 5.3: Installing Visual Studio

  1. Check that you accept the terms and conditions and click Install:

Figure 5.4: Accepting the terms and conditions

  1. Wait for the operation to end. This might take a few minutes. There may be additional Visual Studio steps that vary between platform and version; if so, just follow them.

If you have a preferred IDE, you can install it yourself and configure Unity to use it. If you can afford it or you are a teacher or a student (as it is free in these cases), I recommend Rider. It is a great IDE with lots of C# and Unity features that you will love; however, it is not vital for this book. In order to set up Unity to use a custom IDE, do the following:

  1. Open the project.
  2. Go to Edit | Preferences in the top menu of the editor (Unity | Preferences on Mac).
  3. Select the External Tools menu from the left panel.
  4. From the external script editor, select your preferred IDE; Unity will automatically detect the supported IDEs:

Figure 5.5: Selecting a custom IDE

  1. If you don’t find your IDE in the list, you can use the Browse… option. Note that usually, IDEs that require you to use this option are not very well supported—but it’s worth a shot.

Finally, some IDEs, such as Visual Studio, Visual Studio Code, and Rider, have Unity integration tools that you need to install in your project, which is optional but can be useful. Usually, Unity installs these automatically, but if you want to be sure that they are installed, follow these steps:

  1. Open Package Manager (Window | Package Manager).
  2. Set the Packages dropdown to Unity Registry mode:

Figure 5.6: Enabling Unity Registry mode

  1. Search the list for your IDE or filter the list by using the search bar. In my case, I used Rider, and I can find a package called JetBrains Rider Editor:

Figure 5.7: Custom IDE editor extension installation—in this case, the Rider one

  1. Check whether your IDE integration package is installed by looking at the buttons at the bottom-right part of the package manager. If you see an Install or Update button, click on it, but if it says Installed, everything is set up.

Now that we have an IDE configured, let’s create our first script.

Creating a C# script

C# is an object-oriented language, and this is no different in Unity. Any time we want to extend Unity, we need to create our own class—a script with the instructions we want to add to Unity. If we want to create custom components, we need to create a class that inherits from MonoBehaviour, the base class of every custom component.

We can create C# script files directly within the Unity project using the editor, and you can arrange them in folders right next to other assets folders. The easiest way to create a script is by following these steps:

  1. Select any GameObject that you want to have the component we are going to create. As we are just testing this out, select any object.
  2. Click on the Add Component button at the bottom of the Inspector and look for the New script option at the bottom of the list, displayed after clicking on Add Component:

Figure 5.8: The New script option

  1. In the Name field, enter the desired script name, and then click Create and Add. In my case, I will call it MyFirstScript, but for the scripts that you will use for your game, try to enter descriptive names, regardless of the length:

Figure 5.9: Naming the script

It is recommended that you use Pascal case for script naming. In Pascal case, a script for the player’s shooting functionality would be called PlayerShoot. The first letter of each word of the name is in uppercase and you can’t use spaces.

  1. You can check how a new asset with the same name as your script is created in Project View. Remember that each component has its own asset, and I suggest you put each component in a Scripts folder:

Figure 5.10: Script asset

  1. Now, you will also see that your GameObject has a new component in the Inspector window, which has the same name as your script. So, you have now created your first component class:

Figure 5.11: Our script added to a GameObject

Now that we have created a component class, remember that a class is not the component itself. It is a description of what the component should be—a blueprint of how a component should work. To actually use the component, we need to instantiate it by creating a component based on the class. Each time we add a component to an object using the editor, Unity is instantiating it for us. Generally, we don’t instantiate components using the new C# keyword, but by using the editor or specialized functions.

Now, you can add your new empty component to other objects as you would any other component by using the Add Component button in the Inspector window. Then you can look for the component in the Scripts category or search it by name:

Figure 5.12: Adding a custom component in the Scripts category

Something that you need to consider here is that we can add the same component to several GameObjects. We don’t need to create a class for each GameObject that uses the component. I know this is basic programmers’ knowledge but remember that we are trying to recap the basics here.

Now that we have our component, let’s explore how it looks and carry out a class structure recap by following these steps:

  1. Locate the script asset in Project View and double-click on it. Remember that it should be in the Scripts folder you created previously.
  2. Wait for the IDE to open; this can take a while. You will know that the IDE has finished the initialization when you see your script code and its keywords properly colored, which varies according to the desired IDE. In Rider, it looks like what is shown in Figure 5.13. In my case, I knew that Rider had finished initializing because the MonoBehaviour type and the script name are colored the same:

Figure 5.13: A new script opened in the Rider IDE

  1. The first three lines—the ones that start with the using keyword—include common namespaces. Namespaces are like code containers, which is, in this case, code created by others (such as Unity, C# creators, and so on). We will be using namespaces quite often to simplify our tasks; they already contain solved algorithms that we will use. We will be adding and removing the using component as we need; in my case, Rider is suggesting that the first two using components are not necessary because I am not using any code inside them, and so they are grayed out. But for now, keep them as you will use them in later chapters of this book. Remember, they should always be at the beginning of the file:

Figure 5.14: The using sections

  1. The next line, the one that starts with public class, is where we declare that we are creating a new class that inherits from MonoBehaviour, the base class of every custom component. We know this because it ends with : MonoBehaviour. You can see how the rest of the code is located inside brackets right below that line, meaning that the code inside them belongs to the component:

Figure 5.15: The MyFirstScript class definition inherits from MonoBehaviour

Now that we have our C# script, let’s add fields to configure it.

Adding fields

In previous chapters, when we added components as Rigidbody or as different kinds of colliders, adding the components wasn’t enough. We needed to properly configure them to achieve the exact behavior that we need. For example, Rigidbody has the Mass property to control the object’s weight, and the colliders have the Size property to control their shape. This way, we can reuse the same component for different scenarios, preventing the duplication of similar components. With a Box collider, we can represent a cube or rectangular box just by changing the size properties. Our components are no exception; if we have a component that moves an object and if we want two objects to move at different speeds, we can use the same component with different configurations.

Each configuration is a field or variable where we can hold the parameter’s value. We can create class fields that can be edited in the editor in two ways:

  • By marking the field as public, but breaking the encapsulation principle
  • By making a private field and exposing it with an attribute

Now, we are going to cover both methods, but if you are not familiar with Object-Oriented Programming (OOP) concepts, such as encapsulation, I recommend you use the first method.

Suppose we are creating a movement script. We will add an editable number field representing the velocity using the first method—that is, by adding the public field. We will do this by following these steps:

  1. Open the script by double-clicking it as we did before.
  2. Inside the class brackets, but outside any brackets within them, add the following code:

Figure 5.16: Creating a speed field in our component

The public keyword specifies that the variable can be seen and edited beyond the scope of the class. The float part of the code says that the variable is using the decimal number type, and speed is the name we chose for our field—this can be whatever you want. You can use other value types to represent other kinds of data, such as bool to represent checkboxes or Booleans and string to represent text.

  1. To apply the changes, just save the file in the IDE (usually by pressing Ctrl + S or Command + S) and return to Unity. When you do this, you will notice a little loading wheel at the bottom-right part of the editor, indicating that Unity is compiling the code. You can’t test the changes until the wheel finishes:

Figure 5.17: The loading wheel

Remember that Unity will compile the code; don’t compile it in the IDE.

  1. After the compilation is finished, you can see your component in the Inspector window and the Speed variable should be there, allowing you to set the speed you want. Of course, right now, the variables do nothing. Unity doesn’t recognize your intention by the name of the variable; we need to set it for use in some way, but we will do that later:

Figure 5.18: A public field to edit data that the component will use later

In case you don’t see the speed variable, please check the section at the end of this chapter called Common beginner C# script errors, which will give you tips about how to troubleshoot compilation errors.

  1. Try adding the same component to other objects and set a different speed. This will show you how components in different GameObjects are independent, allowing you to change some of their behaviors via different settings.
  2. The second way to define properties is similar, but instead of creating a public field, we create a private field, encouraging encapsulation and exposing it using the SerializeField attribute, as shown in the following screenshot.

Figure 5.19: Exposing private attributes in the Inspector window

If you are not familiar with the OOP concept of encapsulation, just use the first method, which is more flexible for beginners. If you create a private field, it won’t be accessible to other scripts because the SerializeField attribute only exposes the variable to the editor. Remember that Unity won’t allow you to use constructors, so the only way to set initial data and inject dependencies is via serialized private fields or public fields and setting them in the editor (or using a dependency injection framework, but that is beyond the scope of this book). For simplicity, we will use the first method in most of the exercises in this book.

If you want, try to create other types of variables and check how they look in the Inspector. Try replacing float for bool or string, as previously suggested. Consider that not every possible C# type is recognized by Unity; through this book, we will learn the most commonly supported ones. Now that we know how to configure our components through data, let’s use that data to create some behavior.

Now that we have our C# script, let’s see how to do the same in Visual Scripting.

Creating a Visual Script

As we need to create a Script Asset for C# scripts, we need to create the Visual Scripting equivalent called Script Graph and also attach it to our GameObject, although using a different approach this time. Before continuing, it is worth noticing that our objects must only have C# or the Visual Scripting version, but not both, or the behavior will be applied twice, once per version.

Essentially, only do the steps for the version you want to try or do both steps in different objects if you want to experiment.

Let’s create a Visual Script doing the following:

  1. Create a new GameObject to which we will add the Visual Script.
  2. Add the Script Machine component to it. This component will execute the Visual Script Graph we will be creating shortly:

Figure 5.20: Adding a Script Machine component

  1. In the Script Machine component, click the New button and select a folder and a name to save the Visual Script Graph asset. This asset will contain the instructions of our script, and the Script Machine component will execute those:

Figure 5.21: Using the New button to create a Visual Scripting Graph asset

  1. If a warning appears, click the Change now option. This will prevent those changes on the script from affecting the game while its running, because as the warning says, it can cause instability of the code. Always stop the game, change the code, and then play again.
  2. Click the Edit Graph Button to open the Visual Script editor window. You can drag the Script Graph tab to any part of the editor to merge that window:

Figure 5.22: Visual Scripting asset editor

  1. Put the mouse in an empty area in the grid of the Visual Script editor, and while holding the middle mouse button, move the mouse to scroll through the graph. On MacBooks and Apple Magic Mouses you can scroll using two fingers on the trackpad.

What we did is create the Visual Graph asset that will contain the code of our script, and attached it to a GameObject through the Script Machine component. Unlike C# scripts, we can’t attach the Graph Asset directly; that’s why we need the Script Machine to run the component for us.

Regarding fields, the ones we created in the C# scripts are contained in the script itself, but for Visual Graph they work a little bit differently. When we added the Script Machine component, another one was added: the Variables component. This will hold all the variables for all the Visual Script Graph that a GameObject can contain. That means that all graphs we add to our object will share those variables. You can create graph-specific variables if you want, but they won’t be exposed in the Inspector, and this way also simplifies the access of variables from other objects’ scripts. Also remember you will want to add several graphs to the object, given that each graph will take care of different behaviors, in a way in which we can mix and match them according to our needs.

In order to add a variable to our GameObject that can be used by our graph, let’s do the following:

  1. Select a GameObject with a Visual Script added (with the Script Machine component) and look at the Variables component.
  2. Click the input field that says (New Variable Name) and type the name of the variable. In my case, this is speed. If you don’t see that option, click the triangle at the left of the Variables component name.
  3. Click the Plus (+) button of the Variables component.
  4. In the Type dropdown, select Float.
  5. Optionally you can set an initial value in the Value field:

Figure 5.23: Creating variables for the Visual Graph

We created a speed variable that we can configure in the GameObject to alter the way all Visual Scripts Graphs attached to our GameObject will work, or at least the ones that use that Variable value. Consider that maybe you will have different kinds of speed, like movement and rotational speed, so in real cases you might want to be a little bit more specific with the variable name.

The Variables component used in Visual Scripting is also called Blackboard, a common programming technique. This Blackboard is a container of several values of our object, like a memory or database, that several other components of our object will then query and use. C# scripts usually contain their own variables inside instead. With our scripts created and ready to be configured, let’s see how to make both of them do something.

Using events and instructions

Now that we have a script, we are ready to do something with it. We won’t implement anything useful in this chapter, but we will settle the base concepts to add interesting behavior to the scripts we are going to create in the next chapters.

In this section, we are going to cover the following concepts:

  • Events and instructions in C#
  • Events and instructions in Visual Scripting
  • Using fields in instructions
  • Common beginner C# script errors

We are going to explore the Unity event system, which will allow us to respond to different situations by executing instructions. These instructions will also be affected by the value of the editor. Finally, we are going to discuss common scripting errors and how to solve them. Let’s start by introducing the concept of Unity events in C#.

Events and instructions in C#

Unity allows us to create behavior in a cause-effect fashion, which is usually called an event system. An event is a situation that Unity is monitoring—for example, when two objects collide or are destroyed, Unity tells us about this situation, allowing us to react according to our needs. As an example, we can reduce the life of a player when it collides with a bullet. Here, we will explore how to listen to these events and test them by using some simple actions.

If you are used to event systems, you will know that they usually require us to subscribe to some kind of listener or delegate, but in Unity, there is a simpler method available. For C# scripts we just need to write a function with the exact same name as the event we want to use—and I mean exactly. If a letter of the name doesn’t have the correct casing, it won’t execute, and no warning will be raised. This is the most common beginner’s error that is made, so pay attention. For Visual Scripting we will be adding a special kind of node, but will discuss that after the C# version.

There are lots of events or messages to listen to in Unity, so let’s start with the most common one—Update. This event will tell you when Unity wants you to update your object, depending on the purpose of your behavior; some don’t need them. The Update logic is usually something that needs to be executed constantly—to be more precise, in every frame. Remember that every game is like a movie—a sequence of images that your screen switches through fast enough to look like we have continuous motion. A common action to do in the Update event is to move objects a little bit, and by doing this, every frame will make your object constantly move.

We will learn about the sorts of things we can do with Update and other events or messages later. Now, let’s focus on how to make our component at least listen to this event. Actually, the base script already comes with two event functions that are ready to use, one being Update and the other one Start. If you are not familiar with the concept of methods in C#, we are referring to the snippet of code in the following screenshot, which is already included in our script. Try to find it in yours:

Figure 5.24: A function called Update, which will be executed with every frame

You will notice a (usually) green line of text (depending on the IDE) above the void Update() line—this is called a comment. These are basically ignored by the compiler. They are just notes that you can leave to yourself and must always begin with // to prevent Unity from trying to execute them and failing. We will use this to temporarily disable lines of code later.

Now, to test whether this actually works, let’s add an instruction to be executed all the time. There’s no better test function than print. This is a simple instruction that tells Unity to print a message to the console, where all kinds of messages can be seen by the developers to check whether everything is properly working. The user will never see these messages. They are similar to the classic log files that developers sometimes ask you for when something goes wrong in the game and you are reporting an issue.

In order to test events in C# using functions, follow these steps:

  1. Open the script by double-clicking on it.
  2. To test, add print("test"); within the event function. In the following screenshot, you can see an example of how to do that in the Update event. Remember to write the instruction exactly, including the correct casing, spaces, and quote symbols:

Figure 5.25: Printing a message in all the frames

  1. Save the file, go to Unity, and play the game.

Remember to save the file before switching back to Unity from the IDE. This is the only way that Unity knows your file has changed. Some IDEs, such as Rider, save the file automatically for you, but I don’t recommend you use auto-save, at least in big projects (you don’t want accidental recompilations of unfinished work—that takes too long in projects with lots of scripts).

  1. Look for the Console tab and select it. This is usually found next to the Project View tab. If you can’t find it, go to Window | General | Console, or press Ctrl + Shift + C (Command + Shift + C on macOS).
  2. You will see a new printed message saying "test" every frame on the Console tab. If you don’t see this, remember to save the script file before playing the game.
  3. You might see a single message but with a number increasing to its right; that means the same message is appearing several times. Try clicking the Collapse button of the Console to change that behavior.
  4. Let’s also test the Start function. Add print("test Start"); to it, save the file, and play the game. The full script should look as follows:

Figure 5.26: The script that tests the Start and Update functions

If you check the console now and scroll all the way up, you will see a single "test Start" message and lots of "test" messages following it. As you can guess, the Start event tells you that the GameObject is created and allows you to execute the code that needs to happen just once at the beginning of its lifetime.

For the void Update() syntax, we will say to Unity that whatever is contained within the brackets below this line is a function that will be executed in all the frames. It is important to put the print instruction inside the Update brackets (the ones inside the brackets of the class). Also, the print function expects to receive a value to print inside its parenthesis, called an argument or parameter. In our example we want to print simple text, and in C# it must be enclosed with quotation marks. Finally, all instructions inside functions such as Update or Start must end with a semicolon.

Here, I challenge you to try to add another event called OnDestroy using a print to discover when it executes. A small suggestion is to play and stop the game and look at the bottom of the console to test this one.

For advanced users, you can also use breakpoints if your IDE allows you to do that. Breakpoints allow you to freeze Unity completely before executing a specific code line to see how our field’s data changes over time and to detect errors. Here, I will show you the steps to use breakpoints in Rider, but the Visual Studio version should be similar:

  1. Install the Unity package belonging to your IDE if not already installed. Check the Package Manage for the JetBrains Rider Editor package. In the case of Visual Studio, install the Visual Studio Editor package.
  2. Click on the vertical bar at the left of the line where you want to add the breakpoint:

Figure 5.27: A breakpoint in the print instruction

  1. Go to Run | Attach to Unity Process. If you are using Visual Studio, go to Debug | Attach Unity Debugger:

Figure 5.28: Attacking our IDE with a Unity process

  1. From the list, look for the specific Unity instance you want to test. The list will show other opened editors or executing debugging builds if any.
  2. If this doesn’t work, check if the editor is in debug mode, looking at the bug icon at the bottom-right part of the editor. If the bug looks blue with a checkbox, then it is ok, but if it looks gray and crossed out, click it and click Switch to debug mode:

Figure 5.29: Changing from release mode to debug mode

Stopping the debugging process won’t close Unity. It will just detach the IDE from the editor.

Now let’s explore the Visual Scripting equivalent of using events and instructions.

Events and instructions in Visual Scripting

The same concept of events and instructions remains in Visual Scripting, but of course this will be done with nodes in the graph. Remember a node represents an instruction of the graph, and we can connect them to chain the effects of each instruction. In order to add events and the print instruction on our graph, do the following:

  1. Open the Visual Script Graph (double-click the Visual Script asset).
  2. Right-click the On Start and On Update nodes that are created by default and then click Delete. Even if those events are the ones we need, I want you to see how to create them from scratch:

Figure 5.30: Deleting nodes

  1. Right-click in any empty space of the Graph and type start inside the Search box. It can take a while the first time.
  2. Select the On Start element in the list with the green checkbox to its left. In this case I knew this was an event because I was aware of it, but usually you will recognize it as an event because it won’t have input pins (more on that in the next steps):

Figure 5.31: Searching the On Start event node

  1. Drag the white arrow at the right of the event node, also known as the Output Flow Pin, and release the mouse button in any empty space.
  2. In the Search box search for the print node, select the one that says Mono Behaviour:Print. This means that when the On Start event happens, the connected node will be executed, in this case print. This is how we start to chain instructions to events:

Figure 5.32: Creating a print node connected to the event

  1. Drag the empty circle at the left of the Message input pin of the Print node and release it in any empty space. This pin has a circle indicating that is a parameter pin, data that will be used when executing the pin. The flow pins, the ones with a green arrow, represent the order in which the nodes will be executed.
  2. Select the String Literal option, which will create a node to allow us to specify the message to print:

Figure 5.33: Creating a string literal node

  1. In the empty white box write the message to be printed:

Figure 5.34: Specifying the message to print

  1. Play the game and see the message printed in the console. Be sure you have only the Visual Scripting version in the scene to avoid confusing the message in the console with the C# version. You can also use different message texts in the Visual Scripts to be sure which ones are really executing.

You can chain more actions to the On Start by dragging the pin at the right (Flow Output Pin) of the Print node, and chaining new nodes, but we will do that later. Now that we have our scripts doing something, let’s make the instructions use the fields we created so the scripts use their configurations.

Using fields in instructions

We have created fields to configure our components’ behavior, but we have not used them so far. We will create meaningful components in the next chapter, but one thing we will often need is to use the fields we have created to change the behavior of the object. So far, we have no real use of the speed field that we created. However, following the idea of testing whether our code is working (also known as debugging), we can learn how to use the data inside a field with a function to test whether the value is the expected one, changing the output of print in the console according to the field’s value.

In our current C# script, our speed value doesn’t change during runtime. However, as an example, if you are creating a life system with shield damage absorption and you want to test whether the reduced damage calculation is working properly, you might want to print the calculation values to the console and check whether they are correct.

The idea here is to replace the fixed message inside the print functions with a field. When you do that, print will show the field’s value in the console. So, if you set a value of 5 in speed and you print it, you will see lots of messages saying 5 in the console, and the output of the print function is governed by the field. To test this, your print message within the Update function should look as follows:

Figure 5.35: Using a field as a print function parameter

As you can see, we just put the name of the field without quotation marks. If you use quotation marks, you will print a "speed" message. In other scenarios, you can use this speed value within some moving functions to control how fast the movement will be, or you can perhaps create a field called "fireRate" (fields use camel case instead of Pascal case, with the first letter being in lowercase) to control the cooldown time between one bullet and the next:

Figure 5.36: Printing the current speed

Now, to make the Visual Script graph print the value of the speed variable we created in the Variables component, let’s do the following.

  1. Open the Visual Scripting graph asset (double-click it).
  2. In the panel at the left, select the Object tab to display all the variables our object has—essentially the ones we defined in the Variables component previously.
  3. Drag the speed variable using the two lines to the left of the variable box to any empty area of the graph. This will create a GetVariable node in the graph to represent the variable. Consider the drag has a bug at the moment, so you might need to try a couple of times, trying to drag from the left part:

Figure 5.37: Dragging variables to the graph to be used in the nodes

  1. Drag the empty circle at the right of the Get Variable node to the circle to the left of the Message input pin of the Print node. This will replace the previous connection to the String Literal node. This node doesn’t have Input or Output flow nodes (the green arrow ones), as they are data-only nodes that provide data to other nodes. In this case, when Print needs to execute, it will execute Get Variable to get the text to read:

Figure 5.38: Connecting the speed variable to the print node

  1. Right-click on the String Literal node and delete it.
  2. Play the game and observe.

With all this, we now have the necessary tools to start creating actual components. Before moving on, let’s recap some of the common errors that you will likely encounter if this is your first time creating scripts in C#.

Common beginner C# script errors

The Visual Scripting scripts are prepared in a way in which you make fewer errors, not allowing you to write incorrect syntax like C# script does. If you are an experienced programmer, I bet you are quite familiar with them, but let’s recap the common errors that will make you lose lots of time when you are starting with C# scripting. Most of them are caused by not copying the shown code exactly. If you have an error in the code, Unity will show a red message in the console and won’t allow you to run the game, even if you are not using the script. So, never leave anything unfinished.

Let’s start with a classic error, a missing semicolon, which has resulted in many programmer memes and jokes. All fields and most instructions inside functions (such as print), when called, need to have a semicolon at the end. If you don’t add a semicolon, Unity will show an error, such as the one in the screenshot on the left in Figure 5.39, in the console. You will also notice that this also has an example of bad code, where the IDE is showing a red icon suggesting something is wrong in that place:

Figure 5.39: An error in the print line hinted by the IDE and the Unity console

You will notice that the error shows the exact script (MyFirstScript.cs), the exact line of code (14, in this case), and usually, a descriptive message—in this case, ; expected—as a way to specify the instruction ends there, so the compiler can process the next instruction as a separate one. You can simply double-click the error and Unity will open the IDE highlighting the problematic line. You can even click on the links in the stack to jump to the line of the stack that you want.

I already mentioned why it is important to use the exact case for every letter of the instruction. However, based on my experience of teaching beginners, I need to stress this particular aspect more.

The first scenario where this can happen is in instructions. In the following screenshots, you can see how a badly written print function looks—that is, the error that the console will display and how the IDE will suggest that there is something wrong. First, in the case of Rider, the instruction is colored red, saying that the instruction is not recognized (in Visual Studio, it will show a red line instead). Then, the error message says that Print does not exist in the current context, meaning that Unity (or C#, actually) does not recognize any instruction named Print. In another type of script, Print in uppercase may be valid, but not in regular components, which is why the “in the current context” clarification exists:

Figure 5.40: Error hints when writing an instruction wrong

Now, if you write an event with the wrong casing, the situation is worse. You can create functions such as Start and Update with whatever name you want for other purposes. Writing update or start is perfectly valid as C# will think that you are going to use those functions not as events but as regular functions. So, no error will be shown, and your code will just not work. Try to write update instead of Update and see what happens:

Figure 5.41: The wrong casing in the Update function will compile the function but won’t execute it

Another error is to put instructions outside the function brackets, such as inside the brackets of the class or outside them. Doing this will give no hint to the function as to when it needs to execute. So, a print function outside an Event function makes no sense, and it will show an error such as the ones in the following Figures 5.42 and 5.43.

This time, the error is not super descriptive. C# is expecting you to create a function or a field—the kind of structures that can be put directly inside a class:

Figure 5.42: Misplaced instruction or function call

Finally, another classic mistake is to forget to close open brackets. If you don’t close a bracket, C# won’t know where a function finishes and another starts or where the class function ends. This may sound redundant, but C# needs that to be perfectly defined. In the following screenshots, you can see how this would look:

Figure 5.43: Missing closed brackets

This one is a little bit difficult to catch because the error in the code is shown way after the actual error. This is caused by the fact that C# allows you to put functions inside functions (not used often) and so C# will detect the error later, asking you to add a closing bracket. However, as we don’t want to put Update inside Start, we need to fix the error before, at the end of Start. The error message will be descriptive in the console, but again, don’t put the close bracket where the message suggests you do so unless you are 100% sure that position is correct.

You will likely face lots of errors aside from these ones, but they all work the same. The IDE will show you a hint and the console will display a message; you will learn them with time. Just have patience as every programmer experiences this. There are other kinds of errors, such as runtime errors, code that compiles but will fail when being executed due to some misconfiguration, or the worst: logic errors, where your code compiles and executes with no error but doesn’t do what you intended.

Summary

In this chapter, we explored the basic concepts that you will use while creating scripts. We discussed the concept of a script’s assets and how the C# ones must inherit from MonoBehaviour to be accepted by Unity to create our own scripts. We also saw how to mix events and instructions to add behavior to an object and how to use fields in instructions to customize what they do. All of this was done using both C# and Visual Scripting.

We just explored the basics of scripting to ensure that everyone is on the same page. However, from now on, we will assume that you have basic coding experience in some programming language, and you know how to use structures such as if, for, array, and so on. If not, you can still read through this book and try to complement the areas you don’t understand with a C# introduction book as you need.

In the next chapter, we are going to start seeing how we can use what we have learned to create movement and spawning scripts.

Join us on Discord!

Read this book alongside other users, Unity game development experts, and the author himself.

Ask questions, provide solutions to other readers, chat with the author via Ask Me Anything sessions, and much more.

Scan the QR code or visit the link to join the community.

https://packt.link/handsonunity22

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset