Rows drop down in Array/Match 3

I am trying to make a little Match3 Game. Right now have problem making the gems/tiles dropping down. I am able to destroy the gem. I am able to use the Coroutine to check if the array is null (access from another script), which is no problem. I assume I am not accessing directly in the position of the array so I can’t seem to figure out how to move the gems down.
Below is the error I get
" NullReferenceException: Object reference not set to an instance of an object

 public Vector2 mapSize;
private Vector3 gridPlacement;
public GameObject[] listGems;
public GameObject gem;
public GameObject[,] gemHolder;
void Start()
{
     //allGems = new GameObject[mapSize.x, mapSize.y];
     GenerateBoard();
}
public void GenerateBoard()
{
     gemHolder = new GameObject[9, 9];
     string holderName = "Generated Board";
     Transform boardHolder = new GameObject(holderName).transform;
boardHolder.parent = transform;
     for (int x = 0; x < mapSize.x; x++)
     {
         for (int y = 0; y < mapSize.y; y++)
         {
             gridPlacement = CoordToPosition(x, y);
             int gemsToUse = Random.Range(0, listGems.Length); // making gems random
             gem = Instantiate(listGems[gemsToUse], gridPlacement, Quaternion.Euler(Vector3.right * 90)); // putting gems in the board
             gem.transform.parent = this.transform; // putting it in parent
             gem.name = "(" + x + "," + y + ")"; // naming the grid as coordinates
             //make sure tile is aware of its placement on the map
             gem.GetComponent<GemPosition>().x = x;
             gem.GetComponent<GemPosition>().y = y;
             gemHolder[x, y] = gem;
         }
     }
}
Vector3 CoordToPosition(int x, int y)
{
     return new Vector3(-mapSize.x / 2 + 3f + x, 0, -mapSize.y / 2 + 0.5f + y); // position of grid
}
public IEnumerator MoveRowsDown()
{
     int nullCount = 0;
     for (int x = 0; x < mapSize.x; x++)
     {
         for (int y = 0; y < mapSize.y; y++)
         {
             if (gemHolder[x, y] == null)
             {
                 nullCount++;
             }
             else if (nullCount > 0)
             {
                 gemHolder[x, y] = gemHolder[x, (y - nullCount)];
             }
         }
         nullCount = 0;
     }
     yield return new WaitForSeconds(.4f);
}

You didn’t say what line is giving you the issue, so it’s hard to diagnose, but I’m not really sure why you’re using mapSize for your grid since you already know you have a 9x9 grid so maybe that’s the issue.

As for the gems falling down, just check if the grid space below is empty and move the gem down.

for(int x = 0; x < 9; ++x)
{
   for(int y = 0; y < 9 - 1; ++y) // - 1 just for clarity, you should define the grid size somewhere as a const
   {
       if(grid[x, y] == null) // skip if empty
           continue;

       if(grid[x, y + 1] == null) // is the cell below us empty?
       {
           grid[x, y + 1] = grid[x, y]; // move it down one cell
           grid[x, y] = null; // remove it from the current cell

           grid[x, y + 1].position = CoordToPosition(x, y + 1); // set the visual position
       }
   }
}

I think that’ll work. It’s a little early for me and I wrote the code in place here, so you may have to do a little debugging.

I have mapSize, as I want to be able to change the size of the board if needed.
for the 9x9 delcaration, I thought would be better to move the gems based on the position in the array rather than trying to move them based on the position of the game world. So I had to cast the gem into the gemHolder[x,y] array. However I tried to put the size based on the map size as gemHolder[mapsize.x, mapsize,y], but it gave me error so I just delcare as my current grid size for now.

Right now I think the problem I have is with the couroutine. I tried to put it your way but still give me the error of " NullReferenceException: Object reference not set to an instance of an object" and nothing happens when I destory the gem.

Maybe I am not using the couroutine the correct way. Right now I have it in another script, then once I destroy the gem it runs the courotine like this

    void MouseOverGem(GameObject ourHitObject)
    {
        if (Input.GetMouseButtonDown(0))
        {
            AccessNeigbhour = ourHitObject.GetComponent<GemPosition>();
            UpGemPos = AccessNeigbhour.upGem;
            RightGemPos = AccessNeigbhour.rightGem;
            DownGemPos = AccessNeigbhour.downGem;
            LeftGemPos = AccessNeigbhour.leftGem;

            if (swipeDirection == "up")
            {
                DestroyImmediate(UpGemPos);
                StartCoroutine(AccessBoard.MoveRowsDown());

            }

I would think you would have to start on the bottom row and move upward. If it’s null, and the one above is not null, move that one down one, otherwise check the one above that until there’s a null at the top, or you have moved each one down. Then do the next row higher until done. Actually, I suppose you would only move them down one row at a time so they had the appearance of falling so you would only check one space above and move it down, traverse all the rows, then pause and start again. If every null had a null above, or was on the top row, then finish.