isSensor sprite body collissions only detectable through world collision event

I am working on a game feature using sensors, and am having an issue, whereby I can’t seem to use the standard collission detection mechanisms

I’ve re-created the issue in a sandbox here - Phaser 3 - Colissions - CodeSandbox

What happens within this -

  • We create a player, and 5 bots within index.js
  • On left click, the player (player.ts) will create a “grenade” and throw towards bots (colliding with them), then after 1 second will explode (this is when the grenade body turns from a normal physics body, into a sensor to detect a “kill area”). - grenade.ts, line 49

The problem is as you see in logs, when the grenade hits the bots before explosion (I.E not a sensor), the collission signature works as expected

grenade.setOnCollide((pair) => {
    console.log(`collission between ${pair.bodyA.gameObject.type} and ${pair.bodyB.gameObject.type}`)
  });

However once the grenade turns into a sensor, that callback no longer gets called, and I must rely on this unperformant way to check for sensor hits

this.scene.matter.world.on('collisionstart', function (event)

Is there any way I can listen for collissions on the grenade sprite, rather than every player having tio listen to all collission events, and iflter for the correct ones (feels extremelly un-performant)

Hi,

I never used Matter before, but i usually make different classes between weapons and explosions.
Based on your Bot class, i made a Explosion class. And inside Grenade.explode i just create a new explosion. It seems to work, but perhaps not the way you want (with sensor)

Explosion class


export default class Explosion extends Phaser.Physics.Matter.Sprite {
  health = 100;
  constructor(scene, x, y, key) {
    super(scene.matter.world, x, y, key);
    // set shape to circle
    this.setCircle(50);

    // this.setCollisionCategory(collisionGroups.BOT_GROUP);
    // this.setCollidesWith([collisionGroups.GRENADE_GROUP]);
    this.type = "EXPLOSION";

    this.setOnCollide((pair) => {
      console.log(
        `Explosion collission between ${pair.bodyA.gameObject.type} and ${pair.bodyB.gameObject.type}`
      );
    });

    // destroy the grenade after 0.1 seconds#
    this.scene.time.addEvent({
      delay: 100,
      callback: () => {
        this.destroy();
      }
    });
  }
}```

Grenade class
```import Phaser from "phaser";
import Explosion from "./explosion";
export default class Grenade extends Phaser.Physics.Matter.Sprite {
  public worldLayer: Phaser.Tilemaps.TilemapLayer;
  public associatedEntityId: number;

  constructor(
    scene: Phaser.Scene,
    private startX: number,
    private startY: number,
    private targetAngle: number,
    private speed: number
  ) {
    super(scene.matter.world, startX, startY, "grenade", 0);

    this.setVelocity(1, 1);
    this.rotation = Phaser.Math.DegToRad(targetAngle) + 1.57079633;

    this.setFriction(0, 0);
    this.type = "GRENADE_MOVING";

    // Detonate after 5 seconds
    this.scene.time.addEvent({
      delay: 1000,
      callback: () => {
        this.explode();
      }
    });
  }

  explode() {
    this.type = "GRENADE_EXPLODING";

    const explosion = new Explosion(this.scene,
      this.x + 25,
      this.y + 25,
      'test',
      )

    // destroy the grenade after 0.1 seconds#
    this.scene.time.addEvent({
      delay: 100,
      callback: () => {
        this.destroy();
      }
    });
  }
}```

Makes sense @BlunT76 you could certainly add an extra class for that.

Regarding a cleaner way to detect sensor collission with bodys, I’ve made use of phaser-matter-collision-plugin

The demo now uses it - Phaser 3 - Colissions - CodeSandbox, found the suggestiion in Modular Game Worlds in Phaser 3 (Tilemaps #5) — Matter Physics Platformer | by Michael Hadley | ITNEXT