NullReferenceException: Object reference not set to an instance of an object

Hi everyone,

I’m trying to code a kind of game board generated by Conway’s life game.

I have a problem with adding a component to a GameObject. I would like to add a Cell component to a GameObject to have its properties and manage the cells.
I think that unfortunately I must go about it wrong, maybe I just misunderstood the use of AddComponent<>.

The exact title of my error is:
NullReferenceException: Object reference not set to an instance of an object
Cell.Awake () (at Assets/Cell.cs:22)
UnityEngine.GameObject:AddComponent()
CellManager:Start() (at Assets/CellManager.cs:29)

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

public class CellManager : MonoBehaviour {

    public float timeStep = .1f;
    public int mapW = 50, mapH = 50;

    public MapController mapInit;

    public GameObject cellPrefab;
    public Cell[,] cells;
    public Cell cell;
   

    private void Awake()
    {
        cells = new Cell[mapW, mapH];
    }

    private void Start()
    {
        for (int x = 0; x < mapW; x++)
        {
            for (int y = 0; y < mapH; y++)
            {
                GameObject localCell = Instantiate(cellPrefab, new Vector3(x, y), Quaternion.identity);
                cell = localCell.AddComponent<Cell>() as Cell;
                cell.cellManager = this;
                cell.vector = localCell.transform.position;
              

                cells[x, y] = cell;
            }
        }
    }

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

public class Cell : MonoBehaviour {

    public CellManager cellManager;
    public bool alive;
    public int[,] map;
    public bool departure = false;
    public bool arrival = false;

    public Vector3 vector;

    SpriteRenderer sRend;

    private void Awake()
    {
        sRend = GetComponent<SpriteRenderer>();
      

        map = cellManager.mapInit.map;

        if (map[(int)vector.x, (int)vector.y] == 1)
        {
            alive = true;
        }
        else
        {
            alive = false;
        }


    }

    private void Start()
    {

        if (vector.x == 49 && vector.y == 47)
        {
            departure = true;
        }else if (vector.x == 3 && vector.y == 0)
        {
            arrival = true;
        }
            MapColor();
    }

    private void MapColor()
    {
         //white means alive and black means dead
        if (!alive)
        {
            sRend.color = Color.white;
        }
        else if (alive)
        {
            sRend.color = Color.black;
        }

        if (departure)
        {
            sRend.color = Color.green;
            Debug.Log("green");
        }
        if (arrival)
        {
            sRend.color = Color.red;
            Debug.Log("red");
        }
    }


   
    private void Update()
    {
        MapColor();

        //will the cell be alive at the next step ?
        if (alive)
        {
            if (GetNeighbors() == 2) //alive and 2 neighbors
            {
                alive = true;
            }
            else if (GetNeighbors() == 3) //alive and 3 neighbors
            {
                alive = true;
            }
            else //alive and other count
            {
                alive = false;
            }
        }

        else if (!alive)
        {
            if (GetNeighbors() == 3) //dead and 3 neighbors
            {
                alive = true;
            }
            else //dead and other count
            {
                alive = false;
            }
        }

        if (departure) alive = false;
        if (arrival) alive = false;
          
    }


    GameObject cell;
    public int GetNeighbors()
    {
        int count = 0;
        for (int i = 0; i < 8; i++)
        {
            Debug.Log("coucou");
            //if (cellManager.cells.TryGetValue(NeighborPosition(i), out cell))
            //{
            //    //Debug.Log("neighbor");
            //    if (cell.GetComponent<Cell>().alive)
            //    {
            //        //Debug.Log("count");
            //        count += 1;
            //    }
            //}
        }
        return count;
    }


    Vector3 NeighborPosition(int i)
    {
        if (i == 0 && vector.x < cellManager.mapW - 1)
        {
            return vector + new Vector3(1, 0, 0);
        }
        else if (i == 1 && vector.x < cellManager.mapW - 1 && vector.y > 1)
        {
            return vector + new Vector3(1, -1, 0);
        }
        else if (i == 2 && vector.y > 1)
        {
            return vector + new Vector3(0, -1, 0);
        }
        else if (i == 3 && vector.x > 1 && vector.y > 1)
        {
            return vector + new Vector3(-1, -1, 0);
        }
        else if (i == 4 && vector.x > 1)
        {
            return vector + new Vector3(-1, 0, 0);
        }
        else if (i == 5 && vector.x > 1 && vector.y < cellManager.mapW - 1)
        {
            return vector + new Vector3(-1, 1, 0);
        }
        else if (i == 6 && vector.x < cellManager.mapW - 1)
        {
            return vector + new Vector3(0, 1, 0);
        }
        else if (i == 7 && vector.x < cellManager.mapW - 1 && vector.x < cellManager.mapW - 1)
        {
            return vector + new Vector3(1, 1, 0);
        }
        else
        {
            return Vector3.zero;
        }
    }
}

Sorry about the long question and the long code. I don’t know what can be used.

cellManager is null in Cell’s Awake as Awake is called immediately after Instantiate or AddComponent, so even though you’re setting it in the very next line inside CellManager’s Start, it’s already too late. Change Cell’s Awake to either OnEnable or Start and it should work as those functions are deferred a bit later in the execution cycle – or for a slightly better architecture, have the Cell find the CellManager itself rather than having to manually set it from an outside source.