Problems following a Hex Map tutorial - Object reference not set to an instance of an object

I’m pretty new to Unity I’ve been working through a series of tutorials on YouTube for creating a hex map. I just worked through the second part - found here

and I can’t get all the code to work - despite going through the video numerous times to see if I’ve missed anything.

The author of the video had to backtrack about a quarter of the way into the video and I think he forgot to explain something that happened during that time…

I’ll paste in the code below. The problem code are the two lines that start with hexGO.GetComponent() - I get an error that says ‘NullReferenceException: Object reference not set to an instance of an object’

Any suggestions would be greatly appreciated!

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

public class HexMap : MonoBehaviour {

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

    public GameObject HexPrefab;
    public Material[] HexMaterials;

    public readonly int numRows = 20;
    public readonly int numColumns = 40;

    public void GenerateMap()
    {
        for (int column = 0; column < numColumns; column++)
        {
            for (int row = 0; row < numRows; row++)
            {
                // Instantiate a hex
                Hex h = new Hex (column, row);
                Vector3 pos = h.PositionFromCamera (
                  Camera.main.transform.position,
                   numRows,
                   numColumns
               );

                GameObject hexGO = Instantiate (
                    HexPrefab,
                    pos,
                    Quaternion.identity,
                    this.transform
                );

                hexGO.GetComponent<HexComponent>().Hex = h; //These two lines aren't working
                hexGO.GetComponent<HexComponent>().HexMap = this; //These two lines aren't working

                MeshRenderer mr = hexGO.GetComponentInChildren<MeshRenderer> ();
                mr.material = HexMaterials [Random.Range (0, HexMaterials.Length)];
            }
        }
    }
}

First, please use code tags. See the first post in the forum.

Second, please try googling “NullReferenceException: Object reference not set to an instance of an object” as it is easily the most-asked question in this forum presently.

That was the first thing I did… I know what the error is, I don’t know why it’s happening…

Well you know which line it’s on, so look at what could possible be null on that line:

hexGO.GetComponent<HexComponent>().Hex = h;

It’s either hexGO or HexComponent. So make sure that:

  1. Your prefab exists.
  2. It has a HexComponent on it.

A construct like the above can also be broken apart into its constituent elements in order to see what might be null.

HexComponent hc = hexGo.Getcomponent<HexComponent>();
hc.Hex = h;

Now you know where it blows up.

Engineers must be masochistic at heart because for some crazy reason, a lot of engineers like to ball all those statements up on one line because they like to make debugging difficult, and I don’t understand it.

Break it all apart, like by line, so you can breakpoint it at ANY POINT, because a) the compiler will make it just as fast, and b) it might reveal to you that you have a bug!

Hi Errorstaz - I had a look and I think I have both (but I’m not sure.) I’ll attach a picture to show what I see in Unity…

Thanks for your responses Kurt. As per your recommendation, I broke that line up into

HexComponent hc = hexGO.GetComponent<HexComponent>();
hc.Hex = h;

It fails on the second line - same Null Reference exception… I’m at a bit of a loss for how to proceed.

So breaking it down, the first line gets the HexComponent component from the given game object.

If it fails on the second line, it means it was unable to find said HexComponent.

Now here are some possibilities:

  • there IS no HexComponent on the GameObject
  • the HexComponent is disabled, which means it won’t be found.
  • the GameObject this script is running on isn’t the one you think it is (i.e., you dropped this script on another object as well)… try using Debug.Log( name) right before this construct to reveal the name of the GameObject

The above thought processes are pretty common to almost every minute-to-minute development problem you find when working in Unity, so keep lists like this handy. You can easily spend as much time tracking down “plumbing” of GameObjects and Components as you do tracking down actual code bugs. :slight_smile:

I can see what you mean about keeping track of the ‘plumbing’ - that’s definitely my biggest problem at the moment. I think it’s largely due to my lack of familiarity with Unity.

It seems like the script is now working - the only thing I did (other than adding lots of Debug.Log statements) is to hit apply on the HexPrefab. Could that have been enough to fix the problem? And if so why did it fix it?

It could have fixed it. So here’s some more Unity3D insight (and anyone else feel free to jump in and correct me or add to the discussion):

When you make a prefab, you are “snapshotting” a bunch of GameObjects and Components and their settings at that particular moment in time. It is not a “live” connection. It is just a onetime copy, as well as a link that says “I came from that prefab.”

When you drag that prefab into a scene, you are making a copy of that prefab, but the scene says “I look just like that Prefab, except I am located here.” I.e., the scene “overrides” the root transform only, and preserves the “I came from that prefab” link.

If you go into a prefab in your scene and move it, it moves that root transform, but it does not change the source prefab.

If you go into a prefab in your scene and change other parts of it, now ONLY THAT INSTANCE in your scene has those changes that you made. All other instances including the prefab itself, will have the base prefab values.

If you hit APPLY on an instance, the things that you changed on that instance will be copied to the base prefab, then every other instance that uses that base prefab will get those changes… EXCEPT other instances that override those particular changes.

tl;dr: It’s complicated, but it actually totally makes sense from a “take baseline and modify” approach.

PS - it also explains why the simple request for “nested prefabs” has not yet been met: it’s a hard problem to solve, because then you have prefabs that would need to contain the “changes” of other prefabs that happen to be inside of them, and then you have Prefab-ception.

Thanks Kurt - that does help explain what was happening. I have a lot of gaps in my understanding of Unity. I’m trying to go through tutorials to increase my understanding of how things work - but it’s a different way of thinking (for me.) It’ll take time to understand the various nuances of Unity, but then Rome wasn’t built in a day! Thanks again!

1 Like

Indeed… been using it 5+ years now and still finding new insights. It’s an awesome environment to work in. The Unity guys have done an amazing job extending and enhancing a truly completely configurable development environment.

1 Like