Scene Loading Speed

I’m getting about a one second delay between pressing a button and loading a different scene with very little in it. Is this normal? Is there a way to speed this up?

If it’s not possible to make the transition more seamless should I be avoiding using multiple scenes?

Thanks

That’s due to a network request being made when loading a scene to the scene data. This can be avoided by preloading the scene data via:

(There is a bug that I’m looking at when this is called multiple times at once in the Editor but for the single scene and in a published build, this should work fine)

Alternatively, you can use Templates instead and instantiate instances of hierarchy at runtime instead of using scenes.

Thanks.
In the help it says:
The scene item or URL of the scene file. Usually this will be “scene_id.json”.

…but how do I find out what the scene_id is?

I tried using straight :

this.app.scenes.loadSceneData(“scene_id.json”);

…but I just get an error.

"The scene item or URL of the scene file. Usually this will be “scene_id.json”.

You either need to pass in the relative path to the scene which would be the scene id and the extension (eg 345738.json)

Or use the Scene registry item instead

var item = this.app.scenes.find('Scene name');
this.app.scenes.loadSceneData(item, function(error, item) {});

PR made to make this clearer in the docs: https://github.com/playcanvas/engine/pull/3173

Thanks. I got this working if I call it just before the loadSceneHierarchy function, however this way seems to mean that the fast loading of scenes only happens from the second time onwards.(The very first time you try to load the scene it is slow)

So in trying to fix this, I tried adding the function for each scene on its own in my initialization of the app for all scenes like:

 //Preload Scene Data for faster loading
    var scene1 = this.app.scenes.find('Home Scene');          
    this.app.scenes.loadSceneData(scene1.url, function(error, item) {});
    var scene2 = this.app.scenes.find('Model Viewer Scene');          
    this.app.scenes.loadSceneData(scene2.url, function(error, item) {});

…but I get an error in Launch.js: TypeError: app.root.getByGuid is not a function

The preload still takes time to actually load. When it has finished loading, the callback is fired.

Once it has finished loading, then loadSceneHierarchy can be called without a network delay. Calling loadSceneData just before loadSceneHierarchy has no effect on the first load as loadSceneData hasn’t finished loading by the time loadSceneHierarchy is called.

You may still get a delay/frame drop/stall when loadSceneHierarchy is called as it needs to create the entities and initialise them.

As I mentioned above:

The workaround is to load the scene one after the previous one has finished loading (ie a callback chain)

Or use templates which may be easier.

I tried the callback chain but still get an error. Using templates would mean some heavy refactoring so its not really an option I want to pursue. (I might have chosen that route to start with if I’d known about the scene loading delay.)

Example of the callback loading method here: https://playcanvas.com/editor/scene/1155281

https://playcanvas.com/editor/code/796865?tabs=47903718

// Hacky, but just to show you what I mean:
   var self = this;
    self.app.scenes.loadSceneData(self.app.scenes.find(self.sceneFilenameStrings[0]), function (error, sceneRegistryItem) { 
        if (error) {
            console.error(error);
        } else {
            self.app.scenes.loadSceneData(self.app.scenes.find(self.sceneFilenameStrings[1]), function (error, sceneRegistryItem) { 
                if (error) {
                    console.error(error);
                } else {
                    self.app.scenes.loadSceneData(self.app.scenes.find(self.sceneFilenameStrings[2]), function (error, sceneRegistryItem) { 
                        if (error) {
                            console.error(error);
                        } 
                    });
                }
            });
        }
    });

Wouldn’t have thought it be too difficult. Open the scene, make the scene root a template and change the loading code from scenes.load etc to instantiate the template into the current scene.

1 Like

Okay Thanks. Using your chained example worked perfectly. I must have been doing something else wrong with my callback syntax.
Cheers

1 Like

I have a fix in review for this issue so you don’t have to do this chain callback

This is now fixed and released in the editor: https://github.com/playcanvas/editor/releases/tag/v1.18.6

This code should now work:

    var scene1 = this.app.scenes.find('Home Scene');          
    this.app.scenes.loadSceneData(scene1.url, function(error, item) {});
    var scene2 = this.app.scenes.find('Model Viewer Scene');          
    this.app.scenes.loadSceneData(scene2.url, function(error, item) {});
1 Like