Search Unity

Beginner topic: Trying to Understand a script error ~NULL REFERENCE EXCEPTION(SOLVED)

Discussion in 'Scripting' started by drt_t1gg3r, Sep 9, 2017.

  1. drt_t1gg3r

    drt_t1gg3r

    Joined:
    Sep 2, 2017
    Posts:
    6
    THE CODE
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. [System.Serializable]
    4. public class ColorToPrefab {
    5.  
    6.     public Color32 color;
    7.     public GameObject prefab;
    8.     public int index;
    9.     public string name;
    10. }
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class LevelGenerator : MonoBehaviour {
    4.  
    5.     public Texture2D map;
    6.  
    7.     public ColorToPrefab[] colorMappings;
    8.  
    9.     GameObject[,]prefabTileMap;
    10.  
    11.     void Start () {
    12.         GenerateLevel();
    13.     }
    14.  
    15.     void GenerateLevel ()
    16.     {
    17.         Color32[] pColor = map.GetPixels32 ();
    18.         int w = map.width;
    19.         int h = map.height;
    20.         for (int x = 0; x < w; x++)
    21.         {
    22.             for (int y = 0; y < h; y++)
    23.             {
    24.                 Debug.Log ("* * * * *   GeneratingTile --> x: " + x + ", y: " + y+"    * * * * *");
    25.                 int index = x + y * w;
    26.                 GenerateTile(pColor[index],x, y);
    27.             }
    28.         }
    29.     }
    30.  
    31.     void GenerateTile (Color32 color, int x, int y)
    32.     {
    33.         Debug.Log ("c: "+color);
    34.         if (color.a == 0) {
    35.             // The pixel is a path. Let's ignore it!
    36.             Debug.Log("PATH FOUND -RETURN-");
    37.             prefabTileMap [x, y] = null;
    38.             return;
    39.         }
    40.  
    41.         foreach (ColorToPrefab colorMapping in colorMappings)
    42.         {
    43.             Debug.Log ("ColorMapping.color: "+colorMapping.prefab.name);
    44.             if (colorMapping.color.Equals(color))
    45.             {
    46.                 Debug.Log ("ColorMapping.color == pixelColor --> CREATING OBJECT");
    47.                 Vector3 position = new Vector3(x, 1, y);
    48.                 GameObject go = (GameObject)Instantiate (colorMapping.prefab, position, Quaternion.identity, transform);
    49.  
    50.                 prefabTileMap [x, y] = go; // THIS IS WHERE ERROR OCCURS
    51.                 GridIndex gi = go.GetComponent<GridIndex> ();
    52.                 gi.indexX = x;
    53.                 gi.indexY = y;
    54.                 return;
    55.             }
    56.         }
    57.     }
    58.  
    59. }
    60.  
    THE ERROR
    DESCRIPTION:
    I'm trying to understand why I got the error. The list ColorToPrefab has a color, and a prefab tied to it as you can see in the code above.
     
    Last edited: Sep 9, 2017
  2. Scabbage

    Scabbage

    Joined:
    Dec 11, 2014
    Posts:
    268
    In C# you have two data types, a reference type and a value type.

    Classes (like GameObject) are reference types, structs (Vector3, Color) and primitives (int, double, float) are value types.

    When you pass a value type into a method, you give it the value, not the object itself. The value of an int will be copied and given to the method.

    With reference types, a variable storing one points to the object in memory (usually on the heap). When you give it to a method you give the method a pointer to the object, so both the caller and the callee are using the exact same object.

    This also means a reference type can be null, ie pointing to nothing. A NRE is when you try to use a value from an object that doesn't exist.

    First check what value is null so you can find out why it is. Just put:

    Code (CSharp):
    1. print(prefabTileMap ==null ? "tilemap is null" : "tilemap is instantiated");
    2. print(go == null ? "go is null" : "go is instantiated");
    I'm betting on it being the tilemap not being created, I can't see an instantiation anywhere in your script.
     
    drt_t1gg3r likes this.
  3. drt_t1gg3r

    drt_t1gg3r

    Joined:
    Sep 2, 2017
    Posts:
    6
    Code (CSharp):
    1. GameObject[,] prefabTileMap;
    on line 9 is where I declare it. I assumed that the array would be initialized with "null" pointers by default. But I'm not trying to GET the value inside an array, I'm trying to SET a value in the array. I would understand the error if I were referencing a value from the array, but I'm trying to set a value to the array.
     
  4. drt_t1gg3r

    drt_t1gg3r

    Joined:
    Sep 2, 2017
    Posts:
    6
    Okay, I see why I got the error. The prefabTileMap variable was "NULL" value. I assumed the reference variable would have been initialized and then filled with "NULL" values for it's cells. But just declaring the prefabTileMap only saved space I guess and did not assign it anything.

    So, I added in
    Code (CSharp):
    1. prefabTileMap=new GameObject[w,h];
    inside the GenerateLevel script and the code works fine. Crazy how things have to be put together.
     
    Last edited: Sep 9, 2017
  5. Scabbage

    Scabbage

    Joined:
    Dec 11, 2014
    Posts:
    268
    You ARE referencing a value from the array. Arrays are reference types, and like I said:
    In the case of a null array, you're accessing the nth element of... what? The array doesn't exist yet! Bork, throw a NRE.

    Good to see you got it sorted anyway, there is a difference between declaration and assignment ;p