0

I'm trying to add a Quest-object to a Person. It succeeds for one and gives a nullreferenceexception for the other, what am I doing wrong here? P.S. The player and requestor are set in the Unity inspector.

public class GameCreator : MonoBehaviour {
     private Quest quest;
     public Player player;
     public Requestor requestor;

     void Start() {
         quest = createQuest();
         requestor.thisPerson.SetQuest(quest); //this is the problem
         player.thisPerson.SetQuest(quest);
     }
}

public class Player : MonoBehaviour {
     public Person thisPerson;

     void Start() {
           thisPerson = new Person("Name");
     }
}

public class Requestor: MonoBehaviour {
     public Person thisPerson;

     void Start() {
           thisPerson = new Person("Name");
     }
}

public class Person {
     public Quest quest;

     void SetQuest(Quest quest) {
           this.quest = quest;
     }
}

Any suggestions why this is going wrong?

Teysz
  • 741
  • 9
  • 33
  • 1
    possible duplicate of [What is a NullReferenceException and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – CodeSmile Feb 16 '15 at 10:43
  • Nope, that question was about just a NullReferenceException, I had a question about those in C# specifically in Unity. Plus this question has been answered over TWO years ago... – Teysz Feb 17 '15 at 11:02
  • The causes of NullReferenceException and how to fix them are always the same, at the minimum the reference question is explaining the causes well enough that it should be clear why the error occurs (here either requestor or thisPerson are null). – CodeSmile Feb 17 '15 at 15:40
  • If you had bothered to read the selected anwser below, you would know Unity does things in some random order which can cause NRE's when one uses the Start() method instead of the Awake() method, it's NOT because any of the reasons stated in your "duplicate". – Teysz Feb 18 '15 at 19:22

2 Answers2

3

Move your variable initialization in to Awake(), see the documentation for the following (paraphrased):

Awake is used to initialize any variables or game state before the game starts.... and use Start to pass any information back and forth.

The way your GameCreator.Start() is written you are reliant on the arbitrary order in which Unity calls your scripts. GameCreator could be the first object called, in which case none of your other scripts have initialized their values.

Other possible errors:

  1. You don't explicitly instantiate requestor, I'm going to assume this was done in Unity's Inspector.
  2. You didn't include `createQuest()' which could be returning null.
Jerdak
  • 3,997
  • 1
  • 24
  • 36
1

As Jordak said, your Start methods can run in any possible order, so you can't rely on Start of some component in the other. You have several ways to address this issue:

  • You can move the basic initialization code to Awake(). However, this only allows you two levels of initialization, and can be insufficient in the future.
  • You can adjust script priority in the project settings. However, this is not really C# way, as this makes your code rely on logic that is not obvious from it.
  • Instead of initializing thisPerson field in the class initialization, create a public property to access it. (Public fields are bad practice in C# anyway). In this property, you can check if the field is null before returning it, and if it is, initialize it.
Max Yankov
  • 12,551
  • 12
  • 67
  • 135