3.6.2关于preloadScene的一些疑问

  • director.preloadSceneonLoaded 回调中并没有 SceneAsset 参数。

  • 使用 director.preloadScene 的方式预加载场景对场景切换速度的提升不如另外两种方式:

    • 使用 resources.loadScene 的方式预加载场景,需要被加载的场景在 resources bundle 中:

      import { _decorator, Component, Node, SceneAsset, director, resources } from 'cc';
      const { ccclass, property } = _decorator;
      @ccclass('Scene1')
      export class Scene1 extends Component {
          private testScene: SceneAsset = null;
          onBtnDirectorPreloadClick() {
              console.log("call director.preloadScene");
              director.preloadScene("TestSceneInsideResourcesDir", (err, sceneAsset) => {
                  if (!err) {
                      this.testScene = sceneAsset;
                      console.log('preload success', sceneAsset);
                  }
              });
          }
      
          onBtnResourcesPreloadClick() {
              console.log("call resources.loadScene");
              resources.loadScene('TestSceneInsideResourcesDir', (err, sceneAsset) => {
                  if (!err) {
                      this.testScene = sceneAsset;
                      console.log('preload success', sceneAsset);
                  }
              });
          }
      
          onBtnLoadClick() {
              console.log("call director.loadScene");
              globalThis.lastTestTime = (new Date()).getTime();
              director.loadScene("TestSceneInsideResourcesDir")
          }
      
          onBtnRunClick() {
              if (this.testScene) {
                  console.log("call director.runScene");
                  globalThis.lastTestTime = (new Date()).getTime();
                  director.runScene(this.testScene);
              } else {
                  console.error('this.testScene = ', this.testScene);
              }
          }
      }
      
      Scene1.ts:9 call director.preloadScene
      Scene1.ts:13 preload success undefined
      Scene1.ts:29 call director.loadScene
      director.ts:461 LoadScene TestSceneInsideResourcesDir: 96.21142578125 ms
      Test.ts:10 In Test scene onLoad, time diff is: 100
      

      可以看到使用 director.preloadScene 的方式 time diff 是 100

      Scene1.ts:19 call resources.loadScene
      Scene1.ts:23 preload success SceneAsset {_objFlags: 0, _name: 'TestSceneInsideResourcesDir', _callbackTable: {…}, loaded: true, _native: '', …}
      Scene1.ts:29 call director.loadScene
      director.ts:461 LoadScene TestSceneInsideResourcesDir: 7.18017578125 ms
      Test.ts:10 In Test scene onLoad, time diff is: 11
      

      使用 resources.loadScene 的方式 time diff 是 11,看日志差别可以说是非常大了,在我的测试场景下大概有 9 倍的差距

    • 如果被加载的场景不在 resources bundle 中,那就是下面这样加载,直接拖到组件中:

      import { _decorator, Component, Node, SceneAsset, director } from 'cc';
      const { ccclass, property } = _decorator;
      @ccclass('Scene2')
      
      export class Scene2 extends Component {
          @property(SceneAsset)
          testScene: SceneAsset = null;
          onRunSceneClick() {
              console.log("call director.runScene");
              globalThis.lastTestTime = (new Date()).getTime();
              director.runScene(this.testScene);
          }
      }
      
      Scene2.ts:10 call director.runScene
      Test.ts:10 In Test scene onLoad, time diff is: 10
      

      可以看到和上面 resources.loadScene 的方式方法一样快,但是这种方式在一些情况下似乎有bug:V3.6.2场景切换报错,有工程文件

      上面的结果都是在 Windows10 Chrome 的环境下得到的,我认为实际上开发者的预期是使用 director.preloadScene 就能达到 resources.loadScene 的效果,否则就没有使用 director.preloadScene 这种方法的意义,但目前看来并不是这样;在我的开发环境中项目是运行在应用的 WebView 中的,这种差别特别明显,当我尝试用上面第2中方法优化的时候又带来了其他问题

  • 在使用 director.preloadScene 预加载场景之后使用 director.loadScene 切换场景,目标场景的依赖的资源越多,切换场景耗时越多;但是使用上面另外两种更快的预加载方式时,目标场景的依赖的资源数量好像不影响切换的耗时,这似乎说明现在 director.preloadScene 内部的处理逻辑与想象的不太一样

TestProject_1116.zip (800.4 KB)
这是我用来测试的工程,在 Chrome 中预览 Scene1 和 Scene2 就能测试

哈哈,我也发现了这个问题,浅显地研究了下,发现在浏览器上preload方法只会加载scene依赖的json文件,但是图片文件并不会被加载,所以load的时候需要加载scene上面的图片,耗时就会比较久,但是直接load场景并没有这个问题,目测应该是preload的bug

不是bug,其实就是不会去解析这个JSON