简体   繁体   中英

NullReferenceException in Unity (C#)

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? PS 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?

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM