Errors changing scene

I am definitely running into some sort of problem with changing scenes.

I have paired the project back to the minimum possible, and I still can’t make head or tail of it. I’ve taken out everything except two scenes, with a single background each, and one script, which simply initializes, waits three seconds and then changes scene.

The first scene change happens OK, but then the second gets the error trace below (and it doesn’t matter which scene you start from).

Note that scene 2 appears to be initialised 7 times, and we then get 7 attempting to change to scene 1s. Then 1 Scene 1 initialisation (which I think is correct and starts to work) and then lots of errors, which I believe may be the other scene changes trying to happen, and everything just getting messed up.

I cannot for the life of me work out why this is happening, or why we get 7 (a randomish number - I’ve had as few as 4 or 5 and as many as 23 - although not since I paired the project back. It’s usually 7 or 8 now, so maybe a timing thing?

I would be very grateful for any help that anyone can offer, as I believe that this problem is all that’s standing between me and a successful prototype. Thanks!

https://playcanvas.com/editor/scene/597697

Nich

Scene 1: GiftieLoader Init    GiftieLoader.js?id=11637244:22
7 Scene 1: Updating to Scene 2   go-on.js?id=11638931:14
7 Scene 2: Go-On Init   go-on.js?id=11638931:23
7 Scene 2: Go-on Updating to scene 1   GiftieLoader.js?id=11637244:5
 Scene 1: GiftieLoader Init

 Uncaught TypeError: Cannot read property 'priority' of null
    at Func.get (playcanvas-stable.dbg.js:21481)
    at playcanvas-stable.dbg.js:22729
    at Array.sort (/native)
    at Func.sortCamerasByPriority (playcanvas-stable.dbg.js:22728)
    at Func.onSetPriority (playcanvas-stable.dbg.js:22548)
    at Func.fire (playcanvas-stable.dbg.js:628)
    at Func.<anonymous> (playcanvas-stable.dbg.js:21474)
    at Func.fire (playcanvas-stable.dbg.js:628)
    at Func.set (playcanvas-stable.dbg.js:21486)
    at Func.<anonymous> (playcanvas-stable.dbg.js:21445)
get @ playcanvas-stable.dbg.js:21481
(anonymous) @ playcanvas-stable.dbg.js:22729
sortCamerasByPriority @ playcanvas-stable.dbg.js:22728
onSetPriority @ playcanvas-stable.dbg.js:22548
fire @ playcanvas-stable.dbg.js:628
(anonymous) @ playcanvas-stable.dbg.js:21474
fire @ playcanvas-stable.dbg.js:628
set @ playcanvas-stable.dbg.js:21486
(anonymous) @ playcanvas-stable.dbg.js:21445
initializeComponentData @ playcanvas-stable.dbg.js:21443
initializeComponentData @ playcanvas-stable.dbg.js:22694
addComponent @ playcanvas-stable.dbg.js:21427
_openComponentData @ playcanvas-stable.dbg.js:32487
_openComponentData @ playcanvas-stable.dbg.js:32493
parse @ playcanvas-stable.dbg.js:32454
open @ playcanvas-stable.dbg.js:31617
open @ launch.js:10130
_loaded @ playcanvas-stable.dbg.js:20737
_preloadScripts @ playcanvas-stable.dbg.js:20793
(anonymous) @ playcanvas-stable.dbg.js:20746
(anonymous) @ launch.js:10120
setTimeout (async)
(anonymous) @ launch.js:10119
loadScene @ launch.js:10721
Editor.call @ launch.js:6262
load @ launch.js:10116
loadSceneHierarchy @ playcanvas-stable.dbg.js:20729
GoOn.loadScene @ go-on.js?id=11638931:38
GoOn.changeScene @ go-on.js?id=11638931:30
GoOn.update @ go-on.js?id=11638931:22
_scriptMethod @ playcanvas-stable.dbg.js:23363
_onUpdate @ playcanvas-stable.dbg.js:23400
_callComponentMethod @ playcanvas-stable.dbg.js:23627
_onUpdate @ playcanvas-stable.dbg.js:23637
fire @ playcanvas-stable.dbg.js:628
update @ playcanvas-stable.dbg.js:21411
update @ playcanvas-stable.dbg.js:20962
(anonymous) @ playcanvas-stable.dbg.js:21311
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
requestAnimationFrame (async)
(anonymous) @ playcanvas-stable.dbg.js:21305
1075playcanvas-stable.dbg.js:21481 Uncaught TypeError: Cannot read property 'enabled' of null
    at Func.get (playcanvas-stable.dbg.js:21481)
    at Func._callComponentMethod (playcanvas-stable.dbg.js:23624)
    at Func._onUpdate (playcanvas-stable.dbg.js:23637)
    at Function.fire (playcanvas-stable.dbg.js:628)
    at Function.update (playcanvas-stable.dbg.js:21411)
    at Application.update (playcanvas-stable.dbg.js:20962)
    at playcanvas-stable.dbg.js:21311

I believe I’ve fixed it. https://playcanvas.com/editor/scene/597962

The problem is that changing scene is not instant (I think it is asynchronous) and therefore in the update loop of both scripts, you are constantly loading a scene every frame after 3 secs which is additive hence the multiple initialisation and update calls.

The heavier the scene, the longer it takes to load which is probably why you have a higher number of initialises until you have paired the project back.

I’ve added a flag to gate the load scene call in the update which has solved the issue :slight_smile:

Oh… So what you’re saying is that changing scene doesn’t stop the update occurring, and so I’m queuing multiple scene changes on top of each other, because I need a lockout (or an additional post-scenechange state).

Got it. Makes complete sense. Thank you!

To be more accurate, there is no concept of ‘changing’ scene in PlayCanvas.

PlayCanvas loads scenes additively and asynchronously meaning it adds the loaded scene to the current graph node hierarchy. (Which is why to ‘change’ scene, you have to delete the previous scene root after the new one is fully loaded).

As it is asynchronous, update is still called as normal.

So if scene one looks like this:

Root
|- EntityFoo

And scene two looks like this:

Root
|- EntityBar

If you start in scene one and load scene two, it will look like this

Root
|- EntityFoo
Root
|- EntityBar

That makes a lot of sense, although I was hoping to be able to use that to keep a single piece of music going across multiple scenes without stopping, by having a first scene that was just music, and immediately chaining to the next scene, and only deleting the “proper” scene each time, leaving the music scene alone, but although deleting the “Old Hierarchy” does indeed appear to leave the music scene “Root” intact, the music stops.

Is there an official way to achieve what I want to do? In Unity, I believe it’s “DontDestroyOnLoad” to keep stuff hanging about during scene changes.

PlayCanvas doesn’t have this but there are a couple of approaches I can think of using (I’ve not done this before as I normally just have one scene and activate/deactivate entities):

  • Reparent anything you want not to be destroyed to pc.app.root (note that this is NOT the Root entity you see in the editor of the scene, it’s one level higher). Problem is that if you reload the scene, you have to check if it already exists and destroy/disable the ‘new’ one if it does.
  • Have a scene that holds all your “DontDestroyOnLoad” entities and load on start and rename the Root entity to something different. Load the other scenes at the same time/after this scene is loaded.

I had a little play with re-parenting, but couldn’t make it work immediately, so ended up creating a “super-scene”. I’ll have another look at that when I have time.