Adding 'rayOrigin: mouse' to Aframe cursor component throwing error - aframe

I am trying to include a mouse click functionality to VR scene apart from focus cursor. I am using it as below -
<a-entity camera look-controls mouse-cursor>
<a-entity position="0 0 -3" scale="0.2 0.2 0.2" geometry="primitive: ring; radiusOuter: 0.20;radiusInner: 0.10;" material="color: #990000; shader: flat" cursor=" fuse: true; rayOrigin: mouse">
</a-entity>
</a-entity>
Below is the error while using this code. Please note that i am using Afrmae with Angular2
ERROR TypeError: Cannot read property 'count' of undefined
at Mesh.raycast (aframe-master.js:21938)
at intersectObject (aframe-master.js:45999)
at Raycaster.intersectObjects (aframe-master.js:46072)
at NewComponent.module.exports.Component.registerComponent.tick (aframe-master.js:69697)
at HTMLElement.value (aframe-master.js:76597)
at HTMLElement.value (aframe-master.js:76645)
at bound (aframe-master.js:79931)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:425)
at Object.onInvokeTask (core.es5.js:3881)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)

If you want your mouse to act like a <a-cursor> You need to move the cursor bit to the <a-scene> :
<a-scene cursor="rayOrigin:mouse">

Related

Uncaught TypeError using A-Frame 1.0.4 + A-Frame Extras nav-mesh and movement-controls

I'm getting the following error when using a simple plane as a nav-mesh and setting my rig's movement-controls="constrainToNavMesh: true".
aframe-extras.min.js:1 Uncaught TypeError: Cannot read property 'forEach' of undefined
at m.getClosestNode (aframe-extras.min.js:1)
at o.getNode (aframe-extras.min.js:1)
at i.<anonymous> (aframe-extras.min.js:1)
at HTMLElement.tick (a-scene.js:709)
at HTMLElement.render (a-scene.js:759)
at bind.js:12
at f (three.js:24703)
at e (three.js:15038)
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/donmccurdy/aframe-extras#v6.1.0/dist/aframe-extras.min.js"></script>
<script src="//cdn.rawgit.com/donmccurdy/aframe-physics-system/v4.0.1/dist/aframe-physics-system.min.js"></script>
<a-entity id="rig" position="0 0 0" movement-controls="constrainToNavMesh: true">
<a-entity id="camera" camera position="0 1.6 0"></a-entity>
</a-entity>
<a-entity geometry="primitive: plane; height: 350; width: 350;" position="0 0 0" rotation="-90 0 0" static-body nav-mesh>
</a-entity>
Is this a known bug? I first thought there was a conflict, but the problem persists even when all other includes are stripped out. All models load fine, and everything else is working.
Error happens only when movement is started by pressing arrow keys. Any advice?
Problem for me was that the nav mesh was too big. Using the same nav mesh scaled down worked. You might have to scale down your whole project, but that is the only solution I know of.

AFrame - Change controls type using setAttribute

I would like to remove the twoway-motion component from the entity player, and replace it with the progressive-controls component, using setAttribute.
While the removeAttribute works fine for removing the twoway-motion, the setAttribute does not add the progressive-controls.
<a-entity id="player" networked="template:#avatar-template;showLocalTemplate:false;"
camera spawn-in-circle="radius:3;"
position="0 1.3 0"
wasd-controls
look-controls
twoway-motion="speed: 35">
<a-entity cursor="fuse: true; fuseTimeout: 500"
position="0 0 -1"
geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03"
material="color: black; shader: flat"
id="defaultCursor">
</a-entity>
</a-entity>
<script>
var playerEl = document.getElementById('player');
var cursorEl = document.getElementById('defaultCursor');
playerEl.removeChild(cursorEl);
playerEl.removeAttribute('twoway-motion');
playerEl.setAttribute('progressive-controls');
</script>
the setAttribute(name, value) requires a value.
To add the component, just use setAttribute('progressive-controls', '') to add it with the default schema

(A-Frame) How to stop a object intersect with cursor?

I use a-frame to do web-vr. I's good to use but I have some situation don't know how to implement.
First I put a Camera with cursor and set the raycaster intersect with object ".trigger".
<a-entity camera="" look-controls="" position="" rotation="" scale="" visible="">
<a-entity cursor="fuse: true; fuseTimeout: 1500" position="0 0 -1" geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03" material="color: cyan; shader: flat" raycaster="objects: .trigger" rotation="" scale="" visible="">
<a-animation begin="click" easing="ease-in" attribute="scale" fill="forwards" from="0.1 0.1 0.1" to="1 1 1" dur="150"></a-animation>
<a-animation begin="cursor-fusing" easing="ease-in" attribute="scale" fill="backwards" from="1 1 1" to="0.1 0.1 0.1" dur="1500"></a-animation>
</a-entity>
</a-entity>
And create a entity with class "trigger".
<a-entity class="tigger" id="clip01" clip01="on: click; conditionId: ShowClipTrigger" data-is-trigger="true" geometry="primitive: plane; width: 2; height: 3" material=" src: #clip01-pic; opacity: 0.99;" position="-5.913 -3.544 4.675" rotation="-82.048 122.222 11.345" scale="" visible="" animation__move="" animation__rotate=""></a-entity>
The ".trigger" object will trigger some action after on click event received. My question is how to disable the intersect after the trigger been click. I try remove the class "trigger" from the object after the click evnet, but it still can intersect with cursor.
I search the a-frame document raycaster but no clue.
After removing the whitelisted class, You need to refresh the raycaster:
var raycasterEl = AFRAME.scenes[0].querySelector('[raycaster]');
raycasterEl.components.raycaster.refreshObjects();
Also You can achieve this by making a simple switch in the event listener:
var switch=true;
el.addEventListener("click", function(evt) {
if(switch){
//doStuff
switch = false;
}
});
or remove the listener completely, like i did here:
//listener
this.doStuff = this.doStuff.bind(this);
el.addEventListener("click", this.doStuff());
//function
doStuff: function(){
this.el.removeEventListener("click",this.doStuff);
}

AFRAME - disable cursor gaze on specific elements

I'm using the following code for visual feedback:
<script src="https://aframe.io/releases/0.5.0/aframe.min.js"></script>
<a-scene>
<a-entity cursor="fuse: true; fuseTimeout: 500" position="0 0 -1" geometry="primitive: ring" material="color: black; shader: flat">
<a-animation begin="click" easing="ease-in" attribute="scale" fill="backwards" from="0.1 0.1 0.1" to="1 1 1"></a-animation>
<a-animation begin="cursor-fusing" easing="ease-in" attribute="scale" fill="forwards" from="1 1 1" to="0.1 0.1 0.1"></a-animation>
</a-entity>
</a-scene>
The problem is that this code is applied where the cursor "collide" with every primitive entity in the scene. I want it to be apply only on specific elements. (or alternatively, disable the animations on specific elements). How can I do it?
Thanks
The cursor component depends on the raycaster component. If the raycaster component is not added as an attribute of the DOM element, the cursor component will initialize one with default settings. However when provided, you can alter certain attribute values of the raycaster component to satisfy your needs.
Luckily for you, the raycaster component supports specific entities with a DOM query selector.
<a-entity cursor raycaster="objects: .clickable"></a-entity>
This will make the cursor only emit events to <a-entity>s with the class name of clickable.
Here is a link to all the raycaster component properties: raycaster component properties.

How do you create an aframe button

Does anyone know how to create a button in aframe
One way to create a button with A-Frame would be to use the <a-box> primitive combined with a cursor. The following is a simple demo:
<a-scene>
<a-entity position="0 .6 4">
<a-camera>
<a-entity id="mycursor" cursor="fuse: true; fuseTimeout: 500; max-distance: 30;"
position="0 0 -5"
geometry="primitive: ring"
material="color: blue; shader: flat">
</a-entity>
</a-camera>
</a-entity>
<!-- "button" -->
<a-entity id="refresh-button" geometry="primitive: box" material="color: red" position="0 0 -2"></a>
</a-scene>
<script>
document.querySelector('#refresh-button').addEventListener('click', function() {
// Refresh stuff would go here!
});
</script>
When the cursor focuses on the "button", the click event would fire. To add text to the button, you can use this component:
https://github.com/ngokevin/aframe-text-component
Lastly, if you're looking for a more traditional "button", you could simply float a <button> element over the canvas or Iframe if you're embedding.
i like https://www.npmjs.com/package/aframe-event-set-component for the hover event. And i give my cursor an attribute (data clickable) and then i say the raycaster he should just trigger entities with the attribute. If you want to let something just be clickable if you for example enter the vr-mode simply remove the dataclickable attribute. Scene looks like this:
<a-scene cursor="rayOrigin: mouse" raycaster="objects: [data-clickable]">
<a-image id="button" data-clickable visible="true" position="2 1.75 -0.2" height="0.5" width="0.5" rotation="0 90 0" onclick="dosomething()" event-set__enter="_event: mouseenter; width: 0.53; height: 0.53;"
event-set__leave="_event: mouseleave; width: 0.5; height: 0.5;"></a-image>
<a-camera>
<a-cursor id="curseid" raycaster="objects: [data-clickable]"</a-cursor>
</a-camera>
</a-scene>
If you want that a button works just if something happend give him the attribute later:
document.getElementById('button').setAttribute('data-clickable', '');
If you done with the button use:
document.getElementById('button').setAttribute('visible', 'false');
document.getElementById('button').removeAttribute('data-clickable');
If you want that the cursor just triggers button if you for example enter vr-mode, change the raycaster="objects: .notclickable" and then give him later with this line his attribute back:
document.getElementById('curseid').setAttribute('raycaster', 'objects: [data-clickable]');
This is for now my way to do buttons, maybe there is a smarter way. I hope this helped a bit :D

Resources