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

App*_*ake 0 c# game-development unity-game-engine

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


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

Unity 控制台窗口中读取 NullReferenceException: Object reference not set to an instance of an object 的错误图像

App*_*ake 5

解释

在 C# 中,这通常是由引用尚未初始化的字段引起的。例如,如果您有一个字段public List<GameObject> items并且您稍后items.Add(foo)没有先执行items = new List<GameObject>(),则您正在尝试将一个项目添加到不存在的列表中。

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

解决方案

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

  1. 如果您使用任何Find-like 方法来获取 GameObject,请确保 GameObject 处于活动状态,否则Find-like 方法将返回 null 或可能返回错误的 GameObject。如果您需要在找到游戏对象时使其处于非活动状态,则需要使用与使用Find-like 方法直接查找游戏对象不同的方式来获取对游戏对象的引用,例如让组件注册到管理器类型班级。

  2. 查看游戏对象,确保您已在检查器中分配了应分配的所有内容。

  3. 如果所有内容都已分配,请使用抛出错误的 GameObject 运行游戏。可能你有一些东西在Awake()Start()否定引用,你会看到检查器切换到None.

两个未分配任何内容的 Unity 检查器字段的图像

  1. 注意用于修改对象的方法的返回类型。例如,如果您GetComponent()在对象上调用或执行任何类似操作,但未找到该组件,则不会抛出错误。它只会返回空值。这可以通过如下一行轻松处理:

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

这应该涵盖最常见的 Unity 特定原因。如果这仍然不能解决您的问题,请查看 Unity 自己的关于 NullReferenceException的页面,对于 C#,一般来说,在这个答案中有对 NullReferenceException 的更深入的解释。