【问题标题】:How do I make my raycaster only work when intersecting with visible objects/entities?如何让我的光线投射器仅在与可见对象/实体相交时工作?
【发布时间】:2019-10-19 08:12:29
【问题描述】:

我想让我的光线投射器只与可见的对象相交。我有三个类,.menu_one、.menu_two 和 .menu_three。当我单击其中一个时,我希望所有其他菜单都消失,以便查看者可以看到 3d 背景。但是,当我四处走动时,当我不想时,我仍然可以单击过去与光线投射器一起出现的菜单。我通过 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);
          } 
          }
        }
      })

【问题讨论】:

    标签: javascript html three.js aframe raycasting


    【解决方案1】:

    您应该明确控制光线投射器objects 列表。例如:

    raycaster="objects: [data-raycastable]"

    现在我们有了一个我们想要让 raycastable 的实体:

    &lt;a-entity geometry material data-raycastable&gt;

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

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

    假设我们把它加回来:

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

    在更复杂的场景中,对许多实体来说可能会更乏味。 aframe-state-component (https://www.npmjs.com/package/aframe-state-component) 之类的东西可以通过根据场景状态以声明方式关闭 raycastability 来提供帮助。假设我们有&lt;a-entity raycaster="objects: [raycastable]"&gt;AFRAME.registerComponent('raycastable', {}),状态是isMenuActive,由状态组件管理:

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

    我已经编写了自己的组件来保持光线投射/可见性同步。

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

    【讨论】:

    • 我从概念上理解你的意思,所以非常感谢你。但是,我尝试遵循 aframe-state-component 并且对于按照您解释得很好的方式实际实现它有点迷茫。感谢您提供更多信息
    • 你可以按照答案的前半部分来
    • 嗨,Ngo 先生,我编辑了我的问题,问你这样的脚本是否适用。非常感谢
    • AFRAME.registerComponent('data-raycastable', { schema: { event: {type: 'boolean', default: true} } init: function () { entityEl.addEventListener('click', function() { if (el.object3D.visible = false) { el.setAttribute('data-raycastable', false); } else if (el.object3D.visible = true) { el.setAttribute('data-raycastable' , true) } }) } }) 这是脚本,但不起作用。
    • 无法将组件命名为数据属性data-raycastable。我的代码示例是删除数据属性,而不是将其设置为真/假。我可以稍后再发布...github.com/supermedium/moonrider 是状态组件的示例。和glitch.com/~aframe-building-ui
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-17
    • 2022-01-20
    • 2020-01-21
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    相关资源
    最近更新 更多