在 Unity (C#) 中,为什么我会收到 NullReferenceException 以及如何修复它?

In Unity (C#), why am I getting a NullReferenceException and how do I fix it?

这是使用 Unity 的初学者最常问的问题之一,所以我再问一次,以解决规范 NullReferenceException 问题未完全回答的特定于 Unity 的原因。


我正在 Unity 中开发游戏,当我点击播放时,我收到一条错误消息“NullReferenceException:对象引用未设置为对象的实例”,我无法弄清楚为什么会这样.是什么原因造成的,我该如何解决?

说明

一般在C#中,这是由于引用了一个还没有初始化的字段引起的。例如,如果您有一个字段 public List<GameObject> items,后来您没有先执行 items = new List<GameObject>() 就调用了 items.Add(foo),那么您正试图将一个项目添加到一个不存在的列表中。

但是,特别是在 Unity 中,最常见的原因是忘记在检查器中设置引用。当您创建一个新组件并添加一个字段 public Transform destination 时,您很可能打算在检查器中分配一个预制件。如果您忘记了,您就是在尝试引用不存在的内容。

解决方案

如果您双击控制台中的错误消息 window,Unity 将(除了少数例外)突出显示引发错误的层次结构中的 GameObject,然后打开您的代码编辑器并突出显示发生错误的脚本行。

  1. 如果您正在使用任何类似于 Find 的方法来获取游戏对象,请确保该游戏对象处于活动状态,否则 Find 类方法将 return null 或者 return 错误的游戏对象。如果您需要 GameObject 在找到时处于非活动状态,则需要使用不同的方式来获取对 GameObject 的引用,而不是使用 Find-like 方法直接查找 GameObject,例如让组件注册经理类型 class.

  2. 查看 GameObject,确保您已在检查器中分配所有应分配的内容。

  3. 如果所有内容都已分配,运行 将选择引发错误的 GameObject 的游戏。您可能在 Awake()Start() 中有一些东西否定了引用,您会看到检查器切换到 None.

  1. 注意用于修改对象的 return 类方法。例如,如果您在一个对象上调用 GetComponent() 或任何类似的东西,但没有找到该组件,它不会抛出错误。它只会 return 为空。这可以很容易地用一行来处理:

    if(thing == null) //log an error, or do something to fix the reference else //do what you wanted to do

这应该涵盖最常见的特定于 Unity 的原因。如果仍然不能解决您的问题,请访问 Unity 自己的页面 on NullReferenceException, and for C# generally, there's a more in-depth explanation of NullReferenceException in this answer.