NullReferenceException in Unity (C#)

本文关键字:Unity in NullReferenceException | 更新日期: 2023-09-27 18:37:04

>我正在尝试将任务对象添加到人员中。它为一个成功并为另一个提供空引用异常,我在这里做错了什么?附言:玩家和请求者在 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;
     }
}

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

NullReferenceException in Unity (C#)

将变量初始化移入 Awake() ,请参阅以下内容的文档(释义):

Awake 用于初始化之前的任何变量或游戏状态 游戏开始....,然后使用"开始"来回传递任何信息。

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

其他可能的错误:

  1. 您没有显式实例化requestor,我将假设这是在 Unity 的检查器中完成的。
  2. 您没有包含可能返回 null 的 'createQuest()'。

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

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