13 min read

A key ingredient in scripting 3D games with Unity is the ability to work with C# to create arrays, lists, objects and dictionaries within the Unity platform. In this tutorial, we help you to get started with creating arrays, lists, and dictionaries effectively.

Learning C# by Developing Games with Unity 2019

This article is an excerpt from Learning C# by Developing Games with Unity 2017. Read more here. You can also read the latest edition of the book here

An array stores a sequential collection of values of the same type, in the simplest terms. We can use arrays to store lists of values in a single variable. Imagine we want to store a number of student names. Simple! Just create a few variables and name them student1, student2, and so on:

public string student1 = "Greg"; 
public string student2 = "Kate"; 
public string student3 = "Adam"; 
public string student4 = "Mia";

There’s nothing wrong with this. We can print and assign new values to them. The problem starts when you don’t know how many student names you will be storing. The name variable suggests that it’s a changing element. There is a much cleaner way of storing lists of data.

Let’s store the same names using a C# array variable type:

public string[ ] familyMembers = new string[ ]{"Greg", "Kate", "Adam", "Mia"} ;

As you can see, all the preceding values are stored in a single variable called familyMembers.

Declaring an array

To declare a C# array, you must first say what type of data will be stored in the array. As you can see in the preceding example, we are storing strings of characters. After the type, we have an open square bracket and then immediately a closed square bracket, [ ]. This will make the variable an actual array. We also need to declare the size of the array. It simply means how many places are there in our variable to be accessed. The minimum code required to declare a variable looks similar to this:

public string[] myArrayName = new string[4];

The array size is set during assignment. As you have learned before, all code after the variable declaration and the equal sign is an assignment. To assign empty values to all places in the array, simply write the new keyword followed by the type, an open square bracket, a number describing the size of the array, and then a closed square bracket. If you feel confused, give yourself a bit more time. Then you will fully understand why arrays are helpful. Take a look at the following examples of arrays; don’t worry about testing how they work yet:

string[ ] familyMembers = new string[]{"John", "Amanda", "Chris", "Amber"} ; 
 
string[ ] carsInTheGarage = new string[] {"VWPassat", "BMW"} ; 
 
int[ ] doorNumbersOnMyStreet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; 
 
GameObject[ ] carsInTheScene = GameObject.FindGameObjectsWithTag("car");

As you can see, we can store different types of data as long as the elements in the array are of the same type. You are probably wondering why the last example, shown here, looks different:

GameObject[ ] carsInTheScene = GameObject.FindGameObjectsWithTag("car");

In fact, we are just declaring the new array variable to store a collection of GameObject in the scene using the "car" tag. Jump into the Unity scripting documentation and search for GameObject.FindGameObjectsWithTag:

GameObject

As you can see, GameObject.FindGameObjectsWithTag is a special built-in Unity function that takes a string parameter (tag) and returns an array of GameObjects using this tag.

Storing items in the List

Using a List instead of an array can be so easier to work with in a script. Look at some forum sites related to C# and Unity, and you’ll discover that plenty of programmers simply don’t use an array unless they have to; they prefer to use a List. It is up to the developer’s preference and task. Let’s stick to lists for now.

Here are the basics of why a List is better and easier to use than an array:

  • An array is of fixed size and unchangeable
  • The size of a List is adjustable
  • You can easily add and remove elements from a List
  • To mimic adding a new element to an array, we would need to create a whole new array with the desired number of elements and then copy the old elements

The first thing to understand is that a List has the ability to store any type of object, just like an array. Also, like an array, we must specify which type of object we want a particular List to store. This means that if you want a List of integers of the int type then you can create a List that will store only the int type.

Let’s go back to the first array example and store the same data in a List. To use a List in C#, you need to add the following line at the beginning of your script:

using System.Collections.Generic;

As you can see, using Lists is slightly different from using arrays. Line 9 is a declaration and assignment of the familyMembers List. When declaring the list, there is a requirement for a type of objects that you will be storing in the List. Simply write the type between the < > characters. In this case, we are using string.

As we are adding the actual elements later in lines 14 to 17, instead of assigning elements in the declaration line, we need to assign an empty List to be stored temporarily in the familyMembers variable. Confused? If so, just take a look at the right-hand side of the equal sign on line 9. This is how you create a new instance of the List for a given type, string for this example:

new List<string>();
Unity Engine

Lines 14 to 17 are very simple to understand. Each line adds an object at the end of the List, passing the string value in the parentheses.

In various documentation, Lists of type look like this: List< T >. Here, T stands for the type of data. This simply means that you can insert any type in place of T and the List will become a list of that specific type. From now on, we will be using it.

Common operations with Lists

List<T> is very easy to use. There is a huge list of different operations that you can perform with it. We have already spoken about adding an element at the end of a List. Very briefly, let’s look at the common ones that we will be possibly using at later stages:

  • Add: This adds an object at the end of List<T>.
  • Remove: This removes the first occurrence of a specific object from List<T>.
  • Clear: This removes all elements from List<T>.
  • Contains: This determines whether an element is in List<T> or not. It is very useful to check whether an element is stored in the list.
  • Insert: This inserts an element into List<T> at the specified index.
  • ToArray: This copies the elements of List<T> to a new array.

You don’t need to understand all of these at this stage. All I want you to know is that there are many out-of-the-box operations that you can use. If you want to see them all, I encourage you to dive into the C# documentation and search for the List<T> class.

List <T> versus arrays

Now you are probably thinking, “Okay, which one should I use?” There isn’t a general rule for this. Arrays and List<T> can serve the same purpose. You can find a lot of additional information online to convince you to use one or the other.

Arrays are generally faster. For what we are doing at this stage, we don’t need to worry about processing speeds. Some time from now, however, you might need a bit more speed if your game slows down, so this is good to remember.

List<T> offers great flexibility. You don’t need to know the size of the list during declaration. There is a massive list of out-of-the-box operations that you can use with List, so it is my recommendation. Array is faster, List<T> is more flexible.

Retrieving the data from the Array or List<T>

Declaring and storing data in the array or list is very clear to us now. The next thing to learn is how to get stored elements from an array. To get a stored element from the array, write an array variable name followed by square brackets. You must write an int value within the brackets. That value is called an index. The index is simply a position in the array. So, to get the first element stored in the array, we will write the following code:

myArray[0];

Unity will return the data stored in the first place in myArray. It works exactly the same way as the return type methods. So, if myArray stores a string value on index 0, that string will be returned to the place where you are calling it. Complex? It’s not. Let’s show you by example.

The index value starts at 0, no 1, so the first element in an array containing 10 elements will be accessible through an index value of 0 and last one through a value of 9.

Let’s extend the familyMembers example:

familymembers code

I want to talk about line 20. The rest of it is pretty obvious for you, isn’t it? Line 20 creates a new variable called thirdFamilyMember and assigns the third value stored in the familyMembers list. We are using an index value of 2 instead of 3 because in programming counting starts at 0. Try to memorize this; it is a common mistake made by beginners in programming.

Go ahead and click Play. You will see the name Adam being printed in the Unity Console. While accessing objects stored in an array, make sure you use an index value between zero and the size of the array. In simpler words, we cannot access data from index 10 in an array that contains only four objects. Makes sense?

Checking the size

This is very common; we need to check the size of the array or list. There is a slight difference between a C# array and List<T>.

To get the size as an integer value, we write the name of the variable, then a dot, and then Length of an array or Count for List<T>:

  • arrayName.Length: This returns an integer value with the size of the array
  • listName.Count: This returns an integer value with the size of the list

As we need to focus on one of the choices here and move on, from now on we will be using List<T>.

ArrayList

We definitely know how to use lists now. We also know how to declare a new list and add, remove, and retrieve elements. Moreover, you have learned that the data stored in List<T> must be of the same type across all elements. Let’s throw a little curveball.

ArrayList is basically List<T> without a specified type of data. This means that we can store whatever objects we want. Storing elements of different types is also possible. ArrayList is very flexible.

Take a look at the following example to understand what ArrayList can look like:

ArrayList

You have probably noticed that ArrayList also supports all common operations, such as .Add(). Lines 12 to 15 add different elements into the array. The first two are of the integer type, the third is a string type, and the last one is a GameObject. All mixed types of elements in one variable!

When using ArrayList, you might need to check what type of element is under a specific index to know how to treat it in code. Unity provides a very useful function that you can use on virtually any type of object. Its GetType() method returns the type of the object, not the value. We are using it in lines 18 and 19 to print the types of the second and third elements.

Go ahead, write the preceding code, and click Play. You should get the following output in the Console window:

console window

Dictionaries

When we talk about collection data, we need to mention Dictionaries. A Dictionary is similar to a List. However, instead of accessing a certain element by index value, we use a string called key.

The Dictionary that you will probably be using the most often is called Hashtable. Feel free to dive into the C# documentation after reading this chapter to discover all the bits of this powerful class.

Here are a few key properties of Hashtable:

  • Hashtable can be resized dynamically, like List<T> and ArrayList
  • Hashtable can store multiple data types at the same type, like ArrayList
  • A public member Hashtable isn’t visible in the Unity Inspector panel due to default inspector limitations

I want to make sure that you won’t feel confused, so I will go straight to a simple example:

dictionaries

Accessing values

To access a specific key in the Hashtable, you must know the string key the value is stored under. Remember, the key is the first value in the brackets when adding an element to Hashtable. Ideally, you should also know the type of data you are trying to access. In most cases, that would not be an issue. Take a look at this line:

Debug.Log((string)personalDetails["firstName"]);

We already know that using Debug.Log serves to display a message on the Unity console, so what are we trying to display? A string value (it’s one that can contain letters and numbers), then we specify where that value is stored. In this case, the information is stored under Hashtable personalDetails and the content that we want to display is firstName.

Now take a look at the script once again and see if you can display the age, remember that the value that we are trying to access here is a number, so we should use int instead of string:

Similar to ArrayList, we can store mixed-type data in Hashtable. Unity requires the developer to specify how an accessed element should be treated. To do this, we need to cast the element into a specific data type. The syntax is very simple. There are brackets with the data type inside, followed by the Hashtable variable name. Then, in square brackets, we have to enter the key string the value is stored under. Ufff, confusing!

As you can see in the preceding line, we are casting to string (inside brackets). If we were to access another type of data, for example, an integer number, the syntax would look like this:

(int)personalDetails["age"];

I hope that this is clear now. If it isn’t, why not search for more examples on the Unity forums?

How do I know what’s inside my Hashtable?

Hashtable, by default, isn’t displayed in the Unity Inspector panel. You cannot simply look at the Inspector tab and preview all keys and values in your public member Hashtable.

We can do this in code, however. You know how to access a value and cast it. What if you are trying to access the value under a key that isn’t stored in the Hashtable? Unity will spit out a null reference error and your program is likely to crash.

To check whether an element exists in the Hashtable, we can use the .Contains(object) method, passing the key parameter:

Hashtable

This determines whether the array contains the item and if so, the code will continue; otherwise, it will stop there, preventing any error.

We discussed how to use C# to create arrays, lists, dictionaries and objects in Unity. The code samples and the examples will help you implement these from the platform.

Do check out this book Learning C# by Developing Games with Unity 2017  to develop your first interactive 2D and 3D platform game.

Read More

Unity 2D & 3D game kits simplify Unity game development for beginners

How to create non-player Characters (NPC) with Unity 2018

Game Engine Wars: Unity vs Unreal Engine

3 COMMENTS

  1. Great content!
    There is a problem with arrays (for instance), though, if you’re using Monobehaviour. You cannot add them with the “new” keyword, or you’ll get this error message:
    “You are trying to create a MonoBehaviour using the ‘new’ keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all”.
    This is a problem I’m facing now and still don’t know how to solve it. What would be the best aproach, create a non Monobehavior class and store the array there or use AddComponent()?
    Cheers.

LEAVE A REPLY

Please enter your comment!
Please enter your name here