Object reference not set when referencing it and adding to array

Hi.
I am attempting to generate a grid and storing the individual Tiles in a 2 dimensional array. But as soon as I am attempting to access the the tiles in the array I get a “null reference exception” Bellow I have included some of the code, if someone could tell me what I’m doing wrong.

Strip down grid generation script:

public class Grid : MonoBehaviour
{
    public Tile[,] Map;
 
    public int gridWidthInHexes = 10;
    public int gridHeightInHexes = 10;
 
    private void createGrid()
    {
        int tempTileIndex = 0;
        int curMapIndexHeight = 0;
        for (float y = 0; y < gridHeightInHexes; y++)
        {
            int curMapIndexWidth = 0;
            for (float x = 0; x < gridWidthInHexes; x++)
            {
                var hex = (GameObject) Instantiate(Hex);
                var gridPos = new Vector2(x, y);
                var tempTile = hex.GetComponent<Tile>();
                tempTile.TileIndex = tempTileIndex;
                Map[curMapIndexWidth, curMapIndexHeight] = hex.GetComponent<Tile>();
                tempTileIndex++;
                curMapIndexWidth++;
            }
            curMapIndexHeight++;
        }
    }
    private void Start()
    {
        Map = new Tile[gridWidthInHexes,gridHeightInHexes];
        createGrid();
    }
}

Strip down game manager script:

public partial class GameMaster : MonoBehaviour
{
    private Grid grid;
    public GameObject unit;
    void Start()
    {
        grid = gameObject.GetComponent<Grid>();
    }
    void OnMapLoaded()
    {
        Debug.Log(grid.Map[1, 3].TileIndex);
    }
}

The Tile script is not that interesting. It only contains some variables.
Please help.

The Error massage is: NullReferenceException: Object reference not set to an instance of an object
GameMaster.OnMapLoaded () (at Assets/_Scripts/GameMaster.cs:19)
GameMaster._LoadedMap () (at Assets/_Scripts/GameEvents.cs:15)
Grid.Start () (at Assets/_Scripts/Grid.cs:99)

Here are the entire scripts: Grid (should be attached to _GameMaster):

using System.Collections.Generic;
using UnityEngine;

public class Grid : MonoBehaviour
{
    private GameMaster gameMaster;

    //The Map
    
    public Tile[,] Map;

    //following public variable is used to store the hex model prefab;
    
    public GameObject Hex;
    //next two variables can also be instantiated using unity editor
    public int gridWidthInHexes = 10;
    public int gridHeightInHexes = 10;

    //Hexagon tile width and height in game world
    private float hexWidth;
    private float hexHeight;

    //Method to initialise Hexagon width and height
    private void setSizes()
    {
        //renderer component attached to the Hex prefab is used to get the current width and height
        hexWidth = Hex.renderer.bounds.size.x;
        hexHeight = Hex.renderer.bounds.size.z;
    }

    //Method to calculate the position of the first hexagon tile
    //The center of the hex grid is (0,0,0)
    private Vector3 calcInitPos()
    {
        Vector3 initPos;
        //the initial position will be in the left upper corner
        initPos = new Vector3(-hexWidth*gridWidthInHexes/2f + hexWidth/2, 0,
            gridHeightInHexes/2f*hexHeight - hexHeight/2);

        return initPos;
    }

    //method used to convert hex grid coordinates to game world coordinates
    public Vector3 calcWorldCoord(Vector2 gridPos)
    {
        //Position of the first hex tile
        Vector3 initPos = calcInitPos();
        //Every second row is offset by half of the tile width
        float offset = 0;
        if (gridPos.y%2 != 0)
            offset = hexWidth/2;

        float x = initPos.x + offset + gridPos.x*hexWidth;
        //Every new line is offset in z direction by 3/4 of the hexagon height
        float z = initPos.z - gridPos.y*hexHeight*0.75f;
        return new Vector3(x, 0, z);
    }

    //Finally the method which initialises and positions all the tiles
    private void createGrid()
    {
        Map = new Tile[gridWidthInHexes, gridHeightInHexes];

        //Game object which is the parent of all the hex tiles
        var hexGridGO = new GameObject("HexGrid");
        int tempTileIndex = 0;
        int curMapIndexHeight = 0;
        for (float y = 0; y < gridHeightInHexes; y++)
        {
            int curMapIndexWidth = 0;
            for (float x = 0; x < gridWidthInHexes; x++)
            {
                //GameObject assigned to Hex public variable is cloned
                var hex = (GameObject) Instantiate(Hex);
                //Current position in grid
                var gridPos = new Vector2(x, y);
                var tempTile = hex.GetComponent<Tile>();
                tempTile.TilePos = gridPos;
                tempTile.TileIndex = tempTileIndex;
                hex.transform.position = calcWorldCoord(gridPos);
                hex.transform.parent = hexGridGO.transform;
                Map[curMapIndexWidth, curMapIndexHeight] = hex.GetComponent<Tile>();
                tempTileIndex++;
                curMapIndexWidth++;
            }
            curMapIndexHeight++;
        }
    }

    //The grid should be generated on game start
    private void Start()
    {
        
        gameMaster = gameObject.GetComponent<GameMaster>();
        setSizes();
        createGrid();
        if (gameMaster != null)
        {
            gameMaster._LoadedMap();
        }
    }
}

One of the GameMaster scripts should be attached to _GameMaster :

using UnityEngine;

public partial class GameMaster : MonoBehaviour
{
    private Grid grid;
    public GameObject unit;
    void Awake()
    {
        MapLoaded += OnMapLoaded;
    }
    void Start()
    {
        grid = gameObject.GetComponent<Grid>();
    }

    void OnMapLoaded()
    {
        Debug.Log("Generated Map");
        Debug.Log(grid.Map[1, 3].TileIndex);

        
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            if (MouseClick != null) 
                MouseClick(0);
        }

        if (Input.GetMouseButtonDown(1))
        {
            if (MouseClick != null)
                MouseClick(1);
        }

        if (Input.GetMouseButtonDown(2))
        {
            if (MouseClick != null)
                MouseClick(2);
        }
    }
}

public partial class GameMaster
{
    public delegate void LoadingDeligate();
    public event LoadingDeligate MapLoaded;

    public delegate void ClickEvents(int button);
    public event ClickEvents MouseClick;

    public void _LoadedMap()
    {
        if (MapLoaded != null) 
            MapLoaded();
    }
}

The tile script is attached to the tile Prefab:

using UnityEngine;

public class Tile : MonoBehaviour
{
    private int _tileIndex;
    private Vector2 _tilePos;
    private GameObject _unit;
    private bool isHoverd;
    private GameObject GMObject;
    private GameMaster gameMaster;
    private bool isSelected;

    public Texture defultTexture;
    public Texture hoverTexture;
    public Texture selectedTexture;

    public int TileIndex
    {
        get { return _tileIndex; }
        set { _tileIndex = value; }
    }
    public Vector2 TilePos
    {
        get { return _tilePos; }
        set
        {
            _tilePos = value; 
            Debug.Log("New TilePos: " + _tilePos);
        }
    }
    public GameObject Unit
    {
        get { return _unit; }
        set { _unit = value; }
    }

	void Start ()
	{
	    GMObject = GameObject.FindGameObjectsWithTag("GameController")[0];
        gameMaster = GMObject.GetComponent<GameMaster>();
	    gameMaster.MouseClick += OnButtonPress;
	}

    void OnButtonPress(int button)
    {
        if (isHoverd && button == 0)
        {
            renderer.material.SetTexture("_MainTex", selectedTexture);
            isSelected = true;
        }
        else if (!isHoverd && button == 0 && !Input.GetKey(KeyCode.LeftShift))
        {
            renderer.material.SetTexture("_MainTex", defultTexture);
            isSelected = false;
        }
    }

    void OnMouseEnter()
    {
        if (!isSelected)
        {
            renderer.material.SetTexture("_MainTex", hoverTexture);            
        }
        isHoverd = true;
        Debug.Log("hovering: " + _tileIndex);
    }

    void OnMouseExit()
    {
        if (!isSelected)
        {
            renderer.material.SetTexture("_MainTex", defultTexture);
        }
        isHoverd = false;
    }
}

Everything works with the exception of accessing the map array and the only error I get is when I’m trying to access the array with the map stored in.

Move your line:

grid = gameObject.GetComponent<Grid>();

into the Awake method.

OnMapLoaded is most likely being called before the Start method is called, so grid is still null.