0

I am currently in lost, as my GameObject returns null.

About the issue, I'm unsure if it's because I missed a small thing, or if I'm straight up programming the use of multiple classes completely wrong.

My code where I generate the gameobject array:

public class gridInit : MonoBehaviour {

    const int mapWidth = 33;
    const int mapHeight = -27;
    const float tileSizeUnits = 1.0f / 3;
    public GameObject tile;
    // Use this for initialization
    void Start () {
        GenerateTileMap();
        Screen.fullScreen = true;
    }

    void Awake()
    {

    }
    // Update is called once per frame
    void Update () {

    }

    bool walkable = false;
    [HideInInspector]
    public GameObject[] goTile = new GameObject[892]; 

    void GenerateTileMap()
    {
        int tileNumber = 0;
        for (float y = 0; y > mapHeight; y--)
        {
            for (float x = 0; x < mapWidth; x++)
            {
               float tilePosX = x/3;
               float tilePosY = y/3;
               int layerPos = -2;
               goTile[tileNumber] = Instantiate(tile, new Vector3(tilePosX, tilePosY, layerPos), Quaternion.identity) as GameObject;
               goTile[tileNumber].name = "tile" + tileNumber;
               goTile[tileNumber].tag = "grid";
               RaycastHit2D hit;
               Vector3 fwd = goTile[tileNumber].transform.TransformDirection(Vector3.forward);
               Debug.DrawRay(goTile[tileNumber].transform.position, fwd * 50, Color.green);
               hit = Physics2D.Raycast(goTile[tileNumber].transform.position, fwd, 200);
               if (hit)
               {
                   goTile[tileNumber].tag = "walkableGrid";
               }
               tileNumber++;     
            }
        }
    }

And my class where I would like to use set GameObjects:

public class gameCalibration : MonoBehaviour {

    bool calibrationComplete = false;
    public gridInit gInit;
    public cam Cam;

    // Use this for initialization
    void Start () {
    }

    // Update is called once per frame
    void Update () {
        {
            for (int i = 0; i < gInit.goTile.Length; i++)
            {
                if (calibrationComplete == false)
                {
                    gInit.goTile[i].GetComponent<Renderer>().enabled = true;
                }
                else
                {
                    gInit.goTile[i].GetComponent<Renderer>().enabled = false;
                }
            }

            if (calibrationComplete == false)
            {
                Calibrate();
            }
            else
            {
                gInit.GenerateObjects();
                calibrationComplete = true;
            }
        }        
    }


    Vector2[] camTileCenter;
    Vector2 tempCenter;
    void Calibrate()
    {
        for (int i = 0; i < gInit.goTile.Length; i++)
        {
                gInit.goTile[i].GetComponent<SpriteRenderer>().color = Color.red;

                if (Cam.redBlobs[i] != null && camTileCenter[i] != tempCenter)
                {
                    camTileCenter[i] = new Vector2(Cam.redBlobs[i].Width / 2, Cam.redBlobs[i].Height / 2);
                    tempCenter = camTileCenter[i];
                }

        }
    }
}

I've tried messing around with some values and how the class is initialized, but for no prevail.

My complete error:

NullReferenceException: Object reference not set to an instance of an object
gameCalibration.Update () (at Assets/Scripts/gameCalibration.cs:21)

Error line in gameCalibration: gInit.goTile[i].GetComponent<Renderer>().enabled = true;

Jon Dier
  • 127
  • 1
  • 13
  • You need to instantiate the class by the looks of it, because you never do so - it never calls it's start method – Alfie Goodacre Nov 10 '16 at 14:31
  • Did you assign reference for gInit in inspector? can you point at the line where it throws exception? – Umair M Nov 10 '16 at 14:33
  • Can you add some logging to determine exactly which reference is null? is it `goTile[i]`, or `GetComponent()`? Knowing that information would clarify the problem at hand. – Serlite Nov 10 '16 at 15:01
  • It's the goTile[i]. – Jon Dier Nov 10 '16 at 15:06
  • In `GenerateTileMap()`, if you try to log a random element from `goTile` right after populating it, does it fail? Also, does `goTile[i]` fail for `i = 0` in your for loop, or some point later? – Serlite Nov 10 '16 at 15:27
  • SpriteRenderer component might not be there on tile Object. You need to [debug](https://unity3d.com/learn/tutorials/topics/scripting/monodevelops-debugger?playlist=17117) it using MonoDevelope/Visual Studio. – Umair M Nov 10 '16 at 15:27
  • @Serlite I've just been running some logs, and it does infact keep running through my loop, it just keep telling me the current onTile element is = null. – Jon Dier Nov 10 '16 at 19:21

2 Answers2

2
public gridInit gInit = new gridInit();

instead of

public gridInit gInit;

I dont see you creating an instance of your object anywhere

FakeCaleb
  • 931
  • 8
  • 18
  • The objects are instantiated in the gridInit.cs, then I want to use the contents of said array in my other class. – Jon Dier Nov 10 '16 at 14:34
  • @JonDier you need to instantiate the class itself though – Alfie Goodacre Nov 10 '16 at 14:35
  • But inside of `gameCalibration` you dont create the instance of the object creating the array – FakeCaleb Nov 10 '16 at 14:35
  • @NewCallum This is a Unity-specific feature - you're able to set values/references for public members in the game editor before actually starting the game, removing the need to programmatically instantiate/find a reference to it. (As such, this is unlikely to be the problem here.) – Serlite Nov 10 '16 at 15:12
0

The issue is that the class, gridInit has not been instantiated, take this situation for example

public List<string> exS;
public List<string> exS2 = new List<string>();

Console.WriteLine(exS.Count); //The List<string> is null, as it has not been instantiated - errors
Console.WriteLine(exS2.Count); //the List<string> is blank, as it was instantiated with new List<string>() - prints 0

As such when you have this situation

public gridInit gInit;
public gridInit gInit2 = new gridInit();

gInit.goTile[i].GetComponent<Renderer>().enabled = false;
gInit2.goTile[i].GetComponent<Renderer>().enabled = false;

Now what do you think happens here? gInit is null as it was not instantiated, whereas gInit2 works, because when we used = new gridInit(); it created the new instance of the class, which then created its variables

Alfie Goodacre
  • 2,581
  • 1
  • 9
  • 23
  • I've been down this path, but since it didn't solve my issue I edited my code just before posting. Good to know the reason behind why it needs to be done. However, the issue still persists despite initiating. – Jon Dier Nov 10 '16 at 14:43
  • In that case change this `void Start () { GenerateTileMap(); Screen.fullScreen = true; }` to `public gridInit() { GenerateTileMap(); Screen.fullScreen = true; }` This constructor will be called when you instantiate the object – Alfie Goodacre Nov 10 '16 at 14:45
  • Either that or try `public gridInit gInit;` but then in your `Start` method put this `gInit = new gridInit();` – Alfie Goodacre Nov 10 '16 at 14:50
  • Same result im afraid – Jon Dier Nov 10 '16 at 14:55
  • @AlfieGoodacre Unity operates a bit differently in dealing with public members - in the editor, you're able to drag an object onto a public field, and assign a reference before running the game. This is likely the reason the code doesn't presently instantiate `gInit`, and also fails a lot later than you would expect if `gInit` was the null reference (because it actually does have a value assigned). – Serlite Nov 10 '16 at 15:24
  • I have used Unity but forgot that variables can be added in the editor :) thanks for that reminder, though if it was null wouldn't that be the first point of error? That's the first time goTile is used as the comparison isn't done until the second iteration of the loop is it? (I might be wrong there and a complete idiot) – Alfie Goodacre Nov 10 '16 at 15:26
  • @JonDier it could also be possible that the tile you are using in this line `gInit.goTile[i].GetComponent().enabled = true;` doesn't have a Renderer component – Alfie Goodacre Nov 10 '16 at 15:27
  • @AlfieGoodacre If `gInit` was null, I'd expect the code to actually fail as it reached `gInit.goTile.Length` - not after it entered the for loop. Null references can sometimes be a bit of a headache to track down though. – Serlite Nov 10 '16 at 15:31