A-Frame: parent 的 raycaster-intersected-cleared 如果与 children 没有交集则触发

A-Frame: parent's raycaster-intersected-cleared triggered if no intersection with children

我正在实现一项功能以在移动 VR 控制器时获取 a-sky 的坐标。

<a-scene scenelistener>
  <a-sky
    id="map-sky"
    color="#222"
    radius="700"
    rotation="0 45 0"
    rotation-control
    raycaster-listen
    class="ray-castable"
  >
    <a-entity
      id="country-tiles"
      country-tiles
      scale="1 1 1"
      rotation="0 90 0"
    ></a-entity>
  </a-sky>
  ... // Oculus entities
</a-scene>

a-sky 及其 children 正在侦听光线投射,并打印出控制台日志记录

AFRAME.registerComponent("raycaster-listen", {
  init: function() {
    this.el.addEventListener("raycaster-intersected", evt => {
      console.log(`raycaster ${this.el.id} intersected!!!`);
    });
    this.el.addEventListener("raycaster-intersected-cleared", evt => {
      console.log(`raycaster ${this.el.id} cleared!!!`);
    });
  }
});

结果:在 children country-tiles 进出时,raycaster-intersected-cleared 事件由 children 及其 parent [=21] 触发=],意思是A-Frame无法得到a-sky和光线投射VR控制器之间的交点。

raycaster  intersected!!!
raycaster map-sky intersected!!!
// Moving out the tile
raycaster  cleared!!!
raycaster map-sky cleared!!!

你可以看看这个Glitch

注意:由于我正在为 VR 控制器开发,因此请使用 WebXR emulator 扩展进行交互

事实证明,来自父元素的 raycaster-intersected-cleared 事件被触发,但这并不意味着它不再相交。为了确认它是否仍然相交,我必须检查 getIntersection 结果是否为 NULL。

AFRAME.registerComponent("raycaster-listen", {
  init: function() {
    this.el.addEventListener("raycaster-intersected", evt => {
      console.log(`raycaster ${this.el.id} intersected!!!`);
      this.raycaster = evt.detail.el;
    });
    this.el.addEventListener("raycaster-intersected-cleared", evt => {
      if (this.raycaster) {
        const intersection = this.raycaster.components.raycaster.getIntersection(this.el);
        if (!intersection) {
          console.log(`raycaster ${this.el.id} cleared!!!`);
        }
      }
    });
  }
});