背景
有些属性或方法只能在主线程中调用,如 .gameObject、Instantiate() 等。这是 Unity 设计时的一个缺陷(为了保证线程安全),多年来一直没有修正,或者说官方懒得弄。
以 Instantiate() 为例,在非主线程调用时,报错大概如下所示。其他属性或方法的报错也大体相同。
注:应注意,此问题在有些情况下 Unity 控制台不会提示任何错误,只是代码会在那里中断,这时可能会让人非常摸不着头脑。使用 try { } catch (Exception e) { Debug.Log(e); }
才能在控制台中显示出错误,以便验证是不是本文所述问题。
解决方法
使用第三方包:https://github.com/PimDeWitte/UnityMainThreadDispatcher.git
步骤 1
优雅导入法:
在 Unity 中,Window -> Package Manager -> 加号 -> Add package from git URL,输入上面的仓库地址,Add。
或者
修改 Packages\manifest.json,在 dependencies 中加入一行:
粗暴导入法:
解压第三方包之后直接丢到Assets里
步骤 2
把UnityMainThreadDispatcher
脚本挂载到场景里的对象上即可
步骤 3
在你的代码中,按照下面的方法调用原来出问题的语句,问题解决。