Entity.script not found

What determines if entiry.script is there or not? I have a “prefab” of my Player - a (disabled) enity with a model, collision and rigifbody + some scripts like playerMovement.js.

Now, I clone this entity with

var player1 = this.PlayerPrefab.clone();                                    
player1.setPosition(0, 0, 0);
this.app.root.addChild(player1);  
player1.enabled = true;                  
console.log("player1.script", player1.script); //undefined, why?

I dont understand why the .sciprt is not available at this point?

Same seems to be true for player1.collision (even though the “prefab” DOES have a collision component)

Code looks fine, can you link to your project please ?

The project in question is private and I’d rather not share it publicly. Can you even access private projects?

Also turns out my code in my original post the issue is not present…although in the console when I do console.log(“player1”), the .script property is missing:

That’s interesting, this entity doesn’t have the script component nor any collision or rigidbody components. Where do you execute that code @jariwake?

Could you also share a screen grab of the inspector when you have that entity selected in editor?

I did some more research, and I think its my player initialization code that causes the problem afrer all, I have to dig into it. It works on the first time, but after destroying a player, cloning a new one and then trying to access other script via script.someOtherScriptOnMyPlayerEntity, the .script is undefined.

Anyway, heres how my player “prefab” looks like:

Entity looks fine, it should work, so yes if you keep having trouble try sharing a bit more of your code to take a look.

Do you think you can reproduce this error in a new project that you could share?

Yeah, I am setting up a dummy project that would reproduce the issue. I’ll post it once I get there.

However, I think I might have an idea why I am getting this entity.script beign undefined (which then least to Uncaught TypeError: Cannot read property ‘playerMovement’ of undefined) - my game is a multiplayer game where the player entity gets destroyed on disconnect, and (re)cloned on connect. For some reason, the destroy() does not actually destroy the player entity of the first session, and on the second session when I click the mouse button to move the player, the code on the player entity of the first session gets invoked.

Does this sound like it might be the issue to you guys? I tried adding event unscubscription on destory, but that didnt solve the issue. This is essesntially what I have now:

LocalPlayerInputHandler.prototype.initializeInputHandler = function(side) {            
    if(this.app.mouse.on) {
        console.log("SUBSCRIBE", this.entity._guid);        
        this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this);
    }
        
    var self = this;
    this.on('destroy', function() {
        console.log("UNSUBSCRIBE", self.entity._guid);
        self.app.off(pc.EVENT_MOUSEDOWN, self.onMouseDown);
    });
};

Are there any other reasons that would explain why destory doesnt actually destory an entity?

@yaustar @Leonidas ok I recreated the problem in an other simpler project. Here is the URL to it: https://playcanvas.com/project/711558/overview/bounce

Nevermind the game itself, just click anywhere on the game with a mouse and observer the error “Uncaught TypeError: Cannot read property ‘testScript’ of undefined” in the console.

The error occurs in Movement.js on line 38 because for some reason, the mouse click code is invoked in the already destroyed player instance. The player cloning and destorying happens in manager.js. If you remove the destroying and cloning the second player, there is no issue.

Ah so, this makes it clearer what the issue is, update your on destroy callback to remove the event listener on the mouse instance, not on the application instance:

    this.on('destroy', function() {
        console.log("---- UNSUBSCRIBE", self.entity._guid);
        self.app.mouse.off(pc.EVENT_MOUSEDOWN, self.onMouseDown);
    });
2 Likes

Ah, thanks a lot! That solved the problem. I somehow missed the .mouse. in between.

Btw, is there any way to check if destroy() is/was actually able to destroy the entity (other than manually check it afterwards)?

Mmm, I haven’t encountered ever any issue with calling destroy() that wouldn’t destroy and remove the entity from the entity hierarchy.

The behavior you were getting due to the error, is mostly JS related. A JS object will be cleared and garbage collected when all references to it has been released. Because you weren’t removing the event handler from the deleted entity, its JS object reference was still available in memory that’s why your console.log(entity._guid) worked and printed a guid.

That wasn’t a guid of an entity that existed at that instant in the Playcanvas scene hierarchy though, it was successfully destroyed as far as Playcanvas is concerned.