Reputation: 23
I want to make my raycaster intersect only with objects that are visible. I have three classes, .menu_one, .menu_two, and .menu_three. When I click on one of them, I want all other menus to disappear so the viewer can see the 3d background. However, when I am walking around I can still click where the menu used to be with the raycaster when I don't want to. What do I pass thru raycaster="objects: ???" or any other method to make it work. ...
<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">
...
I expect the raycaster only to be able to intersect with objects that are visible to the user.
Hi, would this be the way to make this work?
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);
}
}
}
})
Upvotes: 0
Views: 738
Reputation: 13233
You should explicitly control the raycaster objects
list. For example:
raycaster="objects: [data-raycastable]"
Now we have an entity we want to make raycastable:
<a-entity geometry material data-raycastable>
Let's say we hide the entity. We also remove its raycastable attribute:
el.object3D.visible = false;
el.removeAttribute('data-raycastable');
And let's say we add it back:
el.object3D.visible = true;
el.setAttribute('data-raycastable', '');
In more complicated scenes, it can be more tedious on many entities. Things like aframe-state-component
(https://www.npmjs.com/package/aframe-state-component) can assist by declaratively toggling off raycastability depending on scene state. Say we had <a-entity raycaster="objects: [raycastable]">
with AFRAME.registerComponent('raycastable', {})
, and in the state was isMenuActive
which is managed by the state component:
<a-entity id="button" bind-toggle__raycastable="isMenuActive">
And I've written my own component to keep raycastable / visibility in sync.
<a-entity id="button" bind__visible-raycastable="isMenuActive">
Upvotes: 1