Unity Coding: Arrays, Hashtables and Dictionaries explained

EggsIn this article I’m going to explain the basic uses of – and differences between – some of the various types of array-like containers you can use in Unity. If you haven’t heard of arrays before, they can be described as a single variable with a series of “compartments”, where each compartment can contain a value. They’re useful if you want to deal with a collection of values or objects together. In a game programming situation, you might use an array to store a reference to every enemy in your scene, or as a container for collected items in the player’s inventory. Arrays can be ‘iterated over’, which is a fancy way of saying that you can go through each item in your array in sequence, and inspect or perform functions on each item in turn.

(This post has been updated to account for new features in Unity 3 which were not present when the article was originally written – namely, support in Unity’s Javascript for generics and 2D arrays).

There are many types of containers, and a few of them use the name “array”, but there are other types too. The broader term “collection” can be used to describe all these types of containers. These are the types of collection that I’ll be describing in this article:

  • Built-in arrays
  • Javascript Arrays
  • ArrayLists
  • Hashtables
  • Generic Lists
  • Generic Dictionaries
  • 2D Arrays

There are other types for more specialised situations, but I have selected these as being some of the basic staples of programming.

Because Unity is built on Mono, which is an open-source implementation of .Net, you have access to most of .Net’s collection types. All of the above types are standard .Net types, with the exception of the “Javascript Array”. The “Javascript Array” is a type which is added into the Unity Engine, and is only available if you’re using the Javascript syntax in Unity – it’s not available if you’re using C#. However, it is essentially just a wrapper for the ArrayList class – which is available in C# – with a different set of functions provided. If you’re coming to Unity having used Javascript or a Javascript-like language (such as ActionScript) elsewhere outside of Unity, it’s important to be aware of these underlying differences, and bear in mind that Unity’s Javascript isn’t “real” Javascript – it’s just .Net with a different syntax laid over the top!

All types of collections share a few common features:

  • You can fill them with objects, and read back the values that you put in.
  • You can ‘iterate’ through them, which means you can create a loop which runs the same piece of code against each item in the collection.
  • You can get the length of the collection.
  • For most collections – but not all – you can arbitrarily add and remove items at any position, and sort their contents.

Below, I describe some of the most common types of collection, along with their pros and cons, and some of their most useful properties and methods.

Built-in Arrays

The most basic type of array, available in both JS and C#, is the built-in array. The main shortcoming of built-in arrays is that they have a fixed-size (which you choose when you declare the array), however this shortcoming is balanced by their very fast performance. For this reason, built-in arrays are the best choice if you need the fastest performance possible from your code (for example, if you’re targeting iPhone). If there is a fixed and known number of items that you want to store, this is the best choice.

It’s also common to use this type of array if you have a varying number of items to store, but you can decide on a ‘maximum’ for the number of objects that you’ll need. You can then leave some of the elements in the array null when they’re not required, and design your code around this. For example, for the bullets in a shooting game, you may decide to use an array of size 50, allowing a maximum of 50 active bullets at any one time.

This type of array is also useful because it’s one of the type osf array which show up in Unity’s inspector window. This means that a built-in array ia good choice if you want to populate its contents in the Unity editor, by dragging and dropping references.

It’s also usually the type of array you get back from Unity functions, if you use a function which may return a number of objects, such as GetComponentsInChildren.

Built-in arrays are declared by specifying the type of object you want to store, followed by brackets. Eg:

Basic Declaration & Use:

C#

 

// declaration
TheType[] myArray = new TheType[lengthOfArray]; 

// declaration example using ints
int[] myNumbers = new int[10];                

// declaration example using GameObjects
GameObject[] enemies = new GameObject[16];      

// get the length of the array
int howBig = myArray.Length;                  

// set a value at position i
myArray[i] = newValue;                        

// get a value from position i
TheType thisValue = myArray[i];

Javascript

 

// declaration
var myArray = new TheType[lengthOfArray];     

// declaration example using ints
var myNumbers = new int[10];                   

// declaration example using GameObjects
var enemies = new GameObject[16];              

// get the length of the array
var howBig = enemies.Length;               

// set a value at position i
myArray[i] = newValue;                     

// get a value from position i
var thisValue = myArray[i]

Full MSDN Documentation for Built-in Array

Some direct links to useful Functions/Methods of Built-in Arrays:

IndexOf, LastIndexOf, Reverse, Sort, Clear, Clone

Javascript Arrays

The ‘Javascript Array’ in unity is a special class that is provided in addition to the standard .net classes. You can only declare them if you are using a Javascript syntax script – you can’t declare them in C#. Javascript arrays are dynamic in size, which means you don’t have to specify a fixed size. You can add and remove items to the array, and the array will grow and shrink in size accordingly. You also don’t have to specify the type of object you want to store. You can put objects of any type into a Javascript array, even mixed types in the same array.

Javascript arrays are therefore somewhat easier to use than built-in arrays, however they are a bit more costly in terms of performance (although performance cost here is only worth worrying about if you are dealing with very large numbers of objects, or if you’re targeting the iPhone). Another potential downside is that there are certain situations where you need to use explicit casting when retrieving items because of their ‘untyped’ nature – despite Javascript’s dynamic typing.

Basic Declaration & Use:
(Javascript Only)

 

// declaration
var myArray = new Array();     

// add an item to the end of the array
myArray.Add(anItem);           

// retrieve an item from position i
var thisItem = myArray[i];     

// removes an item from position i
myArray.RemoveAt(i);           

// get the length of the Array
var howBig = myArray.length;

Full Unity Documentation for Javascript Array

Some direct links to useful Functions/Methods of Unity’s Javascript Arrays:

Concat, Join, Push, Add, Pop, Shift, RemoveAt, Unshift, Clear, Reverse, Sort

ArrayLists

The ArrayList is a .Net class, and is very similar to the Javascript Array mentioned previously, but this time available in both JS and C#. Like JS Arrays, ArrayLists are dynamic in size, so you can add and remove items, and the array will grow and shrink in size to fit. ArrayLists are also untyped, so you can add items of any kind, including a mixture of types in the same ArrayList. ArrayLists are also similarly a little more costly when compared to the blazingly fast performance of built-in arrays. ArrayLists have a wider set of features compared to JS Arrays, although neither of their feature sets completely overlaps the other.

Basic Declaration & Use:

Javascript

 

// declaration
var myArrayList = new ArrayList();    

// add an item to the end of the array
myArrayList.Add(anItem);              

// change the value stored at position i
myArrayList[i] = newValue;            

// retrieve an item from position i
var thisItem : TheType = myArray[i];  (note the required casting!)

// remove an item from position i
myArray.RemoveAt(i);                  

// get the length of the array
var howBig = myArray.Count;

C#

 

// declaration
ArrayList myArrayList = new ArrayList();    

// add an item to the end of the array
myArrayList.Add(anItem);                    

// change the value stored at position i
myArrayList[i] = newValue;                  

// retrieve an item from position i
TheType thisItem = (TheType) myArray[i];    

// remove an item from position i
myArray.RemoveAt(i);                        

// get the number of items in the ArrayList
var howBig = myArray.Count;

Full MSDN Documentation for ArrayList

Some direct links to useful Functions/Methods of the ArrayList:

Add, Insert, Remove, RemoveAt, Clear, Clone, Contains, IndexOf, LastIndexOf, GetRange, SetRange, AddRange, InsertRange, RemoveRange, Reverse, Sort, ToArray

Hashtables

A Hashtable is a type of collection where each item is made up of a “Key and Value” pair. It’s most commonly used in situations where you want to be able to do a quick look-up based on a certain single value. The piece of information that you use to perform the look-up is the ‘key’, and the object that is returned is the “Value”.

If you are familiar with web development, it’s similar to the type of data in a GET or POST request, where every value passed has a corresponding name. With a Hashtable however, both the keys and the values can be any type of object. For most practical applications, it’s usually the case that your keys are going to be all the same type (eg, strings) and your values are likely to be all of the same type too (eg, GameObjects, or some other class instance). As with ArrayLists, because Hashtable keys and values are untyped, you usually have to deal with the type casting yourself when you retrieve values from the collection.

Hashtables are designed for situations where you want to be able to quickly pick out a certain item from your collection, using some unique identifying key – similar to the way you might select a record from a database using an index, or the way you might pick out the contact details of a person using their name as the ‘unique identifier’.

Basic Declaration & Use:

Javascript

 

// declaration
var myHashtable = new Hashtable();                 

// insert or change the value for the given key
myHashtable[anyKey] = newValue;                    

// retrieve a value for the given key
var thisValue : ValueType = myHashtable[theKey];   (note the required type casting)

// get the number of items in the Hashtable
var howBig = myHashtable.Count;                    

// remove the key & value pair from the Hashtable, for the given key.
myHashtable.Remove(theKey);

C#

 

// declaration
Hashtable myHashtable = new Hashtable();                 

// insert or change the value for the given key
myHashtable[anyKey] = newValue;                          

// retrieve a value for the given key
ValueType thisValue = (ValueType)myHashtable[theKey];    

// get the number of items in the Hashtable
int howBig = myHashtable.Count;                          

// remove the key & value pair from the Hashtable, for the given key.
myHashtable.Remove(theKey);

Full MSDN Documentation for Hashtable Members

Some direct links to useful Functions/Methods of the HashTable:

Add, Remove, ContainsKey, ContainsValue, Clear

Generic List

First of all corrections to the original article: Generics are not supported at all on iPhone, (generics are now supported in Unity 3 iOS!). In addition, you can’t declare Generics in unity’s Javascript, (you can now declare generics in Unity 3’s Javascript!).

The Generic List (also known as List) is similar to the JS Array and the ArrayList, in that they have a dynamic size, and support arbitrary adding, getting and removing of items. The significant difference with the Generic List (and all other ‘Generic’ type classes), is that you explicitly specify the type to be used when you declare it – in this case, the type of object that the List will contain.

Once you’ve declared it, you can only add objects of the correct type – and because of this restriction, you get two significant benefits:

  • no need to do any type casting of the values when you come to retrieve them.
  • performs significantly faster than ArrayList

This means that if you were going to create an ArrayList, but you know that you will only be putting objects of one specific type of object into it, (and you know that type in advance) you’re generally better off using a Generic List. For me, this tends to be true pretty much all the time.

The generic collections are not part of the standard System.Collections namespace, so to use them, you need to add a line a the top of any script in which you want to use them:

 

using System.Collections.Generic;

Basic Declaration & Use:

JS:

// declaration
var myList = new List.<Type>();        

// a real-world example of declaring a List of 'ints'
var someNumbers = new List.<int>();   

// a real-world example of declaring a List of 'GameObjects'
var enemies = new List.<GameObject>();       

// add an item to the end of the List
myList.Add(theItem);             

// change the value in the List at position i
myList[i] = newItem;             

// retrieve the item at position i
var thisItem = List[i];         

// remove the item from position i
myList.RemoveAt(i);

C#:

// declaration
List<Type> myList = new List<Type>();        

// a real-world example of declaring a List of 'ints'
List<int> someNumbers = new List<int>();   

// a real-world example of declaring a List of 'GameObjects'
List<GameObject> enemies = new List<GameObject>();       

// add an item to the end of the List
myList.Add(theItem);             

// change the value in the List at position i
myList[i] = newItem;             

// retrieve the item at position i
Type thisItem = List[i];         

// remove the item from position i
myList.RemoveAt(i);

Full MSDN Documentation for Generic List

Some direct links to useful Methods of the Generic List:

Add, Insert, Remove, RemoveAll, RemoveAt, Contains, IndexOf, LastIndexOf, Reverse, Sort, Clear, AddRange, GetRange, InsertRange, RemoveRange, ToArray

Generic Dictionary

This is another Generic class, so the same restrictions used to apply (unsupported on iPhone, and not declarable in Unity’s Javascript). And the same corrections now stand: Since Unity 3, generics are now supported in Unity iOS and in Unity’s Javascript!.

The Generic Dictionary is to the Hashtable what the Generic List is to the ArrayList. The Generic Dictionary provides you with a structure for quickly looking up items from a collection (like the Hashtable), but it differs from the Hashtable in that you must specify explictly the types for the Keys and Values up-front, when you declare it. Because of this, you get similar benefits to those mentioned in the Generic List. Namely, no annoying casting needed when using the Dictionary, and a significant performance increase compared to the Hashtable.

Because you need to specify the types for both the Keys and the Values, the declaration line can end up a little long and wordy. However, once you’ve overcome this they are great to work with!

Again, to use this, you’ll need to include the Generic Collections package by including this line at the top of your script:

 

using System.Collections.Generic;

Basic Declaration & Use:

JS:

// declaration:
var myDictionary = new Dictionary.<KeyType,ValueType>();

// and a real-world declaration example (where 'Person' is a custom class):
var myContacts = new Dictionary.<string,Person>();

// insert or change the value for the given key
myDictionary[anyKey] = newValue;                 

// retrieve a value for the given key
var thisValue = myDictionary[theKey];      

// get the number of items in the Hashtable
var howBig = myDictionary.Count;                 

// remove the key & value pair from the Hashtable, for the given key.
myDictionary.Remove(theKey);

C#:

// declaration:
Dictionary<KeyType,ValueType> myDictionary = new Dictionary<KeyType,ValueType>();

// and a real-world declaration example (where 'Person' is a custom class):
Dictionary<string,Person> myContacts = new Dictionary<string,Person>();

// insert or change the value for the given key
myDictionary[anyKey] = newValue;                 

// retrieve a value for the given key
ValueType thisValue = myDictionary[theKey];      

// get the number of items in the Hashtable
int howBig = myDictionary.Count;                 

// remove the key & value pair from the Hashtable, for the given key.
myDictionary.Remove(theKey);

Full MSDN Documentation for Dictionary(TKey,TValue)

Some direct links to useful Methods of the Generic Dictionary:

Add, Remove, ContainsKey, ContainsValue, Clear

2D Array

So far, all the examples of Arrays and Collections listed above have been one-dimensional structures, but there may be an occasion where you need to place data into an array with more dimensions. A typical game-related example of this is a tile-based map. You might have a ‘map’ array which should have a width and a height, and a piece of data in each cell which determines the tile to display. It is also possible to have arrays with more than two dimensions, such as a 3D array or a 4D array – however if you have a need for a 3D or 4D array, you’re probably advanced enough to not require an explanation of how to use them!

There are two methods of implementing a multi-dimensional array. There are “real” multi-dimensional arrays, and there are “Jagged” arrays. The difference is this:

With a “real” 2D array, your array has a fixed “width” and “height” (although they are not called width & height). You can refer to a location in your 2d array like this: myArray[x,y].

In contrast, “Jagged” arrays aren’t real 2D arrays, because they are created by using nested one-dimensional arrays. In this respect, what you essentially have is a one-dimensional outer array which might represent your ‘rows’, and each item contained in this outer array is actually an inner array which represents the cells in that row. To refer to a location in a jagged array, you would typically use something like this: myArray[y][x].

Usually, “real” 2D arrays are preferable, because they are simpler to set up and work with, however there are some valid cases for using jagged arrays. Such cases usually make use of the fact that – with a jagged array – each ‘inner’ array doesn’t have to be the same length (hence the origin of the term “jagged”).

Another important correction is that Unity’s Javascript used to have no support for creating 2D arrays – however since Unity 3.2, Unity’s JS now supports this.

Basic Declaration & Use of “real” 2D arrays:

JS:

// declaration:

// a 16 x 4 array of strings
var myArray = new string[16,4];            

// and a real-world declaration example (where 'Tile' is a user-created custom class):

// create an array to hold a map of 32x32 tiles
var map = new Tile[32,32];                   

// set the value at a given location in the array
myArray[x,y] = newValue;                         

// retrieve a value from a given location in the array
var thisValue = myArray[x,y];              

// get the length of 1st dimension of the array
var width = myArray.GetUpperBound(0);            

// get the length of 2nd dimension of the array
var length = myArray.GetUpperBound(1);

 

C#:

// declaration:

// a 16 x 4 array of strings
string[,] myArray = new string[16,4];            

// and a real-world declaration example (where 'Tile' is a user-created custom class):

// create an array to hold a map of 32x32 tiles
Tile[,] map = new Tile[32,32];                   

// set the value at a given location in the array
myArray[x,y] = newValue;                         

// retrieve a value from a given location in the array
ValueType thisValue = myArray[x,y];              

// get the length of 1st dimension of the array
int width = myArray.GetUpperBound(0);            

// get the length of 2nd dimension of the array
int length = myArray.GetUpperBound(1);

 


While I’ve covered some of the basic code for declaring and using each of the types of collections above, I haven’t given examples of code to show how these collections can be iterated over, perform actions on each item in the collection. For more information on how to do this for each type of collection, follow the “full documentation” links that I’ve provided above for each type, where you’ll find sample code showing this.

If you’re still with me, well done for reading this far! I hope you’ve found this article useful. Let me know if you have any suggestions to make it better.

- Ben

About these ads

39 Responses to “Unity Coding: Arrays, Hashtables and Dictionaries explained”

  1. Hey Ben, thank you for this post – just skimmed it at this point but will devour it after work. 1st observation: thank you for including both java and c# implementations; coming from AS3 background – Javascript is a natural fit, although I get the feeling most ppl prefer the C# path – its nice to see both. Awesome info – keep it coming!

  2. Social comments and analytics for this post…

    This post was mentioned on Twitter by robotduck: New blog post – “Unity Coding: Arrays, Hashtables and Dictionaries explained” – http://robotduck.wordpress.com/2009/11/04/88/

  3. In iPhone Unity, in a javascript script I tried your example for builtin arrays:

    var myArray = int[10];

    and I get the error:

    Type ‘System.Type’ does not support slicing.

    Any idea what the problem could be?

    • Hi James,

      This was an error in my original post. The javascript syntax for declaring a built-in array requires the ‘new’ keyword too. Like this:
      var myArray = new int[10];

      sorry for the confusion!

  4. herman.tulleken Says:

    Nice and useful post.

    Perhaps you could also show the syntax for doing declaration and initialisation in one step (especially in the more complicated case of nested arrays) – I am struggling with that right now…

  5. Nice writeup that I just scanned through as a longtime flash developer now doing lots of C# (.net backend stuff). I’m definitely interested in checking out Unity to hopefully combine my skills…

    It seems to me that all of the angled brackets and their contents have been lost in your generics examples though? Unless things are different in Unity but I can’t see how it could know the generic type in your examples above…

    • Hi Kelvin, you’re right, seems like they vanished! They’re back now. thanks for the heads-up :)

  6. Thanks! Just one tip: the sourcecode is very hard to read (gray on black). Maybe you could change it for your readers.

  7. John Crawford Says:

    Good article. It definitely had me thinking about better ways of doing Unity programming. For instance, although I understand C# arrays, it hadn’t occurred to me that I could make them accessible to the Unity Inspector for population.

    Cyclops.

  8. Darcie Clements Says:

    I just wanted to thank you for summarizing all these data in one place like this. It’s been an invaluable reference in choosing which format to use and when with my AI project.

  9. John Crawford Says:

    As I said, I love the article. But I have to mention that the website format is (for me) highly unreadable – white text on black background is just painful. :( Fortunately Opera has the option to override page-setting, although then I lose all formatting.

    Cyclops

  10. The dark gray on black is killing my eyes. ;)

  11. Great post, really useful :)
    By the way, you seem to have included the C# 2D array example twice.

    It’s really useful to see both C# and JS examples here, I’m sure this information is a great benefit to people getting started, or indeed those pretty experienced with Unity.

  12. beloto Says:

    Thank you very much.
    Exactly what i needed to know :P

  13. Great post. Thanks for sharing this.

  14. I made an 2D array using c#
    public GameObject[,] myArray = new GameObject[200,200];
    When I am running the program it’s not shown in the inspector window. Normal public arrays are showing there. Any ideas why its not showing up?
    Thanks!

  15. Chief1234 Says:

    This is a great post – but it does need updating:

    You can now declare dictionaries (and other generics) in Javascript:

    var dic : Dictionary. = new Dictionary.();

    Just remember that dot before the angle brackets and it’s all good.

    • I have finally got around updated the article to include the new support in Javascript for generics and 2D arrays. Sorry for the delay!

  16. Chief1234 Says:

    oops – my angle brackets got killed…

    Here it is again. Change the square brackets to angle brackets –
    This is a great post – but it does need updating:

    You can now declare dictionaries (and other generics) in Javascript:

    var dic : Dictionary.[Texture2D, boolean] = new Dictionary.[Texture2D, boolean]();

    Just remember that dot before the angle brackets and it’s all good.

  17. Dude, really big THANKS for this. I have finally understood how arrays in JS work. Now i can continue programming my little game ;)

  18. [...] is a bit like an array, however it stores key/value pairs rather than a simple list of values. (Read more about Dictionaries and other types of arrays and collections in Unity here). The “key” is the string ID that you choose, and the “value” is an [...]

  19. Veliremus Says:

    Hey, great article! But shouldn’t it be

    import System.Collections.Generic;”

    for Javascript, in stead of …?

    using System.Collections.Generic;

    • Yes, that’s right. “using” is for C#, “import” is the Javascript equivalent.

      • Veliremus Says:

        It could be good to mention that in the tutorial. I spent many hours looking for what I did wrong, and it turned out to be that particular mistake. Do with it what you will :).

  20. Hi, I have session which contain hashtable. When I access t hat session in javascript it assign ‘System.Collections.Hashtable’ value instead of original hashtable.
    Example:
    var myHashtable = (”);
    after that myHashtable variable contain ‘System.Collections.Hashtable’ value.

    What should I do? Please reply

  21. Awesome rundown! This should be part of Unity’s standard reference. It can be so difficult to find articulate explanations of concepts that are written in plain english, are complete, and provide examples/context.

    Thanks so much for making this available to us!

  22. Great post. Javascript having a hashtable really helped out with a project i’m currently involved in. I’m glad I ran across this page

  23. PéPé Says:

    It’s difficult to understand the differences between this arrays, and your post is like a light at bottom of a whole. ( sorry i’m french speaker ). Same with Google traduction i understand ! Thank you very much !

  24. Akkuschrauber Makita…

    [...]Unity Coding: Arrays, Hashtables and Dictionaries explained « robotduck[...]…

  25. [...] Hier findet ihr Bens Artikel: Unity Coding: Arrays, Hashtables and Dictionaries explained. [...]

  26. Interpretariat…

    [...]Unity Coding: Arrays, Hashtables and Dictionaries explained « robotduck[...]…

  27. janoonk Says:

    Could you please update your stylesheet/colors. It’s hard to read especially the code parts. Nonetheless great site!

  28. janoonk Says:

    Could you please update your stylesheet/colors? The text is hard to read especially the code parts. Also the size of the font is too small for the code parts.
    Nonetheless great site!

  29. Thanks for your help, clear and concise.

  30. [...] This link has a good article about Unity’s arrays, hash tables and dictionaries. Keep in mind! This entry was posted in thoughts by volkanongun. Bookmark the permalink. [...]

  31. Hi – is it possible to declare a 2d array in JS with different types? i.e. I need a 2d array where the first dimension is an int and the second dimension is a GameObject.

    var turrets [int, GameObject];

    or similar…

  32. nuverian Says:

    That’s been very usefull. Thank you

  33. harry Says:

    nice post

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 41 other followers

%d bloggers like this: