three.jsaframeaframe-networked

Adding selected character/ .gltf model in a-frame


I'm stuck on one problem. Example image

There are three items I've built into the options. So, I want to click on any one of the buttons to change the avatar as per the click. If anyone selected a male avatar so it should be reflected in others also. For example if there are 4 users. And from that 3 are male and 1 is female and the female selected a female avatar. So, she can able to see others as a male avatar and others can see her as a female avatar(.gltf model).

Is there any way to dynamically add the .gltf model in a-frame and also update it for others?

<body>
<!-- ============================ Start Model Selection ==========================  -->
<div class="container" style="z-index: 1; position: fixed">
  <div class="content_container content_container-1">
    <div class="svg">
      <img
        src="https://s2.svgbox.net/illlustrations.svg?ic=selfie-boy"
        alt="Boy"
      />
    </div>
    <div class="content content-1">Boy</div>
  </div>

  <div class="content_container content_container-1">
    <div class="svg">
      <img
        src="https://s2.svgbox.net/illlustrations.svg?ic=selfie-girl"
        alt="Girl"
      />
    </div>
    <div class="content content-2">Girl</div>
  </div>

  <div class="content_container content_container-1">
    <div class="svg">
      <img
        src="https://s2.svgbox.net/illlustrations.svg?ic=my-robot"
        alt="Robot"
      />
    </div>
    <div class="content content-3">Robot</div>
  </div>
</div>

<!-- ============================ End Model Selection ==========================  -->

<a-scene background="color: #FAFAFA">
  <a-entity environment="preset: forest;  grid: cross"></a-entity>
</a-scene>

This is the code I've written for this.


Solution

  • The docs mention syncing custom components (and gltf-model is a component), and it's quite simple. Lets say we want a model with the standard heads:

    1. Add the entity with the gltf-component to the networked template:

      <template id="avatar-template">
        <a-entity class="avatar">
          <a-entity class="model" gltf-model></a-entity>
          <a-sphere class="head">
          <!-- The rest of the template definition -->
      
    2. Add it to the NAF.schemas:

      NAF.schemas.add({
           template: '#avatar-template',
           components: [
             // the default position, rotation, color
             {
               // the model entity has a .model class
               selector: '.model',
               // we want the gltf-model component to sync between clients
               component: 'gltf-model'
             },
      
    3. Add the model to your local client:

      <a-entity id="player" camera
               networked="template:#avatar-template;attachTemplateToLocal:false;"
               position="0 1.6 0" wasd-controls look-controls>
        <a-entity class="model" gltf-model="#fox" model-changer></a-entity>
      </a-entity>
      
    4. Create the model-changer component which changes the model when the images are clicked:

      AFRAME.registerComponent("model-changer", {
        init: function() {
          // nothing special here - change the models when the images are clicked
          const btn1= document.getElementById("btn1")
          const btn2= document.getElementById("btn2")
      
          // for whatever reason i need to update the model with the actual source, not just the id
          function getAssetSrc(id) {
            return document.getElementById(id).getAttribute("src")
          }
          btn1.addEventListener("click", e => {
            this.el.setAttribute("gltf-model", getAssetSrc(model1))
          })
          btn2.addEventListener("click", e => {
            this.el.setAttribute("gltf-model", getAssetSrc(model2))
          })
        }
      })
      

    Check it out in this glitch - the images should change the models:

    enter image description here