I don’t know what I am doing wrong in this code. I have assigned this code to an Entity with a collider on it.
Now when I enter the volume I get this error:
“Uncaught TypeError: Cannot set property ‘enabled’ of undefined”
I also placed a console.log on it to see if the object in the scene is found. And it is found.
var TriggerVolume = pc.createScript('triggerVolume');
// initialize code called once per entity
TriggerVolume.prototype.initialize = function()
{
this.TriggerZone = this.app.root.findByName("Zone2");
this.entity.collision.on('triggerenter', function (entity)
{
this.TriggerZone.enabled = false;
console.log(this.TriggerZone + ' has entered trigger volume.');
}
);
this.entity.collision.on('triggerleave', function (entity)
{
console.log(entity.name + ' has left trigger volume.');
}
);
};
Hope someone can help me out.
Best,
Maarten
Hi @Maarten_deVries,
It looks like you’re having problems with scope, so when you are referring to this
in your collision event, it is referring to the scope within the collision function. To solve for this, you have two options. The first is to use a self
variable that you can reference back to like this:
var TriggerVolume = pc.createScript('triggerVolume');
// initialize code called once per entity
TriggerVolume.prototype.initialize = function()
{
var self = this;
this.TriggerZone = this.app.root.findByName("Zone2");
this.entity.collision.on('triggerenter', function (entity)
{
self.TriggerZone.enabled = false;
console.log(self.TriggerZone + ' has entered trigger volume.');
}
);
this.entity.collision.on('triggerleave', function (entity)
{
console.log(entity.name + ' has left trigger volume.');
}
);
};
The other option is to pass along the context to your collision function like this:
var TriggerVolume = pc.createScript('triggerVolume');
// initialize code called once per entity
TriggerVolume.prototype.initialize = function()
{
this.TriggerZone = this.app.root.findByName("Zone2");
this.entity.collision.on('triggerenter', function (entity)
{
this.TriggerZone.enabled = false;
console.log(this.TriggerZone + ' has entered trigger volume.');
}, this);
this.entity.collision.on('triggerleave', function (entity)
{
console.log(entity.name + ' has left trigger volume.');
}, this);
};
1 Like
thank you for the quick reply and clear explanation. I got my script working before I read this reply.
I however did it different then your answer.
var TriggerVolume = pc.createScript('triggerVolume');
// initialize code called once per entity
TriggerVolume.prototype.initialize = function()
{
var TriggerZone = this.app.root.findByName("Zone2");
this.entity.collision.on('triggerenter', function (entity)
{
TriggerZone.enabled = false;
console.log(this.TriggerZone + ' has entered trigger volume.');
}
);
this.entity.collision.on('triggerleave', function (entity)
{
console.log(entity.name + ' has left trigger volume.');
}
);
};
Instead of this.TriggerZone = this.app.root.findByName("Zone2");
I did this: var TriggerZone = this.app.root.findByName("Zone2");
and changed this.TriggerZone.enabled = false;
to TriggerZone.enabled = false;
Is this also a correct way?
HI @Maarten_deVries,
That is also a valid solution. The only thing to think about is that using var TriggerZone = this.app.root.findByName("Zone2");
will only be available inside of your initialize function. If you use this.TriggerZone = this.app.root.findByName("Zone2");
, It will be available to other top level functions of your scripts, but it is up to you whether you need it.
Yet another typical JavaScript this
pitfall.
To be brief, this
reference changes in every function
scope.
It will only refer to whatever object you’re calling the function on.
You could use the arrow function introduced in the ES6 standard to avoid this problem.
Alternatively, you could explicitly specify the this
reference at runtime by calling the .call
method of the function’s prototype.