Terrible example but rocket jumping from tf2, if the player is in a radius of the exploding object the player will then get an impulse based on their position relative to the exploding object.
So you need to cycle through each object in a certain radius and apply a force to each of them that will depend on the distance (for example - linear multiplier).
Here is an example of the logic you are interested in in another thread on stackoverflow
In my own perspective for the functionality you would do exactly what @robert.ua said for pushing dynamic entities away from the explosion. For visuals you could use the explosion demo project using the particle system made by playcanvas. If you set an event when the particle system is played to initiate a function for the force and tweak the timing right you could have a good looking and visually appealing explosion.
I have a gravity script that could be modified to do this, it pulls entities with certain tags to it, it could be modified to do the same to all dynamic entities, and just change the force of a āpullā to the center mass of the object with a script to inverted (negative) so it pushes it away and add the functionality I defined earlier.
Could I get that?
Thanks
the only issue is youād have to add either an impulse function or disable the force after explosion, as the gravity code currently constantly pulls the entity to it.
i could add that myself
var GravityScript = pc.createScript('gravityScript');
// attribute for gravity strength
GravityScript.attributes.add('gravityStrength', { type: 'number', default: 9.8 });
// attribute to select the child entity which defines the gravity radius
GravityScript.attributes.add('gravityRadiusEntity', { type: 'entity' });
// initialize script
GravityScript.prototype.initialize = function() {
this.affectedBodies = new Set();
// Listen for trigger events if the child entity has a trigger collider
if (this.gravityRadiusEntity && this.gravityRadiusEntity.collision) {
this.gravityRadiusEntity.collision.on('triggerenter', this.onTriggerEnter, this);
this.gravityRadiusEntity.collision.on('triggerleave', this.onTriggerLeave, this);
}
};
// when an object enters the gravity radius
GravityScript.prototype.onTriggerEnter = function(otherEntity) {
if (otherEntity.tags.has('11')) {
this.affectedBodies.add(otherEntity);
}
};
// when an object leaves the gravity radius
GravityScript.prototype.onTriggerLeave = function(otherEntity) {
if (otherEntity.tags.has('11')) {
this.affectedBodies.delete(otherEntity);
}
};
// called every frame
GravityScript.prototype.update = function(dt) {
this.affectedBodies.forEach(function(otherEntity) {
var distance = this.entity.getPosition().distance(otherEntity.getPosition());
var forceMagnitude = this.gravityStrength * (this.entity.rigidbody.mass * otherEntity.rigidbody.mass) / (distance * distance);
var forceDirection = this.entity.getPosition().sub(otherEntity.getPosition()).normalize();
var force = forceDirection.scale(forceMagnitude);
otherEntity.rigidbody.applyForce(force);
}, this);
};
Additionally, ensure the dynamic entities have the tags: ā11ā or change this to apply to dynamic bodies all together.
thanks ill use this after I finish a different area
Hey, its giving an error when it runs forEach(function(otherEntity) hereās the code just incase i messed something up
var Explode = pc.createScript('explode');
Explode.attributes.add("countdown", {
type: "number",
default: 5
})
// attribute for gravity strength
Explode.attributes.add('gravityStrength', { type: 'number', default: 9.8 });
// attribute to select the child entity which defines the gravity radius
Explode.attributes.add('gravityRadiusEntity', { type: 'entity' });
// initialize code called once per entity
Explode.prototype.initialize = function() {
this.precountdown = this.countdown
this.counting = true
this.affectedBodies = new Set();
// Listen for trigger events if the child entity has a trigger collider
if (this.gravityRadiusEntity && this.gravityRadiusEntity.collision) {
this.gravityRadiusEntity.collision.on('triggerenter', this.onTriggerEnter, this);
this.gravityRadiusEntity.collision.on('triggerleave', this.onTriggerLeave, this);
}
};
// update code called every frame
Explode.prototype.update = function(dt) {
this.objectPos = this.entity.getPosition()
this.push()
if (this.counting == true){
this.countdown -= dt
}
if (this.countdown <= 0){
console.log('yeh')
this.counting = false
this.countdown = this.precountdown
this.push()
}
};
// initialize script
Explode.prototype.initialize = function() {
};
// when an object enters the gravity radius
Explode.prototype.onTriggerEnter = function(otherEntity) {
if (otherEntity.tags.has('moveable')) {
this.affectedBodies.add(otherEntity);
}
};
// when an object leaves the gravity radius
Explode.prototype.onTriggerLeave = function(otherEntity) {
if (otherEntity.tags.has('moveable')) {
this.affectedBodies.delete(otherEntity);
}
};
// called every frame
Explode.prototype.push = function(dt) {
this.affectedBodies.forEach(function(otherEntity) {
var distance = this.entity.getPosition().distance(otherEntity.getPosition());
var forceMagnitude = this.gravityStrength * (this.entity.rigidbody.mass * otherEntity.rigidbody.mass) / (distance * distance);
var forceDirection = this.entity.getPosition().sub(otherEntity.getPosition()).normalize();
var force = forceDirection.scale(forceMagnitude);
otherEntity.rigidbody.applyImpulse(force * -1);
}, this);
};
// swap method called for script hot-reloading
// inherit your script state here
// Explode.prototype.swap = function(old) { };
// to learn more about script anatomy, please read:
// https://developer.playcanvas.com/en/user-manual/scripting/
The issue might be that the context of this
inside the forEach
loop is not what you expect. You can fix this by using arrow function syntax like this:
Explode.prototype.push = function(dt) {
this.affectedBodies.forEach((otherEntity) => {
var distance = this.entity.getPosition().distance(otherEntity.getPosition());
var forceMagnitude = this.gravityStrength * (this.entity.rigidbody.mass * otherEntity.rigidbody.mass) / (distance * distance);
var forceDirection = this.entity.getPosition().sub(otherEntity.getPosition()).normalize();
var force = forceDirection.scale(forceMagnitude);
otherEntity.rigidbody.applyImpulse(force.clone().scale(-1));
});
};
Hope this helps
I could better diagnose the issue having read the console logs and the launch error from the launch page if this is still not working.
Iām dumb for that ill share it if this doesnāt work
Hereās the project too just in case: PlayCanvas | HTML5 Game Engine
[explode.js?id=165694350&branchId=b2942a4a-94bf-41e2-93e8-f20607f1c95f:66]: Cannot read properties of undefined (reading āforEachā)
TypeError: Cannot read properties of undefined (reading āforEachā)
at Explode.push (https://launch.playcanvas.com/api/assets/files/Scripts/Player/Weapons/Projectiles/explode.js?id=165694350&branchId=b2942a4a-94bf-41e2-93e8-f20607f1c95f:66:25)
at Explode.update (https://launch.playcanvas.com/api/assets/files/Scripts/Player/Weapons/Projectiles/explode.js?id=165694350&branchId=b2942a4a-94bf-41e2-93e8-f20607f1c95f:31:10)
at ScriptComponent._scriptMethod (https://code.playcanvas.com/playcanvas-1.68.1.dbg.js:102680:22)
at ScriptComponent._onUpdate (https://code.playcanvas.com/playcanvas-1.68.1.dbg.js:102714:15)
at ScriptComponentSystem._callComponentMethod (https://code.playcanvas.com/playcanvas-1.68.1.dbg.js:103476:52)
at ScriptComponentSystem._onUpdate (https://code.playcanvas.com/playcanvas-1.68.1.dbg.js:103494:11)
at ComponentSystemRegistry.fire (https://code.playcanvas.com/playcanvas-1.68.1.dbg.js:1647:21)
at AppBase.update (https://code.playcanvas.com/playcanvas-1.68.1.dbg.js:70025:19)
at AppBase.tick (https://code.playcanvas.com/playcanvas-1.68.1.dbg.js:71078:20)
at AppBase.start (https://code.playcanvas.com/playcanvas-1.68.1.dbg.js:69986:11)
I think the problem might be that the list of affected bodies isnāt getting set up properly. This could be why itās showing as āundefinedā when you try to use it in the forEach
loop. Double-check how youāre setting up this.affectedBodies
to make sure itās getting populated correctly with the entities that should be affected by the explosion.
I noticed that most the code in the project is simply not being used or some functions are either never read, undefined or never used. Is there a reason for this? Is this project just starting out or is this just an error?
its relatively new
ok ive figured out that its not reading anything in the initialize function but i have to go
nvm i have time