Unity中FixedUpdate报NullReferenceException但LateUpdate无错的原因
为什么FixedUpdate会触发空引用,LateUpdate却不会?
这事儿我太熟了,咱们从Unity的帧执行逻辑入手,拆解一下这个差异的根源:
核心原因:Unity的帧更新顺序差异
Unity的每帧执行流程是有严格顺序的,这直接导致了FixedUpdate和LateUpdate对对象引用的时机不同:
- FixedUpdate:和物理引擎同步,固定时间间隔执行(默认0.02秒),它的执行时机是在所有Update函数之前,甚至一帧内可能执行多次。
- LateUpdate:在所有Update函数执行完毕后才会运行,而且每一帧只执行一次。
这就带来了两种常见的空引用场景:
1. active的赋值时机在Update之后
如果你的active变量是在某个脚本的Update或LateUpdate里赋值的(比如通过FindObjectOfType、动态获取场景对象等),那么:
- FixedUpdate在Update之前跑,这时候
active还没被初始化,自然就是null,触发空引用。 - LateUpdate在所有Update之后跑,已经拿到了有效的
active引用,所以不会报错。
2. 脚本执行顺序的“隐形坑”
Unity允许自定义脚本的执行顺序,如果负责初始化active的脚本,它的Update执行顺序比你的Handler脚本的FixedUpdate晚,那也会导致FixedUpdate执行时active还是null。而LateUpdate不受脚本顺序影响——它一定在所有Update之后执行,所以能拿到正确的引用。
解决建议(适配FixedUpdate的需求)
既然你要在FixedUpdate里操作Rigidbody(这本身是正确的做法,物理操作就该放FixedUpdate),可以试试这几个方案:
- 提前初始化
active:把active的赋值逻辑移到Awake()或Start()里,确保FixedUpdate执行前,变量已经有有效值。 - 加空引用防护:在判断条件前先检查
active是否为null:if (active != null && active.transform.position.x <= -4) { Debug.Log(active.transform.position.x.ToString()); // 这里写你的Rigidbody移动逻辑 } - 调整脚本执行顺序:在
Edit → Project Settings → Script Execution Order里,把负责赋值active的脚本优先级调高,让它在Handler的FixedUpdate之前执行。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

