2D array not working- Null Reference Exception: A null value was found where an object instance was required.

I am attempting to build a 2D grid of tiles. I’m using nested for loops within a coroutine to instantiate each tile and then add the tile to an array. Tiles are prefabs with an attached Tile class script. The Tile class holds information about each tile including it’s position in the grid.

I was previously using a List instead of a 2D array which worked fine at first, until I realised I need to access each Tile using its coordinates.

As far as I can tell the syntax for the array and the instantiation are correct. I’ve tried a few different type casts to be sure. I’ve left the previous list in (commented out) to use as a sanity check to make sure references were working.

The LevelGenerator.cs script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LevelGenerator : MonoBehaviour {    
    // Level grid dimensions
    public int GridSizeX;
    public int GridSizeY;

    // The current position in the grid
    public int GridPosX;
    public int GridPosY;

    // List of tile pieces
    // public List <Tile> levelGrid;

    // 2D array of tile pieces
     public Tile[,] tileArray;
    
    // Critical path values
    public int criticalPathLength = 8;
    public int criticalPathTilesPlaced = 0;

    public bool critPathStarted = false;

    // This stores the grid position of the last critical path tile 
    public int lastCritX;
    public int lastCritY;    

    // Blank tile prefab to be placed
    public Tile blankTile;    
    //=====================================================================================    
	// Use this for initialization
	void Awake ()
    {            
        // Calls the coroutine that buils the level grid
        StartCoroutine(BuildLevelGrid());        
	}
	
	// Update is called once per frame
	void Update ()
    {
         // Instantiate<Tile>(blankTile, new Vector2(GridPosX, GridPosY), transform.rotation);
    }     

    // The level grid is populated here. 
    // There is a pause between placement of each tile for debugging purposes.
    IEnumerator BuildLevelGrid ()
    {          
        // Nested for loops build the grid.
        for (GridPosY = 0; GridPosY < GridSizeY; GridPosY++)
        {
            for (GridPosX = 0; GridPosX < GridSizeX; GridPosX++)
            {
                // Instantiates blank tiles and adds them to the list
                // levelGrid.Add(Instantiate(blankTile, new Vector2(GridPosX, GridPosY), transform.rotation));             
                
                // Populates the array with new tiles
                tileArray[GridPosX, GridPosY] = Instantiate<Tile>(blankTile, new Vector2(GridPosX, GridPosY), transform.rotation);

                // Wait before placing the next tile.
                yield return new WaitForSecondsRealtime(0.2f);                                
            }
        }
    }
}

On play I receive this error:

Null Reference Exception: A null value was found where an object instance was required.
LevelGenerator+c_Iterator0.MoveNext () (at Assets/Scripts/LevelGenerator.cs:64)

Oddly, the Tile prefab is definitely set here. It instantiates one tile and then throws the error.

What I gather from this is that there is an issue while iterating through the nested for loops. It might be possible I’m using values that the 2D array can’t see (should I separate the iterator values from the GridPos variables maybe?).

To test I moved line 64 to the update function (see the commented code there with this line):

// Populates the array with new tiles
tileArray[GridPosX, GridPosY] = Instantiate(blankTile, new Vector2(GridPosX, GridPosY), transform.rotation);

When this line is in the Update function the grid places each tile where it should be, suggesting the iteration in the for loops and the instantiation are both working correctly. This isn’t suitable as it just prints tiles forever and I need to be able to control this.

I haven’t seen this error before so I’m honestly baffled as to how I should fix it.

TLDR:
List instantiates grid of tiles, 2D array doesn’t. Error suggests an issue with the for loop iterators.

@matp86 You are missing array initialization in awake :slight_smile:

void Awake()
    {
        // Calls the coroutine that buils the level grid
        tileArray = new Tile[GridSizeX, GridSizeY];
        StartCoroutine(BuildLevelGrid());
        
    }