简体   繁体   English

Unity(C#)中的NullReferenceException

[英]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? 它为一个成功,为另一个提供nullreferenceexception,我在这里做错了什么? PS The player and requestor are set in the Unity inspector. PS播放器和请求者在Unity检查器中设置。

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() ,请参阅以下文档 (措辞):

Awake is used to initialize any variables or game state before the game starts.... and use Start to pass any information back and forth. Awake用于在游戏开始之前初始化任何变量或游戏状态....,并使用Start来回传递任何信息。

The way your GameCreator.Start() is written you are reliant on the arbitrary order in which Unity calls your scripts. GameCreator.Start()的编写方式GameCreator.Start() Unity调用脚本的任意顺序。 GameCreator could be the first object called, in which case none of your other scripts have initialized their values. GameCreator可能是第一个被调用的对象,在这种情况下,您的其他脚本都没有初始化它们的值。

Other possible errors: 其他可能的错误:

  1. You don't explicitly instantiate requestor , I'm going to assume this was done in Unity's Inspector. 您没有显式实例化requestor ,我将假设这是在Unity的Inspector中完成的。
  2. You didn't include `createQuest()' which could be returning null. 您没有包含可能返回null的`createQuest()'。

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. 正如Jordak所说,您的Start方法可以按任何可能的顺序运行,因此您不能依赖另一个组件中的Start组件。 You have several ways to address this issue: 您可以通过多种方式解决此问题:

  • You can move the basic initialization code to Awake(). 您可以将基本初始化代码移至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. 但是,这并不是真正的C#方式,因为这使您的代码依赖于从中看不出来的逻辑。
  • Instead of initializing thisPerson field in the class initialization, create a public property to access it. 不用在类初始化中初始化thisPerson字段,而是创建一个公共属性来访问它。 (Public fields are bad practice in C# anyway). (无论如何,公共领域在C#中都是不好的做法)。 In this property, you can check if the field is null before returning it, and if it is, initialize it. 在此属性中,可以在返回该字段之前检查该字段是否为null,如果是,则将其初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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