[SOLVED] Changing Scenes and destroying old scene

Hey all,

I have been having trouble deleting the old scene hierarchy when I load up a new scene.

I followed the exact code in the tutorial https://developer.playcanvas.com/en/tutorials/changing-scenes/ and still couldn’t get it to work. Also I forked the project and ran it without any changes and it is behaving different than what is shown on the tutorial page.

Here is what I am trying to do:

SceneManager.js

var SceneManager = pc.createScript('sceneManager');

SceneManager.StartSceneID = 541612;
SceneManager.GameSceneID = 541418;

// initialize code called once per entity
SceneManager.prototype.initialize = function() {
    //this.root = this.app.root.findByName('Root');
    
    this.app.keyboard.on(pc.EVENT_KEYDOWN, this.onKeyDown, this);
    
};

// update code called every frame
SceneManager.prototype.update = function(dt) {
    
};

SceneManager.prototype.onKeyDown = function(button){
    
    if(button.key === pc.KEY_1){

        this.GoToStartScreen();
    }
    
    if(button.key === pc.KEY_2){
        this.GoToGameScene();
    }
    
};


SceneManager.prototype.GoToStartScreen = function(){
      this.changeScenes(SceneManager.StartSceneID);
};

SceneManager.prototype.GoToGameScene = function(){
      this.changeScenes(SceneManager.GameSceneID);
};

SceneManager.prototype.changeScenes = function(sceneId){
    
    var oldHierarchy = this.app.root.findByName ('Root');
    oldHierarchy.destroy();
    
    this.loadScene (sceneId, function () {
        console.log("scene loaded: " + sceneId);

    });
};

SceneManager.prototype.loadScene = function(id, callback){
    //path to the scene
    var url = id + ".json";  
    
    //load the scenes entity hierarchy
    this.app.loadSceneHierarchy(url, function(err, parent){
        if(!err){
            callback(parent);
        } else {
            console.error (err);
        }
    });
};

I want to eventually have a folder entity that persist throughout all the scenes and contains scripts I want to carry over between them. this would include the scenemanager.

The scenemanager is only on the first scene. when I change to the second scene the old hierarchy is deleted which should mean that the scenemanager script should no longer be available. Why is it that I can still use the scenemanager when in the second scene? Any help with understanding scene changes would be very helpful, I have been trying to get this to work for some time now.

UPDATE

I have found a solution. The problem I was running into was that I could switch from my start scene to my game scene no problem, but when I tried to go back to the start screen it would error out. This was because it was reloading the entities that I was passing back and forth and causing me to get duplicate entities causing a lot of bugs and hard to read errors.

the solution:
I made another scene. An InitScene that would only contain the entities I wanted to persist between moving scenes. I would automatically pass this into the StartingScene and along with it add the entity to the hierarchy.

New SceneManager.js

var SceneManager = pc.createScript('sceneManager');

SceneManager.InitSceneID = 541657;
SceneManager.StartSceneID = 541612;
SceneManager.GameSceneID = 541418;

// initialize code called once per entity
SceneManager.prototype.initialize = function() {
    
    this.app.keyboard.on(pc.EVENT_KEYDOWN, this.onKeyDown, this);
    
    console.log("scene manager init");
    
    this.currentScene = SceneManager.StartSceneID;
    
    this.GoToStartScreen();
    
};

// update code called every frame
SceneManager.prototype.update = function(dt) {
    
};

SceneManager.prototype.onKeyDown = function(button){
    
    if(button.key === pc.KEY_1){
        console.log("pressed 1");
        console.log("change scene");
        
        if(this.currentScene === SceneManager.StartSceneID){
            this.currentScene = SceneManager.GameSceneID;
            this.changeScenes(SceneManager.GameSceneID);
        }else{
            this.currentScene = SceneManager.StartSceneID;
            this.changeScenes(SceneManager.StartSceneID);
        }
    }
    
};


SceneManager.prototype.GoToStartScreen = function(){
      this.changeScenes(SceneManager.StartSceneID);
};

SceneManager.prototype.GoToGameScene = function(){
      this.changeScenes(SceneManager.GameSceneID);
};

SceneManager.prototype.changeScenes = function(sceneId){
    
    var oldHierarchy = this.app.root.findByName ('Root');
    
    var managers = this.app.root.findByName('Managers');
    
    oldHierarchy.removeChild(managers);
    
    this.loadScene(sceneId, function (newHierarchy) {

        console.log(oldHierarchy);
        
        newHierarchy.addChild(managers);
        
        oldHierarchy.destroy();

        console.log(newHierarchy);
    });
};

SceneManager.prototype.loadScene = function(id, callback){
    //path to the scene
    var url = id + ".json";  
    
    //load the scenes entity hierarchy
    this.app.loadSceneHierarchy(url, function(err, parent){
        if(!err){
            callback(parent);
        } else {
            console.error (err);
        }
    });
};

I hope this could help someone else out in the future

5 Likes

This is very helpful.

Thanks!!