[SOLVED] Scripts not call initialize when enable it dynamically?

My camera entity have two scripts:

  • fpsCamera: the user can move to anywhere he want.
  • cameraPath: the user’s movement must follow the path defined by system.

The user can enable only one script at the same time. So I need to enable/disable the other script dynamically.

Here is my scripts of camera:

FpsCamera.prototype.initialize = function() {
    console.log('fps camera initialize.');
  this._initialize();
  this.on("state", function (enabled) {
    console.log('state changed: ', enabled);
  });
  this.on('enable', function() {
    console.log('fps camera enabled.');
    this._initialize();
  });
  this.on('disable', function() {
    console.log('fps camera disabled.');
    this.entity.collision.off('collisionstart');
  });
};
CameraPath.prototype.initialize = function() {
    console.log('camera path initialize.');
    this.camera = this.entity.findByName('Camera');
    this.createPath();
    this.on("attr:pathRoot", function (value, prev) {
        if (value) {
            this.createPath();
            this.time = 0;    
        }
    });
    
    this.on("attr:time", function (value, prev) {
        this.time = pc.math.clamp(this.startTime, 0, this.duration);    
    });
    
    this.time = pc.math.clamp(this.startTime, 0, this.duration);    
    
    // Caching some Vec3 objects that will be used in the update loop continously 
    // so we don't keep triggering the garbage collector
    this.lookAt = new pc.Vec3();
    this.up = new pc.Vec3();
};

I switch scripts by the following code:

LeftSideBar.prototype.switchToFreeMode = function() {
    this.currentMode = LeftSideBar.FREE_MODE;
    this.player.script.cameraPath.enabled = false;
    this.player.script.fpsCamera.enabled = true;
};

LeftSideBar.prototype.switchToWanderMode = function() {
    this.currentMode = LeftSideBar.WANDER_MODE;
    this.player.script.cameraPath.enabled = true;
    this.player.script.fpsCamera.enabled = false;
};

However, I got error when switch script:

What I have try:

  • implement swap function
  • listen state/enable/disable event

But the error still here, and the swap function didn’t call, the state/enable/disable event callback didn’t call too, I have no idea how to solve it.
Here is my project: https://playcanvas.com/project/485551/overview/house-scene

You can try add a line when you swap cameras after you disable the script and enable the new one you can call a initCam function with the instructions you need to fire.

What do you mean? Could you please give me some code snippets?

Well as example in my initialize function i have set lot of variables, and if i disable and enable back the entity/script the initialize is not fired again so i moved all that i had in initialize into initCall function and inside initialize i just have this.initCall() the same when i enable back the function this.player.script.fpsCamera.enabled=true;
this.player.script.fpsCamera.initCall();

Oh, I see.

But I want to know why swap function and state/enable/disable's callback do not call, do you have any ideas?

Uhm i have tried your project and seems to work…so i don’t get what the problem is…you already solved that?

In fact, I add a activate attribute as workaround…

@will @ayrin
I just create a demo: https://playcanv.as/p/GS5EHnIh/
The project: https://playcanvas.com/project/476073/overview/init

There is a switch button on top right of the screen. When click it, the click listener is like:

Ui.prototype.onSwitch = function(e) {
    this.mouseInput.enabled = !this.mouseInput.enabled;
    this.touchInput.enabled = !this.touchInput.enabled;
};

There are state listener for mouseInput and touchInput, just simply like:

this.on('state', function(enabled) {
    console.log('touch input state: ', enabled);
});

By default, the mouseInput is enabled, and the touchInput is disabled.

And when you click the switch button, it should output:

mouse input state:  false
touch input state: true

But the demo only output the mouseInput’s state change, not touchInput’s state change.

I think the problem is that the touchInput start as disabled and i don’t see the activate attribute you talked about earlier, so my guess it’s that the initialize funtions of touchInput is not properly fired. But i can be wrong. You enable touchInput and make it load before the mouseInput and when mouseInput is initialized you disable touchInput.

Yes, this project does not apply my workaround solution(add activate attribute).
My idea is the same as yours. Maybe I need to call the initialize function of touchInput manually. Something like:

Ui.prototype.onSwitch = function(e) {
    this.mouseInput.enabled = !this.mouseInput.enabled;
    this.touchInput.enabled = !this.touchInput.enabled;
    if (!this.touchInput.orbitCamera) {
        this.touchInput.initialize();
    }
};

You just have to try and see wich one works :slight_smile: