NullReferenceException when object should be found!

I’m getting a null reference exception from the line of code inside the start menu. Don’t know why this is happening, could it be due to the abstract class? Even though I have a class deriving from it? Doesn’t make sense…

public abstract class NPC : MonoBehaviour
    {
        protected PlayerStats player;

        [SerializeField]
        protected float interactRadius;

        public delegate void OnInteract();
        public event OnInteract OnInteractWith;

        private void Start()
        {
            player = FindObjectOfType<PlayerStats>().GetComponent<PlayerStats>();
        }
     }

Well, firstly, the line in question is redundant. FindObjectOfType() already returns the PlayerStats component to you. That’s its job. Calling GetComponent() on that will either return the same thing right back to you, or throw a NilReferenceException.

Since it’s doing the latter, that means that it’s not finding an object of that type. Check the objects in your scene hierarchy, and make sure you really have what you think you have.

I thought how that worked was like saying: Find the object of type and then you still need to get the component

But anyway, yeah 100% it’s in there, as i did the exact same thing in a derived class and this works;

public class ImportantCitizen : NPC, ITalkable, IQuestGiver
    {

        private PlayerStats playerStats;

        void Start(){
              playerStats = FindObjectOfType<PlayerStats>();
         }
    }

The issue though is I need to use the player with every NPC.

Ah — you shouldn’t try to override or shadow the magic Unity methods like Start and Update in a class hierarchy. It doesn’t work.

Instead, for each such magic method, you must implement it in only one place in each class lineage. So either implement it in the base class, or implement it in each of the subclasses. But don’t try to do both.

Also, please use code tags when posting code. :slight_smile:

1 Like

+1 for code tags

Ah okay, the reason was I had the Start function in the derived class for a delegate event. Also I’ll edit the code tags in I couldn’t actually find them when I was posting the code.

Overriding Unity’s magic methods works just fine :slight_smile:

1 Like

Not in my experience, it doesn’t. Unity is looking them up by name — in such a case you have two implementations with the same name/signature. You’d expect the subclass one to get invoked but (again, in my testing at least), that doesn’t reliably happen.

Two implementations with the same name but contained in different classes. Now I can see the likelihood of failure being high if the base class has a virtual method and the invoking class does not have its own implementation, so maybe that’s what you experienced?

OK, time for me to back off and admit I was wrong. Maybe. :slight_smile:

Thinking more carefully, I think what I experienced is actually what sober minds would expect it to do: it invokes only the method in the subclass. The problem may have been that we’re just so conditioned to thinking of these magic methods as reliably invoked. But this behavior opens a way for a subclass to break a base class, even if the base class method was not declared virtual.

So for example, you make a base class, grab some references you know you’re going to need in Awake or Start, and do your thing. Then 7 months later you derive a subclass that just needs to add a little behavior, and it happens to also have some references to grab, so you implement Awake or Start there too… and suddenly all the base-class code is throwing NOEs because its Awake/Start never runs.

Fairly obvious once you see it, but a bit of a gotcha, and one from which the base class really can’t protect itself (which is unusual in C#, where normally only virtual methods can be overridden).

The need for subclasses in Unity doesn’t come up very often for me — I tend to favor a very shallow class hierarchy, with interfaces. But the above has bitten me once or twice, and so now when I do need to use subclasses, I’m very careful to define which level of the hierarchy is going to implement each magic method. Or I make them virtual, but ensure the subclass calls the base class implementation. Or I implement them only in the base class, and have that call a virtual method that subclasses are welcome to override.

Anyway, ya gotta be careful, is my point. :slight_smile:

1 Like

Yeah I could see how this would happen if you declare your magic methods as private so the IDE compiler doesn’t flag you for hiding.

Good advice though :slight_smile: