2

I am new to A-Frame and still trying to figure everything out! I'm currently constructing a 3D space and would like to create a guided experience for visitors by providing dots on the floor for them to click and be transported to that position. I found this code online which is perfect but I can't get it to work. Here is the link to my project on Glitch: https://glitch.com/~museum-exhibit-demo

This is the code for my camera:

<a-entity position="1.8 -1.1 3" rotation="0 90 0" id="pov">
        <a-camera universal-controls="movementControls: checkpoint" checkpoint-controls="mode: animate">
      <a-entity cursor position="0 0 -1" geometry="primitive: ring; radiusInner: 0.01; radiusOuter: 0.015;" material="color: #CCC; shader: flat;"> </a-entity>
          </a-camera>
    </a-entity>

And this is the code for the cylinder:

<a-cylinder checkpoint radius="0.1.5" height="0.01" position="-0.164 0.111 2.363"  color="#39BB82"></a-cylinder>

Can anyone spot where I'm going wrong?

  • I think the checkpoint-controls are broken - you can make a 'poor mans' version from the `animation` component :) check it out in [this glitch](https://gftruj-aframe-gotoanimation.glitch.me/) – Piotr Adam Milewski Mar 25 '20 at 22:23
  • Wow, thank you so much!! Is it possible to turn off keyboard controls so this navigation is the only way the user can move around? – Gretchen Creekbaum Mar 26 '20 at 14:38
  • Sure, i've put it all into an answer, let me know if it's understandable. – Piotr Adam Milewski Mar 29 '20 at 12:15
  • Thank you for all of your help! This definitely worked! I do have one more question if you're willing to help again: is it possible to have the animation that takes you to the cylinder also change the view of the camera and height? Basically once I click the cylinder to take me to the position it will also snap my view to the text on the wall even if it is not eye height – Gretchen Creekbaum Apr 08 '20 at 22:02

2 Answers2

1

UPDATE:

I just read the current source of aframe-extra and it seems that nothing is broken! In fact there was a backward-incompatible change in the new versions. Rather than the old syntax of:

universal-controls="movementControls: checkpoint;"

Now this new syntax should be used:

movement-controls="controls: checkpoint;"

But keep in mind that since version 3.2.7, the movement offset is calculated on all 3 XYZ axis and therefore the camera will move to the center of the checkpoint. If you want to preserve the height (y) then simply add the code below above line 83:

targetPosition.y = position.y;

Here is a complete working example:

<html>
  <head>
    <meta charset="utf-8">
    <title>Checkpoint Control with AFrame 1.2.0</title>
    <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/donmccurdy/aframe-extras@v6.1.1/dist/aframe-extras.min.js"></script>
  </head>
  <body>
    <a-scene stats>

      <!-- CAMERA -->
      <a-entity position="0 0 0" id="pov">
        <a-camera camera="active: true; spectator: false;" look-controls="pointerLockEnabled:true" movement-controls="controls: checkpoint;" checkpoint-controls="mode: animate; animateSpeed: 10" wasd-controls="enabled: false;" position="0 1.6 22">
          <a-cursor></a-cursor>
        </a-camera>
      </a-entity>

      <!-- CHECKPOINTS -->
      <a-cylinder checkpoint radius="0.5" height="0.01" position="0 0 20" color="#FF0000"></a-cylinder>
      <a-cylinder checkpoint radius="0.5" height="0.01" position="0 0 16" color="#FF0000"></a-cylinder>
      <a-cylinder checkpoint radius="0.5" height="0.01" position="0 0 12" color="#FF0000"></a-cylinder>
      <a-cylinder checkpoint radius="0.5" height="0.01" position="0 0 8" color="#FF0000"></a-cylinder>

    </a-scene>
  </body>
</html>

Information below this line is not valid anymore.


As Piotr already mentioned, the new releases of Aframe-Extra are somehow broken! Using an older version everything will work again.

Below is a working example with Aframe-extra version 3.2.7.

Once the page is fully loaded, click on the screen to lock the cursor, then point the cursor (tiny ring) at a red circle and click.

I also noted few additional options just in case:

  • spectator: false (switch between 1st and 3rd person view)
  • pointerLockEnabled:true (hide the mouse)
  • mode: animate (the other option is teleport)
  • animateSpeed: 10 (well... adjusts the animation speed)
  • wasd-controls="enabled: false;" (otherwise user can move around via WASD/arrow keys)

Code:

<html>
  <head>
    <meta charset="utf-8">
    <title>Checkpoint Control with AFrame 1.2.0</title>
    <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/donmccurdy/aframe-extras@v3.2.7/dist/aframe-extras.min.js"></script>
  </head>
  <body>
    <a-scene stats>

      <!-- CAMERA -->
      <a-entity position="0 0 0" id="pov">
        <a-camera camera="active: true; spectator: false;" look-controls="pointerLockEnabled:true" universal-controls="movementControls: checkpoint;" checkpoint-controls="mode: animate; animateSpeed: 10" wasd-controls="enabled: false;" position="0 1.6 22">
          <a-cursor></a-cursor>
        </a-camera>
      </a-entity>

      <!-- CHECKPOINTS -->
      <a-cylinder checkpoint radius="0.5" height="0.01" position="0 0 20" color="#FF0000"></a-cylinder>
      <a-cylinder checkpoint radius="0.5" height="0.01" position="0 0 16" color="#FF0000"></a-cylinder>
      <a-cylinder checkpoint radius="0.5" height="0.01" position="0 0 12" color="#FF0000"></a-cylinder>
      <a-cylinder checkpoint radius="0.5" height="0.01" position="0 0 8" color="#FF0000"></a-cylinder>

    </a-scene>
  </body>
</html>
Dark
  • 413
  • 5
  • 8
  • Has this content been further updated moving into version 1.40 of A-Frame and 7.0.0 of A-Frame Extras? Functionality of checkpoints no longer seems to be functioning with the provided example. – Cameron Whiting May 18 '23 at 02:11
0

This won't answer the question, but should solve your problem.

You can substitute the checkpoint-controls with a simple animation system:

  1. you click on a cylinder
  2. you animate the camera from the current position to the cylinder

Which could be implemented like this:

// use a system to keep a global track if we are already moving
AFRAME.registerSystem('goto', {
  init: function() {
    this.isMoving = false
  }
})

// this component will have the actual logic
AFRAME.registerComponent('goto', {
  init: function() {
     let camRig = document.querySelector('#rig')

     // upon click - move the camera
     this.el.addEventListener('click', e => {
        // check if we are already moving
        if (this.system.isMoving) return;

        // lock other attempts to move
        this.system.isMoving = true

        // grab the positions
        let targetPos = this.el.getAttribute("position")
        let rigPos = camRig.getAttribute("position")

        // set the animation attributes. 
        camRig.setAttribute("animation", {
          "from": rigPos,
          "to": AFRAME.utils.coordinates.stringify({x: targetPos.x, y: rigPos.y, z: targetPos.z}),
          "dur": targetPos.distanceTo(rigPos) * 750
        })
        camRig.emit('go')
     })

     // when the animation is finished - update the "shared" variable
     camRig.addEventListener('animationcomplete', e=> {
       this.system.isMoving = false
     })
  }
})

with a setup like this:

<!-- Camera with locked movement --/>
<a-entity id="rig" animation="property: position; startEvents: go">
  <a-camera look-controls wasd-controls-enabled="false"></a-camera>
<a-entity>

<!-- Cylinder node --/>
<a-cylinder goto></a-cylinder>

You can see it working in this glitch.

Piotr Adam Milewski
  • 14,150
  • 3
  • 21
  • 42