Here’s the code I attached to one of my game objects:
class TestNode {
var x : float;
var b : boolean;
var o : GameObject;
};
var nodes : TestNode[];
var maxNodes : int = 5;
function Start () {
nodes = new TestNode[maxNodes];
PrintNodes ( "At Start ()" );
}
function Update () {
PrintNodes ( "At Update ()" );
}
function PrintNodes ( prefix : String ) {
var s : String;
if ( prefix != "" ) s += prefix + "\n";
for ( var i : int = 0; i < nodes.length; ++i ) {
s += " nodes[" + i + "] is " + ( nodes[i] == null? "" : "not" ) + " null";
if ( i < nodes.length - 1 )
s += ",";
}
Debug.Log ( s );
}
When run, I got results like this:
At Start ()
nodes[0] is null, nodes[1] is null, nodes[2] is null, nodes[3] is null, nodes[4] is null
At Update ()
nodes[0] is not null, nodes[1] is not null, nodes[2] is not null, nodes[3] is not null, nodes[4] is not null
At Start… each node is null.
But in Update… they’re not null.
Is there something wrong with this?
For some reason, static arrays of objects like that aren’t available the frame they’re created. If you look, you should see that the first Update() says “null” while the others say “not null”. For example, this produces an error:
function Start () {
nodes = new TestNode[maxNodes];
nodes[0].x = 0.5;
}
But this works:
function Start () {
nodes = new TestNode[maxNodes];
yield;
nodes[0].x = 0.5;
}
If you use a dynamic Javascript array instead, then this problem goes away. Yes, it seems kinda weird…
–Eric
In C#, when you create an array of reference types, it starts out with the size you ask for but contains nothing but null references. You then have to fill it out by creating objects for each of the elements. This is intentional, as the language has no way of knowing whether or not you really want all of the elements filling out.
I’m not positive that I know Javascript’s behaviour well enough to say for sure, but I’d expect it to do the same thing, since its built-in arrays are the same .NET class as C#'s built-in arrays. If the objects are mysteriously getting filled in later on, I suspect that that’s Unity’s doing. I’m not sure if that’s an error or not… it seems rather inconsistent.
Here’s an example, in Javascript, of how I’d expect to have to create and fill out this kind of array:
var nodes : TestNode[];
var maxNodes : int = 5;
...
nodes = new TestNode[maxNodes];
for(index = 0; index < maxNodes; ++index)
{
nodes[index] = new TestNode();
}
Thanks everyone.
Actually, when I create an array, I always “new” each element immediately, like NCarter does…
But I never know that if I wait for the next frame, using the keyword yield, I don’t have to “new” them.
… So this is one of the weird cases in Javascript …