Search code examples
c#unity-game-engineunityscript

Having trouble loading "neighbours" of a specific tile into a List


this is my first time asking questions here, i'm actually having a problem in my script: I'm trying to add the neighbors of a tile into a list, but i keep getting the NullReferenceException: Object reference not set to an instance of an object when trying to print what's inside the list.

To note that the first "list.Add" is actually working, the others aren't. To test it i'm always trying to find something that exists, all Tile_(x)_(y) exists.

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

public class TileStats : MonoBehaviour {

    public int x;
    public int y;
    public List<GameObject> neighbours;

    public List<GameObject> populateNeighbours ()
    {
        List<GameObject> list = new List<GameObject>();
        //If we're at x, y.
        //Left one is at x-1,y
        list.Add(GameObject.Find("Tile_" + (x-1) + "_" + y));

        //Right one is at x+1,y
        list.Add(GameObject.Find("Tile_" + (x+1) + "_" + y));


        //Bottom ones are at x,y-1 and x+1,y-1
        list.Add(GameObject.Find("Tile_" + x + "_" + (y-1)));
        list.Add(GameObject.Find("Tile_" + (x+1) + "_" + (y-1)));

        //Top ones are at x,y+1 and x+1,y+1
        list.Add(GameObject.Find("Tile_" + x + "_" + (y+1)));
        list.Add(GameObject.Find("Tile_" + (x+1) + "_" + (y+1)));
        return list;

    }
}


...
Tile_GO.GetComponent<TileStats>().x = x;
Tile_GO.GetComponent<TileStats>().y = y;
Tile_GO.GetComponent<TileStats>().neighbours=Tile_GO.GetComponent<TileStats>().populateNeighbours();
...

The error is thrown when i try to print the input: foreach (GameObject obj in ourHitObject.GetComponent().neighbours) { print("Name: " + obj.name + "Atual: " + i++); }

SOLVED

@AnthonyLeal I looked at the code and that is the problem. You are searching for GameObject while do they don't exist. Just think about it like this: Your generated a gameObject in your for loop then called the populateNeighbours() function in that for loop. That populateNeighbours() function does not operate on the generated GameObject in that loop. It looks for other GameObjects that are not yet generated. You did this many many times leading to over 500 errors. – Programmer


Solution

  • The problem is probably in the code itself, when i try to add the object to the list, reading it should be fine, for example If i add to the list 6x"Left ones", ( x-1) ( y), it will run correctly. If i try to add any other ( right, top, bottom ) the error is thrown when printing.

    This is happening because the first GameObject.Find("Tile_" + (x-1) + "_" + y) found the GameObject in the scene. The rest of the GameObject.Find method failed. When it fails, it returns null. That null is added to the List even though there is nothing there.

    This is something no one can fix for you because we can't see the name of GameObjects in your scene. You have to fix it yourself by checking if the GameObject.Find returns null before adding it to the List. Replace your populateNeighbours() function with the function below to easily debug your code. It won't add the GaeObject if it is null and it will print the name of GameObject it couldn't find. You can then use it to check if that GameObject actually exist in the scene.

    Also, Don't use foreach to loop over List in Unity. Use for loop instead.

    public List<GameObject> populateNeighbours()
    {
        List<GameObject> list = new List<GameObject>();
        //If we're at x, y.
        //Left one is at x-1,y
        GameObject tempObj = GameObject.Find("Tile_" + (x - 1) + "_" + y);
        if (tempObj == null)
            Debug.Log("Tile_" + (x - 1) + "_" + y + " Does NOT exist");
        else
            list.Add(tempObj);
    
        //Right one is at x+1,y
        tempObj = GameObject.Find("Tile_" + (x + 1) + "_" + y);
        if (tempObj == null)
            Debug.Log("Tile_" + (x + 1) + "_" + y + " Does NOT exist");
        else
            list.Add(tempObj);
    
        //Bottom ones are at x,y-1 and x+1,y-1
        tempObj = GameObject.Find("Tile_" + x + "_" + (y - 1));
        if (tempObj == null)
            Debug.Log("Tile_" + x + "_" + (y - 1) + " Does NOT exist");
        else
            list.Add(tempObj);
    
        tempObj = GameObject.Find("Tile_" + (x + 1) + "_" + (y - 1));
        if (tempObj == null)
            Debug.Log("Tile_" + (x + 1) + "_" + (y - 1) + " Does NOT exist");
        else
            list.Add(tempObj);
    
        //Top ones are at x,y+1 and x+1,y+1
        tempObj = GameObject.Find("Tile_" + x + "_" + (y + 1));
        if (tempObj == null)
            Debug.Log("Tile_" + x + "_" + (y + 1) + " Does NOT exist");
        else
            list.Add(tempObj);
    
        tempObj = GameObject.Find("Tile_" + (x + 1) + "_" + (y + 1));
        if (tempObj == null)
            Debug.Log("Tile_" + (x + 1) + "_" + (y + 1) + " Does NOT exist");
        else
            list.Add(tempObj);
    
        return list;
    }