Behavior Scripting in C# and Javascript for game developers

0
1829
16 min read

The common idea about game behaviors – things like enemy AI, or sequences of events, or the rules of a puzzle – are expressed in a scripting language, probably in a simple top-to-bottom recipe form, without using objects or much branching. Behaviour scripts are often associated with an object instance in game code – expressed in an object-oriented language such as C++ or C# – which does the work.

In today’s post, we will introduce you to new classes and behavior scripts. The details of a new C# behavior and a new JavaScript behavior are also covered.

We will further explore:

  • Wall attack
  • Declaring public variables
  • Assigning scripts to objects
  • Moving the camera

To take your first steps into programming, we will look at a simple example of the same functionality in both C# and JavaScript, the two main programming languages used by Unity developers.


It is also possible to write Boo-based scripts, but these are rarely used except by those with existing experience in the language.

To follow the next steps, you may choose either JavaScript or C#, and then continue with your preferred language.

To begin, click on the Create button on the Project panel, then choose either JavaScript or C# script, or simply click on the Add Component button on the Main CameraInspector panel.

Your new script will be placed into the Project panel named NewBehaviourScript, and will show an icon of a page with either JavaScript or C# written on it. When selecting your new script, Unity offers a preview of what is already in the script, in the view of the Inspector, and an accompanying Edit button that when clicked on will launch the script into the default script editor, MonoDevelop. You can also launch a script in your script editor at any time by double-clicking on its icon in the Project panel.

New behaviour script or class

New scripts can be thought of as a new class in Unity terms. If you are new to programming, think of a class as a set of actions, properties, and other stored information that can be accessed under the heading of its name.

For example, a class called Dogmay contain properties such as color, breed, size, or genderand have actions such as rolloveror fetchStick. These properties can be described as variables, while the actions can be written in functions, also known as methods.

In this example, to refer to the breedvariable, a property of the Dogclass, we might refer to the class it is in, Dog, and use a period (full stop) to refer to this variable, in the following way:

Dog.breed;

If we want to call a function within the Dogclass, we might say, for example, the following:

Dog.fetchStick();

We can also add arguments into functions-these aren’t the everyday arguments we have with one another! Think of them as more like modifying the behavior of a function, for example, with our fetchStickfunction, we might build in an argument that defines how quickly our dog will fetch the stick. This might be called as follows:

Dog.fetchStick(25);

While these are abstract examples, often it can help to transpose coding into commonplace examples in order to make sense of them. As we continue, think back to this example or come up with some examples of your own, to help train yourself to understand classes of information and their properties.

When you write a script in C# or JavaScript, you are writing a new class or classes with their own properties (variables) and instructions (functions) that you can call into play at the desired moment in your games.

What’s inside a new C# behaviour

When you begin with a new C# script, Unity gives you the following code to get started:

usingUnityEngine;

usingSystem.Collections;

publicclassNewBehaviourScript:MonoBehaviour{
//UsethisforinitializationvoidStart(){
}

//UpdateiscalledonceperframevoidUpdate(){
}
}

This begins with the necessary two calls to the Unity Engine itself:

usingUnityEngine;
usingSystem.Collections;

It goes on to establish the class named after the script. With C#, you’ll be required to name your scripts with matching names to the class declared inside the script itself. This is why you will see publicclassNewBehaviourScript:MonoBehaviour{at the beginning of a new C# document, as NewBehaviourScriptis the default name that Unity gives to newly generated scripts. If you rename your script in the Project panel when it is created, Unity will rewrite the class name in your C# script.

Code in classes

When writing code, most of your functions, variables, and other scripting elements will be placed within the class of a script in C#. Within-in this context-means that it must occur after the class declaration, and following the corresponding closing }of that, at the bottom of the script. So, unless told otherwise, while following the instructions, assume that your code should be placed within the class established in the script. In JavaScript, this is less relevant as the entire script is the class; it is not explicitly established.

Basic functions

Unity as an engine has many of its own functions that can be used to call different features of the game engine, and it includes two important ones when you create a new script in C#.

Functions (also known as methods) most often start with the voidterm in C#. This is the function’s return type, which is the kind of data a function may result in. As most functions are simply there to carry out instructions rather than return information, often you will see voidat the beginning of their declaration, which simply means that a certain type of data will not be returned.

Some basic functions are explained as follows:

  • Start(): This is called when the scene first launches, so it is often used as it is suggested in the code, for initialization. For example, you may have a core variable that must be set to 0when the game scene begins or perhaps a function that spawns your player character in the correct place at the start of a level.
  • Update(): This is called in every frame that the game runs, and is crucial for checking the state of various parts of your game during this time, as many different conditions of game objects may change while the game is running.

Variables in C#

To store information in a variable in C#, you will use the following syntax:

typeOfDatanameOfVariable=value;

Consider the following example:

intcurrentScore=5;

Another example would be:

floatcurrentVelocity=5.86f;

Note that the examples here show numerical data, with intmeaning integer, that is, a whole number, and floatmeaning floating point, that is, a number with a decimal place, which in C# requires a letter fto be placed at the end of the value. This syntax is somewhat different from JavaScript. Refer to the Variables in JavaScript section.

What’s inside a new JavaScript behaviour?

While fulfilling the same functions as a C# file, a new empty JavaScript file shows you less as the entire script itself is considered to be the class, and the empty space in the script is considered to be within the opening and closing of the class, as the class declaration itself is hidden.

You will also note that the lines usingUnityEngine;and usingSystem. Collections;are also hidden in JavaScript, so in a new JavaScript, you will simply be shown the Update()function:

functionUpdate(){
}

You will note that in JavaScript, you declare functions differently, using the term functionbefore the name. You will also need to write a declaration of variables and various other scripted elements with a slightly different syntax. We will look at examples of this as we progress.

Variables in JavaScript

The syntax for variables in JavaScript works as follows, and is always preceded by the prefix var, as shown:

varvariableName:TypeOfData=value;

For example:

varcurrentScore:int=0;

Another example is:

varcurrentVelocity:float=5.86;

As you must have noticed, the floatvalue does not require a letter ffollowing its value as it does in C#. You will notice as you see further, comparing the scripts written in the two different languages that C# often has stricter rules about how scripts are written, especially regarding implicitly stating types of data that are being used.

Comments

In both C# and JavaScript in Unity, you can write comments using:

//twoforwardslashessymbolsforasinglelinecomment

Another way of doing this would be:

/*forward-slash,startoopenamultilinecommentsandattheendofit,star,forward-slashtoclose*/

You may write comments in the code to help you remember what each part does as you progress. Remember that because comments are not executed as code, you can write whatever you like, including pieces of code. As long as they are contained within a comment they will never be treated as working code.

Wall attack

Now let’s put some of your new scripting knowledge into action and turn our existing scene into an interactive gameplay prototype. In the Project panel in Unity, rename your newly created script Shooterby selecting it, pressing return (Mac) or F2 (Windows), and typing in the new name.

If you are using C#, remember to ensure that your class declaration inside the script matches this name of the script:

publicclassShooter:MonoBehaviour{

As mentioned previously, JavaScript users will not need to do this. To kick-start your knowledge of using scripting in Unity, we will write a script to control the camera and allow shooting of a projectile at the wall that we have built.

To begin with, we will establish three variables:

  • bullet: This is a variable of type Rigidbody, as it will hold a reference to a physics controlled object we will make
  • power: This is a floating point variable number we will use to set the power of shooting
  • moveSpeed: This is another floating point variable number we will use to define the speed of movement of the camera using the arrow keys

These variables must be public member variables, in order for them to display as adjustable settings in the Inspector. You’ll see this in action very shortly!

Declaring public variables

Public variables are important to understand as they allow you to create variables that will be accessible from other scripts-an important part of game development as it allows for simpler inter-object communication. Public variables are also really useful as they appear as settings you can adjust visually in the Inspector once your script is attached to an object. Private variables are the opposite-designed to be only accessible within the scope of the script, class, or function they are defined within, and do not appear as settings in the Inspector.

C#

Before we begin, as we will not be using it, remove the Start()function from this script by deleting voidStart(){}. To establish the required variables, put the following code snippet into your script after the opening of the class, shown as follows:

usingUnityEngine;
usingSystem.Collections;
publicclassShooter:MonoBehaviour{
publicRigidbodybullet;publicfloatpower=1500f;publicfloatmoveSpeed=2f;
voidUpdate(){
}
}

Note that in this example, the default explanatory comments and the

Start()function have been removed in order to save space.

JavaScript

In order to establish public member variables in JavaScript, you will need to simply ensure that your variables are declared outside of any existing function. This is usually done at the top of the script, so to declare the three variables we need, add the following to the top of your new Shooterscript so that it looks like this:

varbullet:Rigidbody;varpower:float=1500;varmoveSpeed:float=5;functionUpdate(){
}

Note that JavaScript (UnityScript) is much less declarative and needs less typing to start.

Assigning scripts to objects

In order for this script to be used within our game it must be attached as a component of one of the game objects within the existing scene.

Save your script by choosing File | Save from the top menu of your script editor and return to Unity. There are several ways to assign a script to an object in Unity:

  1. Drag it from the Project panel and drop it onto the name of an object in the Hierarchy panel.
  2. Drag it from the Project panel and drop it onto the visual representation of the object in the Scene panel.
  3. Select the object you wish to apply the script to and then drag and drop the script to empty space at the bottom of the Inspector view for that object.
  4. Select the object you wish to apply the script to and then choose Component | Scripts | and the name of your script from the top menu.

The most common method is the first approach, and this would be most appropriate since trying to drag to the camera in the Scene View, for example, would be difficult as the camera itself doesn’t have a tangible surface to drag to.

For this reason, drag your new Shooterscript from the Project panel and drop it onto the name of Main Camera in the Hierarchy to assign it, and you should see your script appear as a new component, following the existing audio listener component. You will also see its three public variables such as bullet, power, and moveSpeedin the Inspector, as follows:

You can alternatively act in the Inspector, directly, press the Add Component button, and look for Shooterby typing in the search box. Note, this is valid if you didn’t add the component in this way initially. In that case, the Shootercomponent will already be attached to the camera GameObject.

As you will see, Unity has taken the variable names and given them capital letters, and in the case of our moveSpeedvariable, it takes a capital letter in the middle of the phrase to signify the start of a new word in the Inspector, placing a space between the two words when seen as a public variable.

You can also see here that the bulletvariable is not yet set, but it is expecting an object to be assigned to it that has a Rigidbody attached-this is often referred to as being a Rigidbody object. Despite the fact that, in Unity, all objects in the scene can be referred to as game objects, when describing an object as a Rigidbodyobject in scripting, we will only be able to refer to properties and functions of the Rigidbodyclass. This is not a problem however; it simply makes our script more efficient than referring to the entire GameObjectclass. For more on this, take a look at the script reference documentation for both the classes:

GameObject

Rigidbody

Beware that when adjusting values of public variables in the Inspector, any values changed will simply override those written in the script, rather than replacing them.

Let’s continue working on our script and add some interactivity; so, return to your script editor now.

Moving the camera

Next, we will make use of the moveSpeedvariable combined with keyboard input in order to move the camera and effectively create a primitive aiming of our shot, as we will use the camera as the point to shoot from.

As we want to use the arrow keys on the keyboard, we need to be aware of how to address them in the code first. Unity has many inputs that can be viewed and adjusted using the Input Manager-choose Edit | Project Settings | Input:

As seen in this screenshot, two of the default settings for input are Horizontal and Vertical. These rely on an axis-based input that, when holding the Positive Button, builds to a value of 1, and when holding the Negative Button, builds to a value of -1. Releasing either button means that the input’s value springs back to 0, as it would if using a sprung analog joystick on a gamepad.

As input is also the name of a class, and all named elements in the Input Manager are axes or buttons, in scripting terms, we can simply use:

Input.GetAxis("Horizontal");

This receives the current value of the horizontal keys, that is, a value between -1 and 1, depending upon what the user is pressing. Let’s put that into practice in our script now, using local variables to represent our axes.

By doing this, we can modify the value of this variable later using multiplication, taking it from a maximum value of 1 to a higher number, allowing us to move the camera faster than 1 unit at a time.

This variable is not something that we will ever need to set inside the Inspector, as Unity is assigning values based on our key input. As such, these values can be established as local variables.

Local, private, and public variables

Before we continue, let’s take an overview of local, private, and public variables in order to cement your understanding:

  • Local variables: These are variables established inside a function; they will not be shown in the Inspector, and are only accessible to the function they are in.
  • Private variables: These are established outside a function, and therefore accessible to any function within your class. However, they are also not visible in the Inspector.
  • Public variables: These are established outside a function, are accessible to any function in their class and also to other scripts, apart from being visible for editing in the Inspector.

Local variables and receiving input

The local variables in C# and JavaScript are shown as follows:

C#

Here is the code for C#:

voidUpdate(){floath=Input.GetAxis("Horizontal")*Time.deltaTime*moveSpeed;floatv=Input.GetAxis("Vertical")*Time.deltaTime*moveSpeed;

JavaScript

Here is the code for JavaScript:

functionUpdate(){varh:float=Input.GetAxis("Horizontal")*Time.deltaTime*moveSpeed;varv:float=Input.GetAxis("Vertical")*Time.deltaTime*moveSpeed;

The variables declared here-hfor Horizontaland vfor Vertical, could be named anything we like; it is simply quicker to write single letters. Generally speaking, we would normally give these a name, because some letters cannot be used as variable names, for example, x, y, and z, because they are used for coordinate values and therefore reserved for use as such. As these axes’ values can be anything from -1 to 1, they are likely to be a number with a decimal place, and as such, we must declare them as floating point type variables. They are then multiplied using the *symbol by Time.deltaTime, which simply means that the value is divided by the number of frames per second (the deltaTimeis the time it takes from one frame to the next or the time taken since the Update()function last ran), which means that the value adds up to a consistent amount per second, regardless of the framerate.

The resultant value is then increased by multiplying it by the public variable we made earlier, moveSpeed. This means that although the values of hand vare local variables, we can still affect them by adjusting public moveSpeedin the Inspector, as it is a part of the equation that those variables represent. This is a common practice in scripting as it takes advantage of the use of publicly accessible settings combined with specific values generated by a function.

You read an excerpt from the book Unity 5.x Game Development Essentials, Third Edition written by Tommaso Lintrami. Unity is the most popular game engine among Indie developers, start-ups, and medium to large independent game development companies. This book is a complete exercise in game development covering environments, physics, sound, particles, and much more—to get you up and running with Unity rapidly.

Unity 2017 Game Development Essentials

Read Next

Scripting Strategies

Unity 3.x Scripting-Character Controller versus Rigidbody

LEAVE A REPLY

Please enter your comment!
Please enter your name here