Hi everyone,
I’m working on a PlayCanvas application where the main scene (Dashboard) manages the game state and UI (HTML/CSS-based). From there, the user can load other scenes (like a “Virtual World” or additional mini-games).
I load these extra scenes additively, and when the user exits them, I attempt to remove them completely. The goal is to fully unload a scene, so if the user returns to it later, it behaves exactly like it did the first time — fully fresh, without any lingering data or behavior.
Here’s the problem:
After unloading and reloading a scene (e.g., the Virtual World), I start getting errors, likely due to script instances or references persisting even after I believe the scene has been removed. It seems like not everything is getting deleted — perhaps textures, script components, or other memory objects are still hanging around.
In other engines, removing a scene usually clears everything (scripts, assets, state). But in PlayCanvas, that doesn’t seem to happen automatically.
Key points:
- I load scenes additively and remove them when not needed.
- I don’t want to switch scenes entirely, as the main Dashboard scene needs to stay active.
- On first load, everything works perfectly. On subsequent loads (after unloading), I encounter issues.
- I suspect it’s due to script instance references like
MyScript.instance = this;
not getting properly destroyed.
Questions:
- How can I ensure that an added scene is completely removed (all entities, script instances, assets)?
- What is the best practice in PlayCanvas to re-add a previously removed scene cleanly, as if it were loaded the first time?
I also checked the documentation and integrated the logic based on it, so adding and deleting a scene isnt a problem and seems to work - its like i havent thought about something when trying to add a scene a second time (for example if the user reenters the virtual world or a minigame)
Maybe I’ve missed something important or need to handle cleanup differently. Any best practices or common pitfalls when working with dynamic scene loading/unloading in PlayCanvas would be greatly appreciated.
Thanks in advance!
References:
Scene adding:
SceneManager.prototype._loadSceneHierarchy = function (_scene) {
// define root entity
if(_scene == 'virtual-world')
this.sceneRootEntity = this.rootVW;
else{
this.sceneRootEntity = this.rootSubScene;
}
// loading
if (!this._loadingScene) {
this._loadingScene = true;
// remove the current scene that is loaded if scene root
if (this.sceneRootEntity.children.length > 0) {
this.sceneRootEntity.children[0].destroy();
}
var self = this;
var scene = this.app.scenes.find(_scene);
// load scene additional
this.app.scenes.loadSceneHierarchy(scene, function (err, loadedSceneRootEntity) {
if (err) {
console.error(err);
} else {
loadedSceneRootEntity.reparent(self.sceneRootEntity);
self._loadingScene = false;
}
});
// exclude scenes from scene-settings loading
if(_scene == 'game-quiz')
return;
// load the scene settings
this.app.scenes.loadSceneSettings(scene, function (err) {
if (err) {
console.error(err);
} else {
console.log('scene settings loaded');
}
});
}
};
Scene deleting:
SceneManager.prototype.destroyActiveScene = function () {
if (!this.rootSubScene) {
console.warn("No rootSubScene found.");
return;
}
const children = this.rootSubScene.children.slice();
for (let i = 0; i < children.length; i++) {
children[i].destroy();
console.log("deleted scene " + children[i].name)
}
};