Megabite #21 - Working With Simple Arrays

Arrays are an incredibly valuable method of storing variable data in the world of programming, and a great way of accessing that data in very useful ways.  In this article, I want to touch on the basic array options that Unity3d gives you access to, and also explain why you would want to use such things to make your life easier.

Let's say, for example, that you want to store 5 separate pictures as textures.  You can easily make 5 different variables the old fashioned way:

var pic1 : Texture;
var pic2 : Texture;
var pic3 : Texture;
var pic4 : Texture;
var pic5 : Texture;

If you do something like this, however, accessing that data becomes difficult in certain scenarios.  You need to actually declare specific variables within your code, and to use the 5 pictures you end up with a big chunk of non-dynamic code.  For example, if I wanted to make a row out of these variables and they were each roughly 50px X 50px, I would have to do something like this:

function OnGUI() {
     GUI.DrawTexture(Rect(0,0,50,50), pic1);
     GUI.DrawTexture(Rect(0,50,50,50), pic2);
     GUI.DrawTexture(Rect(0,100,50,50), pic3);
     GUI.DrawTexture(Rect(0,150,50,50), pic4);
     GUI.DrawTexture(Rect(0,200,50,50), pic5);
}

For some scenarios, that might be perfect.  In everything, we want to consider the options available to us.  Consider for a minute though all the work that would go into doing something similar for a scope of maybe 20 pictures... or maybe even 100.  Very quickly something like this would get out of hand, and the code would be more susceptible to programming error.

With arrays, we can make one single variable that holds all of your data.  On top of that, we can actually access it dynamically through loops or fancy code.  Unity gives us 2 options when it comes to building arrays in javascript - one is the standard javascript method, and the other is to use the unity inspector to assign the data.  Heck, we can even change the type we choose on the fly to suit our needs, but we can get to that later.

First, we'll use a built-in array.  This array will allow us to use the inspector for easy drag/drop assignment.  To make the variable, we simply use this:

var pic : Texture[];

That's it?  Yep, pretty much.  After you save and compile the script, you end up with something like this in your inspector window.  The variable name "Pic" is there, and it has a size of 0 because we haven't set that number yet.  Let's set it to 5 and see what happens.

Once we set the size, we end up with neat little drag/drop spaces (or you can simply click on the spaces and select your pictures).  This makes it pretty easy to change the order of pictures or replace them on the fly while simply collapsing the variable with the arrow if you no longer need to mess with it.

But how do we use the data?  Well, an array variable is accessible through the key number that you see in the picture.  The first entry is 0, and it progresses upwards form there.  So Pic1-Pic5 from the first example effectively becomes Pic[0] - Pic[4].  Using those brackets is important - it tells unity that we're dealing with an array.

To complete this picture example, I want to point out that the key number of an array is actually an integer when it comes to code.  That's not the case if you just call a variable "Pic1" - that number becomes a string in that regard.  In an array, we can use math to access the different portions of an array, and that's uber-important when it comes to loops like this:

function OnGUI() {
   for (x=0; x < Pic.Length; x++) {
      GUI.DrawTexture(Rect(0,(x * 50), 50, 50), Pic[x]);
   }
}

While this might seem complicated (and it might be if you don't fully understand the FOR loop), the important thing to notice is that the loop will actually run for the length of however many objects are in the "Pic" array.  This means your code will work fine with 5 pictures, but it would also work just as well for 5000 or 5,000,000 pictures.  We've made our code completely dynamic now, and the math allows it to expand as needed.

In some cases, we may not want to work with the inspector at all.  In that event, we may need to make an array on the fly and add to it with code alone.  Commonly this is the case with things such as Vector3s, integers, floats, or other variable types.

Making a blank array variable is easy:

var myArray = new Array();

Heck, we can even start it off with some values pretty easily:

var myArray = new Array(42, 38, 11, 14);

In the above case, myArray[0] would equal 42, myArray[1] = 38, and so on.

One important thing to note is the terminology.  This is commonly referred to as a javascript array.  The javascript array is the only type that can be altered in size through code.  If your array is visible in the inspector, you won't easily be able to change the size and scope of the array without conversion.

The Unity Docs contain a lot of good stuff and examples in the world of js array manipulation, but the common commands to memorize should be:

  • Push
  • Pop
  • Shift
  • RemoveAt

Push is great, especially when you are first creating an array.  If you've just used the "new Array()" command, you can quickly fill it with 50 random numbers by doing something like this:

for (x=0; x<50; x++) {
myArray.Push(Random.Range(0,5000));
}

You'll end up with an array where myArray[0] though myArray[49] exist, each with a random number between 0-5000.  You can use the Pop command to remove the last array entry completely

myArray.Pop();

if you did this, you have myArray[0] though myArray[48] now - the Pop command destroys the last entry in the series.  If you wish to destroy the very first number, tho one currently in the myArray[0] slot, you would use the Shift command:

myArray.Shift();

In doing this, you are deleting that first entry, but everything moves down to fill the space.  You still have one less entry, but the new first number in the array is the one that used to be at myArray[1].  Removing from arrays will always cause the index key to reorganize to fill the blank space.  This is important to realize when working with RemoveAt(), because if you choose to do something like this:

myArray.RemoveAt(39);

Then whatever was at myArray[39] would disappear and everything at 40 or higher would move down to fill the spot.

While for your own purposes you may use arrays to hold integers, you may find it useful to experiment how amazing they are with Transforms, GameObjects, Vector3s, and so forth.  Experimentation will lead you into places you never expected, but through mastery of the basic array, you should be able to perform some extremely dynamic and spectacular functions.