wiserim / phaser-raycaster

Raycasting plugin for Phaser 3. Documentation:

Home Page:https://wiserim.github.io/phaser-raycaster/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Rectangle Added to a Container Not Registering for Raycasting

Tresky opened this issue · comments

I've created a custom class called Actor that inherits from Phaser.Container and I've added a number of sprites to the class that are all nested inside of the container.

I've created a Phaser.GameObjects.Rectangle that is a part of the container to act as the bounding box for ray casting for that object.

// Actor.js
class Actor extends Phaser.GameObjects.Container {
  constructor (scene) {
    super(scene)
    this.scene.add.existing(this)

    this.boundingBox = new Phaser.GameObjects.Rectangle(scene, 0, 0, 16, 32)
    this.boundingBox.setDisplayOrigin(8, 24)
    this.boundingBox.parent = this
    this.add(this.boundingBox)
  }

  castRay () {
    let ray = this.scene.raycaster.createRay()
    ray.setOrigin(this.x, this.y)
    ray.setAngleDeg(DIRECTION_ANGLES[this.direction])
  
    const intersection = ray.cast()
    console.log('inter', intersection)
  }
}

// Scene.js
create () {
  this.raycaster = this.raycasterPlugin.createRaycaster({
    debug: { enabled: true },
  })

  const actor = new Actor(this)
  this.raycaster.mapGameObjects(actor.boundingBox)
}

Here's a screenshot of what I'm experiencing. You can see the red rectangle is the boundingBox having been successfully mapped into the Raycaster plugin. However, you can also see the ray that's casted goes right through the rectangle and doesn't hit.

Screen Shot 2022-05-27 at 1 31 05 PM

Am I doing something wrong?

I've discovered that the rectangle is actually getting mapped, but the position of the mapped rectangle is not relative to the container. It's actually globally positioned at (0, 0). See top-left of the attached screenshot.

Screen Shot 2022-05-28 at 9 33 35 AM

.

Hello,
Your bounding box has position relative to it's container.
While mapping object raycaster is treating mapped object's position as relative to scene (and it's own display origin).

You can fix this, by setting bounding box position to it's parent position and not adding it to container.
You can also override methods you use to update Actor's position, so the bounding box will be updated alongside it's parent.

// Actor.js
class Actor extends Phaser.GameObjects.Container {
  constructor (scene) {
    super(scene)
    this.scene.add.existing(this)
    //set bounding box position
    this.boundingBox = new Phaser.GameObjects.Rectangle(scene, this.x, this.y, 16, 32)
    this.boundingBox.setDisplayOrigin(8, 24)
    this.boundingBox.parent = this
    //this.add(this.boundingBox)
  }
  
  setPosition (x, y, z, w) {
    super(x, y, z, w)
    this.boundingBox.setPosition(x, y, z, w)
    return this;
  }
  /*rest of code*/
}

I've published version 0.10.3.
Container's Map now allows to choose single child element which will be mapped, by passing it as mapChild option to Map.config parameters.

container.add(child);
raycaster.mapGameObjects(container, true, { mapChild: child });

or in case of your Actor class:

const actor = new Actor(this)
this.raycaster.mapGameObjects(actor, true, { mapChild: actor.boundingBox });