【问题标题】:FixedUpdate is called before Start of the same MonoBehaviorFixedUpdate 在同一个 MonoBehaviour 的开始之前被调用
【发布时间】:2019-05-14 08:42:28
【问题描述】:

我有一个 MonoBehavior 做如下的事情:

public class MyMonoBehavior : MonoBehaviour
{
    private Rigidbody m_Rigidbody;

    private void Start()
    {
        m_RigidBody = GetComponent<Rigidbody>();
    }

    private void FixedUpdate()
    {
        m_Rigidbody.AddForce(Vector3.one); // May throw NullRefrenceException
    }
}

MyMonoBehavior 附加到在运行时创建的 GameObject。 有时,m_Rigidbody.AddForce(Vector3.one); 会抛出 NullRefrenceException。 FixedUpdate 似乎在 Start 之前运行。是bug吗?

根据Unity3d documentation

第一帧更新前开始:

  • 在第一个之前调用 Start 仅在启用脚本实例时才更新帧。

对于添加到场景中的对象,将调用 Start 函数 更新之前的所有脚本,等等都被调用。自然, 这在对象被实例化时无法强制执行 游戏玩法。

所以上面的所有脚本似乎都包含“MyMonoBehavior”本身?所以它的 FixedUpdate 可以在它的 Start 之前执行。

我的理解正确吗?或者这是 Unity3d 的 bug?

我的Unity3d版本是2017.3.1f1

【问题讨论】:

  • FixedUpdate物理引擎的周期性更新回调。 Update 是基于 frame 的更新,即显示更新。他们彼此独立工作。文档唯一保证的是:“Start 在第一次 frame 更新之前被调用...”尝试Awake 并查看docs.unity3d.com/Manual/ExecutionOrder.html
  • ...OnEnable 可能是更好的选择,因为刚体组件可能不会在唤醒时初始化。或者你必须做解决方法if(m_RigiBody) ...FixedUdate:“这个函数在每个固定帧率帧调用,如果启用了 MonoBehaviour。”所以应该先调用OnEnable
  • 我在没有做任何测试的情况下就写了这个。如果您可以确认它有效,我会将其转换为答案。
  • 顺便说一句:GetComponent&lt;Rigibody&gt;(); 你的意思是Rigidbody 还是你创建了自己的扩展组件?
  • @Quasimodo'sclone 请注意,在docs.unity3d.com/Manual/ExecutionOrder.html 中也有一个图形清楚地表明StartPhysics 块之前也被调用,所以这实际上不应该是问题,对吧?

标签: unity3d


【解决方案1】:

这就是为什么你有Awake。基本上,您应该在Awake 中进行特定于您的对象的初始化,并将与其他对象的交互留给StartAwake 被称为对象实例化过程的一部分,所以我非常怀疑你会遇到类似的问题。

【讨论】:

  • 但是m_RigidBody = GetComponent&lt;Rigidbody&gt;(); 只是获得一个通常应该已经存在的参考,因此使用AwakeStart 获得它实际上应该没有区别。 (当然我也会使用Awake,如果我知道另一个组件稍后会要求传递参考,例如)
  • @derHugo OP 的问题是 FixedUpdate 被调用之前引用有机会被分配。
猜你喜欢
  • 1970-01-01
  • 2016-05-13
  • 1970-01-01
  • 2016-04-23
  • 1970-01-01
  • 2022-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多