Collision detection problem!

I don’t know why collision detection sometimes not work!!!

    if (result.other.tags.has('Ball')){        
        result.other.destroy();
    }

Record_2019_03_17_15_45_58_870

Record_2019_03_17_15_45_43_977

Record_2019_03_17_18_08_28_939

Record_2019_03_17_18_09_04_724

Judging from the gif provided by you - the physics works correctly. What event do you use to detect another collision? Contact event?

EDIT:
In my practice, I encountered a similar problem. When the player’s entity moved on a flat surface, the collisionstart event was triggered with a certain periodicity, although it had to be worked only once, at the very beginning. I assume that the following problem exists in the physics engine. When contact is made with another entity and if the contact point is at the junction of the triangles of the model (as in the screenshot below), the collision event does not work. These are my personal observations. Alternatively, you can try to increase the number of polygons for models and check result.
Sphere

Are you 100% sure that every ball has the ‘Ball’ tag (with the same letter casing)?

Yes I’m sure
I don’t know why sometimes not work!

you can see my project
https://playcanvas.com/editor/scene/723409

first I used collision start
then I used contact and not work

this is my code that attached to MainBall

var DestroyMe = pc.createScript('destroyMe');

DestroyMe.prototype.initialize = function() {
   this.entity.collision.on('contact', this.onContact, this);
};


DestroyMe.prototype.onContact = function (result) {

    if (result.other.rigidbody && result.other.tags.has('Ball')){
       result.other.destroy();
    }
};

also when I use applyImpulse my code not work
why should I use applyForce Instead of applyImpulse!

Try changing the event type to collisionstart. And try to apply the method I wrote above.

as I mentioned above first I used oncollision start when It not work I decided to use another method
but not work

You can try for each ball to make the BoundingSphere a radius slightly larger than the ball itself. Then, using the intersectsBoundingSphere() method, check overlapping of this sphere with the main ball. I personally did not check this method.

oh thanks!!! You deserve a full pitcher beer from me!
I was looking for equivalent of Physics.SphereCast that I use in unity

var sphere = new pc.BoundingSphere(this.entity.getPosition(),2);
if(sphere.intersectsBoundingSphere){
    this.entity.destroy();
}

how can I compare tag in this way?

if(sphere.intersectsBoundingSphere && tag === 'Ball'){

}

It’s not so simple. :slightly_smiling_face: Now I will try to recreate the situation on the test scene.

thanks
I also tested collision detection by mesh
3

but it kill the performance and balls move from another!

I did an entity check by tags. In this scene, you are interested in the BoundingTest and PlayerMovement scripts. In the PlayerMovement script, I selected the necessary code sections in the comments. In fact, 2 spheres are created, one of which checks interaction with the other. The entity ball is also transferred via an event to another script that checks the condition by tags. If the tag is equal to the Ball, then the entity is removed from the scene. There is only one problem - these spheres are created on each frame, this can affect performance. I did not deal with the issue of code optimization. :slightly_smiling_face:

Yes, in this case, the total number of triangles on the stage increases significantly, which slows down render loop.

thanks but it doesn’t work when speed is high! :persevere:
Record_2019_03_18_07_45_02_4 Record_2019_03_18_07_45_10_382

I attached this script to brown ball

var BoundingTest = pc.createScript('boundingTest');

BoundingTest.attributes.add('radius', { type: 'number', default: 1 });

// initialize code called once per entity
BoundingTest.prototype.initialize = function() {

};

BoundingTest.prototype.update = function(dt) {
    this.sphere = new pc.BoundingSphere(this.entity.getPosition(), this.radius);
    this.app.fire('test', this.sphere, this.entity);
};

I attach this script to white ball

var DestroyBall = pc.createScript('destroyBall');

// initialize code called once per entity
DestroyBall.prototype.initialize = function() {
 var self = this;
this.app.on('test', function(sph, entity) {
    if(self.sphere.intersectsBoundingSphere(sph) && entity.tags.has('Ball')) {
        entity.destroy();
    } else {
        console.log('Entity cannot be removed from the scene.');
    }
});   
};

// update code called every frame
DestroyBall.prototype.update = function(dt) {
        this.sphere = new pc.BoundingSphere(this.entity.getPosition(), this.radius);
};

@yaustar have you any Idea?

Have you tried to make a radius for spheres a bit larger than the model itself?

yes It seems worked
but currently I have another problem
I can’t call a function inside app
for example:

this.app.on('test', function(sph, entity) {
this.entity.destroy(); // I can't access to current class
});

It’s simple. You have lost the execution context for the nested function. Save the context to a separate variable and access the application through it.

var self = this;
this.app.on('test', function(sph, entity) {
    self.entity.destroy(); // I can't access to current class
});
1 Like

Why do you need to refer to the entity to which the script is attached? In my example, I delete the entity that is passed as an argument to the function.