如何使Raycaster仅在与可见对象/实体相交时起作用?

时间:2019-06-03 18:50:39

标签: javascript html three.js aframe raycasting

我想使我的光线投射器仅与可见对象相交。我有三个类,.menu_one,.menu_two和.menu_three。当我单击其中之一时,我希望所有其他菜单都消失,以便观看者可以看到3d背景。但是,当我四处走动时,我仍然可以单击不想使用的菜单,该菜单曾经与raycaster一起使用。我如何通过raycaster =“ objects:???”或其他任何使其起作用的方法。 ...

<a-cursor
      id="cursor"
      material="color: black; shader: flat"
      position="0 0 -4.5"       
      geometry="primitive: ring; radiusInner: 0.15; radiusOuter: 0.2"
      animation__click="property: scale; startEvents: click; from: 0.1 0.1 0.1; to: 1 1 1; dur: 150"
      animation__fusing="property: fusing; startEvents: fusing; from: 1 1 1; to: 0.1 0.1 0.1; dur: 1500"
      event-set__mouseenter="_event: mouseenter; color: springgreen"
      event-set__mouseleave="_event: mouseleave; color: black"
      raycaster="objects: [data-visible]">
    </a-cursor>  


<a-entity class="menu1"
            geometry="primitive: plane; height: 0.2; width: 0.5"
            material="color: black"
            text="value: ${city_name}; color: white; align: center; wrapCount: 10; font: exo2bold"
            event-set__mouseenter="scale: 1.5 1.5 1"
            event-set__mouseleave="scale: 1 1 1"
            event-set__1="_event: click; _target: #models; _delay: 300; visible: false">

...

我希望光线投射器只能与用户可见的对象相交。

嗨,这是完成这项工作的方法吗?

AFRAME.registerComponent('data-raycastable', {
      init: function () {
        var self = this;
        var el = this.el;
        var data = this.data;

        this.eventHandlerFn = function () {
          if (el.object3D.visible = true){
          el.setAttribute('data-raycastable', '');
          }
          else {
            el.removeAttribute('data-raycastable')
          }
        }

        update: function() {

          el.addEventListener('click', this.eventHandlerFn);
          } 
          }
        }
      })

1 个答案:

答案 0 :(得分:0)

您应该显式控制raycaster objects列表。例如:

raycaster="objects: [data-raycastable]"

现在,我们有一个实体,希望使其可以进行射线投射:

<a-entity geometry material data-raycastable>

假设我们隐藏了实体。我们还删除了它的raycastable属性:

el.object3D.visible = false;
el.removeAttribute('data-raycastable');

假设我们将其重新添加:

el.object3D.visible = true;
el.setAttribute('data-raycastable', '');

在更复杂的场景中,它在许多实体上可能更加乏味。像aframe-state-componenthttps://www.npmjs.com/package/aframe-state-component)这样的事物可以通过根据场景状态声明性地切换光线投射能力来提供帮助。假设我们将<a-entity raycaster="objects: [raycastable]">AFRAME.registerComponent('raycastable', {})一起使用,并且状态为isMenuActive,该状态由状态组件管理:

<a-entity id="button" bind-toggle__raycastable="isMenuActive">

我已经编写了自己的组件,以保持可射线广播/可见性同步。

<a-entity id="button" bind__visible-raycastable="isMenuActive">