到目前为止,我一直在编码,认为monobehaviour
中的函数将按以下顺序执行:
OnEnable>开始>更新> OnDisable
问题在于我认为此顺序将是绝对,这意味着在一个函数没有完全完成之前,下一个函数就无法开始执行。
update
结束之前不会执行start
吗?然后我的问题出现在不同的monobehaviour
类之间的同步中。
我有一个在其start
函数中创建一些对象(基本上是菜单)的类。然后在另一个类中,我有一个类似的代码,但它也依赖,该类由第一个类创建的对象已经存在。我收到错误消息,因为尚未找到对象。
NullReferenceException:对象引用未设置为对象ShopHandler.Start()的实例(在Assets / Scripts / Shops / ShopHandler.cs:60)
所以现在我被困住了。因此,我的第二个问题是,
最后,还必须问这两个问题:
update
函数是否可以在这些类中的任何一个中执行,而它们却以某种方式“等待”其初始化部分,无论是在start
函数,OnEnable
函数中还是其他函数中? 当然,update
函数依赖于已经初始化的对象,这可能会导致新的问题。
预先感谢
答案 0 :(得分:2)
问题是我认为该顺序是绝对的,这意味着在一个函数没有完全完成之前,下一个函数就无法开始执行。
第一个问题是:是这样吗?在开始结束之前不会执行更新吗?
通常是的,但是有一个例外。
如果将Start
实现为协程,则可以在Update
以相同的单行为结束之前调用Start
。
例如,此代码:
IEnumerator Start()
{
Debug.Log("Start beginning");
yield return null;
Debug.Log("Start continuing");
yield return null;
Debug.Log("Start completing");
}
void Update()
{
Debug.Log("Update running");
}
可以产生以下输出:
从头开始
开始继续
更新正在运行
开始完成
更新正在运行
更新正在运行
更新正在运行
...
答案 1 :(得分:1)
这是我的方法:
假设您有两个单性行为A和B。假设B必须在A之后初始化。
1-)创建一个函数,即“ Initialise”,并在B而不是Start函数中使用它:
df = {}
for item in data:
if 'features' in item:
if 'properties' in item:
nn = item.get("properties").get("PRI_NEIGH")
if 'geometry' in item:
coords = item.get('geometry').get('coordinates')
df[nn] = coords
df_n=pd.DataFrame(df)
2-)在A obj中引用B obj,在准备好初始化后使用bObj.Initialise:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class B : MonoBehaviour
{
public void Initialise()
{
//Code you run on Start()
}
}
最后,如果您希望在任何时候运行Update函数,我通常更喜欢使用某些东西作为标志。因此,这是我的第二个B类版本,用于控制update()行为:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class A : MonoBehaviour
{
public B bObj;
// Start is called before the first frame update
void Start()
{
//Things to do in Start()
//...
//...
//...
bObj.Initialise();
}
}
答案 2 :(得分:0)
很难说出问题的实际出处,因为您尚未发布任何代码。但是,我相信您可以通过实施2
是的,如果启用/激活了游戏对象/单行为,则在更新功能之前调用所有“开始功能”(和“唤醒”)!未激活的游戏对象上不会调用开始/唤醒/更新
您应该查看Script Execution Order
。在这里,您可以确保按特定顺序调用类的启动/唤醒/更新功能。它应该在项目设置下列出。
初始化场景时,将在所有唤醒/开始功能完成后调用更新(除非将它们定义为协程,但这可能不是您的问题)。