文档

Unity Engine

Unity Engine

Null 引用

Understand what causes a NullReferenceException in C# and how to avoid uninitialized object references.
阅读时间4 分钟最后更新于 1 个月前

尝试访问值为
null
的类型的成员时,C# 中会发生
NullReferenceException
。在运行时出现
NullReferenceException
通常意味着在使用对象引用变量之前忘记初始化该变量。有关产生 null 引用的常见编码错误的完整解释,请参阅 Microsoft 文档。
Null 引用错误消息如下所示:
NullReferenceException: Object reference not set to an instance of an object at Example.Start () [0x0000b] in /Unity/projects/nre/Assets/Example.cs:10
此错误消息指出脚本文件
Example.cs
的第 10 行发生
NullReferenceException
,该异常发生在
Start()
函数内部。根据这些信息,比较容易查找和修复 Null 引用异常。在此示例中,代码为:
using UnityEngine;using System.Collections;public class Example : MonoBehaviour { // Use this for initialization void Start () { GameObject myGameObject = GameObject.Find("exampleGameObject"); Debug.Log(myGameObject.name); } }
代码会查找名为“exampleGameObject”的游戏对象。在此示例中不存在该名称的游戏对象,因此
Find()
函数返回
null
。在下一行(第 9 行),我们使用
myGameObject
变量并尝试打印出其引用的游戏对象的名称。由于 Unity 正在尝试访问不存在的游戏对象,因此会返回
NullReferenceException

Null 检查

此示例中的解决方案是,在给定名称的游戏对象不存在的情况下包含结果。以下脚本将检查
go
变量是否返回
null
,如果是,则显示一条消息:
using UnityEngine;using System.Collections;public class Example : MonoBehaviour { void Start () { GameObject myGameObject = GameObject.Find("exampleGameObject"); if (myGameObject == null) { Debug.Log("No GameObject called exampleGameObject found"); } else { Debug.Log(myGameObject.name); } } }

自定义 == 运算符

对于继承自 UnityEngine.Object 的类型,Unity 使用 C# 相等和不等运算符的自定义版本。这意味着,即使
myGameObject
在技术上持有有效的 C# 对象引用,上述示例 (
myGameObject == null
) 中的 null 检查也可以对
true
求值(反过来,
myGameObject != null
也可以对
false
求值)。在以下两种情况下会发生这种情况:
  1. 对象可以是所谓的“假 null”或占位对象,Unity 在编辑器中仅用于填充未初始化的 MonoBehaviour 字段。这些对象可存储有用的调试信息,以便在您尝试引用这些字段时帮助您找到这些字段的来源。
  2. 对象可以是托管 (C#) 对象,该对象尚未进行垃圾收集,但由于非托管 (C++) 对应对象已被销毁,因此应被视为 null。

Try/Catch 代码块

如果使用需要在检视面板 (Inspector) 窗口中初始化的变量,Unity 也会调用
NullReferenceException
。如果忘记这样做,则变量将为
null
。处理
NullReferenceException
的另一种方法是使用
try
/
catch
代码块。例如:
using UnityEngine;using System;using System.Collections;public class Example2 : MonoBehaviour { public Light myLight; // set in the inspector void Start () { try { myLight.color = Color.yellow; } catch (NullReferenceException ex) { Debug.Log("myLight was not set in the inspector"); } } }
在此代码示例中,名为
myLight
的变量是需要在检视面板窗口中设置的
Light
。如果未设置此变量,则默认为
null
。
若尝试在
try
代码块中改变光源的颜色,则会导致
NullReferenceException
。如果发生这种情况,
catch
代码块会显示一条消息,提醒您在检视面板中设置光源。

其他资源