0

我正在尝试将 Quest 对象添加到 Person。它对一个成功并为另一个给出了 nullreferenceexception,我在这里做错了什么?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;
     }
}

有什么建议为什么会出错?

4

2 回答 2

3

将您的变量初始化移到 中Awake(),请参阅以下文档(释义):

Awake 用于在游戏开始之前初始化任何变量或游戏状态....并使用 Start 来回传递任何信息。

GameCreator.Start()的编写方式依赖于 Unity 调用脚本的任意顺序。 GameCreator可能是第一个调用的对象,在这种情况下,您的其他脚本都没有初始化它们的值。

其他可能的错误:

  1. 你没有明确地实例化requestor,我假设这是在 Unity 的 Inspector 中完成的。
  2. 您没有包含可能返回 null 的“createQuest()”。
于 2013-10-28T15:09:48.757 回答
1

正如 Jordak 所说,您的 Start 方法可以按任何可能的顺序运行,因此您不能依赖另一个组件的 Start 。您有几种方法可以解决此问题:

  • 您可以将基本初始化代码移至 Awake()。但是,这仅允许您进行两个级别的初始化,并且将来可能会不够用。
  • 您可以在项目设置中调整脚本优先级。但是,这并不是真正的 C# 方式,因为这会使您的代码依赖于从中不明显的逻辑。
  • 不要在类初始化中初始化 thisPerson 字段,而是创建一个公共属性来访问它。(无论如何,公共领域在 C# 中都是不好的做法)。在该属性中,您可以在返回之前检查该字段是否为空,如果是,则对其进行初始化。
于 2013-10-29T09:45:54.077 回答