[SOLVED] Using events, losing access to objects due to scope

Yes, I’m stuck again. :stuck_out_tongue:

I’m trying to respawn a player entity, using this:

http://developer.playcanvas.com/en/user-manual/scripting/events/

I have the app.fire(“respawn”) on my code for the death trigger(just a bottomless hole trigger for now).

The player has this in their code, under initialize():

respawn: function () {
    console.log("respawn was heard by player object, attempting a respawn.");
    this.entity.rigidbody.teleport(this.spawnpoint.getPosition,this.spawnpoint.getRotation);
    this.entity.rigidbody.linearVelocity = new pc.Vec3(); //erase any velocity
    this.entity.rigidbody.angularVelocity = new pc.Vec3(); //erase any rotational velocity
},

I know the code is firing, because the console will show the “respawn was heard” text. But it instantly crashes out after that when I try to access this.entity. Anything to do with the entity, or anything on the listening object for that matter, will return a null or similar error about the object not existing, and this.spawnpoint also no longer exists if I call console.log(this.spawnpoint) (It was a property setup in the editor on the player object, pointing to the entity for a spawn point).

Is this another problem of scope? How am I supposed to be using these to manipulate anything?

Is the example on the documentation page supposed to be able to do things to the “Display” entity with the x and y values? It doesn’t show a path to actually manipulate the listening object in the example code, so I’m rather lost. The other example of it’s use show to use app. in order to make global messages, but then the object scope is wrong? This is the only other example of fire() being used I found in the docs:

http://developer.playcanvas.com/en/tutorials/beginner/keepyup-part-three/

Surely every object doesn’t need to pass a reference to itself down every single “fire” event call just to enable accessing their data from each other?

Looks like you aren’t calling getPosition and getRotation correctly. this.spawnpoint.getPosition() (note brackets)

Also, you can use pc.Vec3.ZERO to reset the velocity which stops you allocating a new vector every time you respawn.

1 Like

Ok, that helped a bit. At least the function should be working now. Can’t believe I missed the ()s.

If I copy and paste the three lines into other functions, it works, I think.

I say I think, because I got a grey screen after the teleport line. The camera is parented to the player, so maybe there is a bug or something weird happening there, because the whole playcanvas seems to just hang on rendering when the camera teleports. (The power bar GUI still renders fine, so maybe the camera simply has lost it’s position in space entirely somehow? The screen is grey, which is the default “clear” color of the camera rendering.) It appears the camera stops rendering if I teleport it. The documentation doesn’t seem to mention anything other then each scene needs at least a single rendering camera, and the teleport command doesn’t mention using it(or not to use it) on cameras either. Maybe a bug?

I tried unparenting the camera from the player just so I could see what was happening, and the player object vanishes off into space somewhere out of view (with the spawnpoint clearly in view of the camera) when the teleport command is triggered. So something is not working right with the teleport. Where is Scotty when you need him?

Regardless of the above teleport strangeness, I’m still unable to get the object reference in my own reset function if I try using the message system to trigger it. I get this error now:

[Robot_movement.js:128]: Uncaught TypeError: Cannot read property 'rigidbody' of undefined

I don’t understand why I’m getting this error, because the respawn function should be on the same scope as the other code functions I just tested pasting it into. At least I think so? Here’s the code I got for responding to a respawn, right underneath the standard initilize function in the main script object:

respawn: function () {
    console.log("respawn was heard by player object, attempting a respawn.");
    //console.log(this);
    this.entity.rigidbody.teleport(this.spawnpoint.getPosition(),this.spawnpoint.getRotation());
    this.entity.rigidbody.linearVelocity = pc.Vec3.ZERO; //erase any velocity
    this.entity.rigidbody.angularVelocity = pc.Vec3.ZERO; //erase any rotational velocity
},

As you can see, this is just a basic function called by the listen trigger I’ve set up like so:

initialize: function () {
    //vector for calculating movement speed
    this.drive_vector = new pc.Vec3();
    this.drive_originalFriction = this.entity.rigidbody.friction; //save the editor friction
    
    //if "respawn" event is heard, lose all boosts and reset control inputs.
    app.on("respawn", this.respawn);
},

Yet when the kill object sends the “respawn” message, the function seems unable to find the player object even though the player object is the one responding to the message.

Mysterious things appear to be happening all over this piece of code, and I don’t know why. More help please?

There is a 3rd argument for the on method which is the scope that should be used for the event handler. So do app.on("respawn", this.respawn, this)

2 Likes

That seemed to do the trick, thanks! I had missed the scope argument, which left the code off in lala land when looking for the variables. It’s always the simple things like this that seem to get me.