Search Unity

Null Object ?!

Discussion in 'Scripting' started by charlotte, Mar 5, 2008.

  1. charlotte

    charlotte

    Joined:
    Jan 28, 2008
    Posts:
    11
    Here's the code I attached to one of my game objects:
    Code (csharp):
    1.  
    2. class TestNode {
    3.     var x : float;
    4.     var b : boolean;
    5.     var o : GameObject;
    6. };
    7.  
    8. var nodes : TestNode[];
    9. var maxNodes : int = 5;
    10.  
    11. function Start () {
    12.     nodes = new TestNode[maxNodes];
    13.    
    14.     PrintNodes ( "At Start ()" );
    15. }
    16.  
    17. function Update () {
    18.     PrintNodes ( "At Update ()" );
    19. }
    20.  
    21. function PrintNodes ( prefix : String ) {
    22.     var s : String;
    23.    
    24.     if ( prefix != "" ) s += prefix + "\n";
    25.    
    26.     for ( var i : int = 0; i < nodes.length; ++i ) {
    27.         s += " nodes[" + i + "] is " + ( nodes[i] == null? "" : "not" ) + " null";
    28.        
    29.         if ( i < nodes.length - 1 )
    30.             s += ",";
    31.     }
    32.    
    33.     Debug.Log ( s );
    34. }
    35.  

    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?
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    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:

    Code (csharp):
    1. function Start () {
    2.     nodes = new TestNode[maxNodes];
    3.     nodes[0].x = 0.5;
    4. }
    But this works:

    Code (csharp):
    1. function Start () {
    2.     nodes = new TestNode[maxNodes];
    3.     yield;
    4.     nodes[0].x = 0.5;
    5. }
    If you use a dynamic Javascript array instead, then this problem goes away. Yes, it seems kinda weird....

    --Eric
     
  3. NCarter

    NCarter

    Joined:
    Sep 3, 2005
    Posts:
    686
    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:

    Code (csharp):
    1. var nodes : TestNode[];
    2. var maxNodes : int = 5;
    3. ...
    4. nodes = new TestNode[maxNodes];
    5. for(index = 0; index < maxNodes; ++index)
    6. {
    7.     nodes[index] = new TestNode();
    8. }
     
  4. charlotte

    charlotte

    Joined:
    Jan 28, 2008
    Posts:
    11
    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 ...