Search code examples
aframewebxr

How to fix an A-frame virtual environment that never loads on first attempt but does upon refresh?


I (a very amateur programmer) am trying to make an environment in A-frame where you point a cursor at different objects and it changes the displayed value on a thermometer: https://fst-retail-safety.glitch.me

The site never loads completely on the first try but reliably loads upon refresh. If I omit the cursor listener from the GLTF used for the environment, it also loads correctly. Any ideas on how to fix this? Perhaps the cursor is trying to fuse with the background object before it loads and it's causing an error? Many thanks for any help.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Food Service Temperature Inspection</title>
    <meta name="description" content="Environment test" />
    <script src="https://aframe.io/releases/1.1.0/aframe.min.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/donmccurdy/[email protected]/dist/aframe-extras.min.js"></script>
    
    <script>
      AFRAME.registerComponent("cursor-listener-box", {
        init: function() {
          this.el.addEventListener("click", function(evt) {
            let target1 = document.querySelector("#IRtext");
            target1.setAttribute("value", "100");
          });
        }
      });
    </script>
    <script>
      AFRAME.registerComponent("cursor-listener-background", {
        init: function() {
          this.el.addEventListener("click", function(evt) {
            let target1 = document.querySelector("#IRtext");
            target1.setAttribute("value", "65");
          });
        }
      });
    </script>
  </head>

  <body>
    <a-scene background="color: #FAFAFA" renderer="colorManagement: true">
      <a-assets>
        <a-asset-item
          id="gltf"
          src="https://cdn.glitch.com/13648f22-5ed9-4349-ad71-1e8bd63b6485%2Fpumptest20.glb"
        ></a-asset-item>
        <a-asset-item
          id="IRthermo"
          src="https://cdn.glitch.me/7344c97b-c709-4f6e-a17b-3a7e1c7278a4%2FIR%20thermometer.glb"
        ></a-asset-item>
        <a-asset-itm
          id="navmesh"
          src="https://cdn.glitch.com/13648f22-5ed9-4349-ad71-1e8bd63b6485%2Fpumpnavmesh7.glb"
        ></a-asset-itm>
        <img
          id="concrete"
          src="https://cdn.glitch.me/13648f22-5ed9-4349-ad71-1e8bd63b6485%2Fconcrete.jpg"
        />
        <img
          id="background"
          src="https://cdn.glitch.me/13648f22-5ed9-4349-ad71-1e8bd63b6485%2Findustrial_1k.jpg"
        />
        <img
          id="watertank"
          src="https://cdn.glitch.me/13648f22-5ed9-4349-ad71-1e8bd63b6485%2Fwatertank.jpg"
        />
      </a-assets>

      <a-entity
        gltf-model="#gltf"
        scale="0.15 0.15 0.15"
        position="0 1.5 -2"
        cursor-listener-background
      ></a-entity>

      <a-light
        type="directional"
        intensity="0.7"
        color="#FAFAFA"
        position="0 4 0"
      ></a-light>
      <a-light
        type="ambient"
        intensity="0.6"
        color="#FAFAFA"
        position="0 4 0"
      ></a-light>

      <a-box
        material="src: #watertank"
        scale="5 3.3 5"
        position="-6.3 1.93 -1.4"
      ></a-box>
      <a-box
        material="src: #watertank"
        scale="5 3.3 5"
        position="-2 4.5 -11"
      ></a-box>

      <!--test shapes for script-->
      <a-entity
        geometry="primitive:box"
        material="color:green; shader:flat"
        position="0 1.6 -1"
        scale="0.2 0.2 0.2"
        cursor-listener-box
      ></a-entity>

      <a-entity
        gltf-model="#navmesh"
        scale="0.15 0.15 0.15"
        position="0 -.3 -2"
        visible="true"
        nav-mesh
      ></a-entity>
      <a-entity
        geometry="primitive: plane; height: 10; width: 10"
        material="src: #concrete; repeat:10 10"
        position="0 .3 0"
        rotation="-90 0 0"
      ></a-entity>

      <a-sky src="#background"></a-sky>

      <!--Player rig-->
      <a-entity
        id="rig"
        movement-controls="speed: 0.08; constrainToNavMesh: true"
      >
        <a-entity camera position="0 1.6 0" look-controls>
          <a-entity
            cursor="fuse: true; fuseTimeout: 100"
            position="0 0 -0.5"
            geometry="primitive: ring; radiusInner: 0.007; radiusOuter: 0.01"
            material="color: black; shader: flat"
          >
          </a-entity>
          <a-entity
            gltf-model="#IRthermo"
            scale="0.05 0.05 0.05"
            position="0.15 0 -0.5"
            rotation="0 -90 0"
          ></a-entity>
          <a-text
            id="IRtext"
            value="25"
            align="center"
            color="black"
            position="0.184 0.01 -0.295"
            scale="0.1 0.1 0.1"
            rotation="-16 0 0"
          ></a-text>
          <a-text
            value="TEMPERATURE"
            align="center"
            color="black"
            position="0.184 0.03 -0.295"
            scale="0.03 0.03 0.03"
            rotation="-16 0 0"
          ></a-text>
          <a-text
            value="F"
            align="center"
            color="black"
            position="0.19 -0.014 -0.29"
            scale="0.1 0.1 0.1"
            rotation="-16 0 0"
          ></a-text>
          <a-entity
            geometry="primitive: ring; radiusInner:0.002; radiusOuter:0.003"
            material="color: black; shader: flat"
            position="0.18 -0.01 -0.29"
            rotation="-16 0 0"
          ></a-entity>
        </a-entity>
      </a-entity>
    </a-scene>
  </body>
</html>

Solution

  • I've opened it up, and when something in the scene isn't loaded, there is a nice log in the console:

    Uncaught TypeError: Cannot read property 'array' of undefined
    at TextGeometry.computeBoundingSphere (index.js:96)
    at P.raycast (three.js:8649)
    (....)
    

    No need to search for the array of undefined - the rest tells us that there is an issue with raycasting the text elements.

    Since you only want to interact with certain things (which aren't text elements), you can specify which items should the cursor interact with:

    <!-- let them share a common class -->
    <a-box class="interactable></a-box>
    
    <!-- raycaster setup -->
    <a-entity
       cursor="fuse: true; fuseTimeout: 100"
       raycaster="objects: .interactable">
    </a-entity>
    

    Like i did in this remix