-1

I'm having a bit of trouble with Unity 3D's Component-based design model.

Here's an example that demonstrates my problem:

class MyComponent : MonoBehaviour
{
    MyType entity;

    void Start() 
    {
        entity = (MyType)FindObjectsOfType(typeof(MyType)).First();
    }

    void MyMethod() 
    {
        var x = entity.SomeProperty; // <= NullReference exception
    }
}

// ....

var clone = (GameObject)Instantiate(original);
clone.GetComponent<MyComponent>().MyMethod();

Sometimes, not always though, MyMethod executes before Start so what I end up doing is move all the initializations I usually have in Start to MyMethod which is quite an ugly workaround:

    void Start() { }

    void MyMethod() 
    {
        entity = (MyType)FindObjectsOfType(typeof(MyType)).First();
        var x = entity.SomeProperty; // <= now it's fine.
    }

My question is, what is the correct way of working with this pattern (without a constructor)?

4

2 回答 2

3

当您从另一个组件的 Awake 调用 MyMethod 时,可能会发生这种情况,因为 Awake在游戏开始之前被调用。我看到的唯一解决方案是确保不要在 Awake() 事件中调用其他组件(在本例中为 MyMethod)上的方法,而是在 Start() 事件中调用。

于 2013-07-09T13:29:18.997 回答
0

Unity 文档说“在游戏开始之前调用 Awake”,但这并不准确。当在场景中游戏对象变为活动状态并携带该组件时,将调用组件的 Awake 方法。

加载场景时,默认情况下某些游戏对象将处于活动状态,但稍后可能会激活其他游戏对象。然后有可能通过 AddComponent 动态添加组件。

在依赖 Awake 和 Start 方法之间的依赖关系时,应牢记这一点。竞争条件的另一个示例是从 Update 方法启用组件。虽然启用组件意味着将调用其 Start 方法,但这不会在运行更新周期中发生,因此其他组件无法依赖第一个组件的“.enabled”属性来确定它是否已启动。

于 2019-01-14T08:43:59.973 回答