Search code examples
javascriptthree.jsaframe

How to make a entity clickable which is getting generated dynamically in networked A-Frame?


I am using a networked A-frame to generate a new entity when the page is loaded. I want to add a few functionalities on those entities like hover, on click, etc. I tried making it clickable but it didn't work.

function rigClick(){
        console.log("Entity Clicked");
      }
<a-scene>
    <a-entity id="rig" onclick="rigClick()">
        <a-entity
          id="foo"
          networked="template:#rig-template;attachTemplateToLocal:false;"
          camera="active:true;"
          position="-27 2.5 24"
          wasd-controls="acceleration:12;"
          look-controls
          spawn-in-circle="radius:2"
        >
        </a-entity>
     </a-entity>
</a-scene>

I also tried using the register component but I am unable to get the results.

AFRAME.registerComponent('click-handler', {
      init: function () {
        let entity = document.querySelector('#rig')

        entity.addEventListener('click', (e) => {
          console.log("You just clicked on entity");
        })
      }
    });
<a-scene>
    <a-entity id="rig">
        <a-entity
          id="foo"
          networked="template:#rig-template;attachTemplateToLocal:false;"
          camera="active:true;"
          position="-27 2.5 24"
          wasd-controls="acceleration:12;"
          look-controls
          spawn-in-circle="radius:2"
          click-handler
        >
        </a-entity>
     </a-entity>


Solution

  • If you want to use your mouse, you need a cursor which will map 2D mouse clicks onto 3D rays checking whats under the mouse cursor:

    <script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
    <script>
    // declare a component
    AFRAME.registerComponent("click-detector", {
     // called upon initialisation
     init: function() {
       // when a click is detected
       this.el.addEventListener("click", () => {
        // log "clicked"
        console.log("clicked")
       })
     }
    })
    </script>
    <a-scene cursor="rayOrigin: mouse" raycaster="objects: a-sphere">
      <a-sphere position="0 1.25 -2" radius="1.25" color="#EF2D5E" click-detector></a-sphere>
    </a-scene>

    Works the same in aframe-networked as long as you add the component to the networked-template so that every new 'player' has the component attached:

    <template id="avatar-template">
      <a-entity class="avatar">
        <a-sphere class="head" scale="0.45 0.5 0.4" click-detector></a-sphere>
      </a-entity>
    </template>