Version: 1.3
语言 : 中文
小游戏启动加速
功能强化

微信小游戏Object.InstantiateAsync

用户代码中调用Instantiate时,引擎内分为两步执行:

  • 通过transfer序列化构建出对象;
  • 通过IntegrateMainThread初始化新创建的对象,进入引擎事件生命周期。 使用同步Instantiate时,这两步会在同一帧内完成。

异步InstantiateAsync与同步接口的区别在于:

  • 对于单次InstantiateAsync调用,上述两步将拆分到两帧完成;
  • 执行第一步transfer序列化构建对象时,会使用JobSystem来加速,但依旧会在一帧内完成;
  • 在第二步IntegrateMainThread增加了一个队列。如果单帧时间内有多次的InstantiateAsync调用,则可根据IntegrationTime 的时间长度,分多帧完成。

微信小游戏分帧Integration

由于微信小游戏是单线程,使用JobSystem加速transfer序列化构建对象无法达到预期的效果。另外对于单次实例包含大量对象, 例如包含Collider、Renderer等的Prefab,在完成IntegrateMainThread进入引擎事件生命周期后,首次更新会有较长的创建物理几何体,编译shader等耗时。

从实际的测试来看,执行第二步IntegrateMainThread所在的那一帧总时间远高于执行第一步构建对象所在的帧。 因此在微信小游戏平台上,我们对第二步IntegrateMainThread做了进一步分帧处理,允许单次InstantiateAsync调用能够拆分成更多帧执行。 当前版本为保证Renderer和粒子等继承自Behaviour的对象运行时序正确,允许最多分成4帧执行。纹理、shader等资源以及用户的MonoBehaviour不受该限制影响。

Instantiate
Instantiate
InstantiateAsync
InstantiateAsync
实例化总耗时 单帧最高时长 7帧总耗时 平均每帧耗时
Instantiate 73.2ms 73.2ms 160ms 22.8ms
InstantiateAsync 84ms 35.6ms 135ms 19.2ms

从测试结果看,在实例化相同的对象时,单帧最高时长为73.10ms。替换为InstantiateAsync后,降低为35.6ms。另外,异步接口因为将工作负载拆分到了4帧完成,7帧总耗时降低为135ms,同步接口耗时约160ms。

InstantiateAsync 的分帧效果受IntegrationTime时长设置影响较大,默认为每帧2ms, 可通过AsyncInstantiateOperation.SetIntegrationTimeMS 接口设置时长。更小的值能够减少卡顿,但会延长实例化的总耗时。

使用InstantiateAsync()接口时需要注意,在完成对象的实例化前,不能提前卸载对象所在的AB和其依赖AB。否则可能出现材质或prefab引用丢失的情况,导致游戏逻辑或渲染出错。

小游戏启动加速
功能强化