Hey web developers! Looking for a fun way to build VR experiences on the Oculus Quest? This tutorial will provide a brief guide to drafting an AFrame.IO VR experience that includes GLTF model loading and teleportation controls. As web developers, we have the unique opportunity to link data, models, and services to WebXR experiences. We really love seeing AFrame.IO work well on the Oculus platform. These are exciting times and trends!
AFrame.IO Script for Oculus WebXR
Fork the script at https://aframeexamples.glitch.me. In 2023, I feel that @ProfStemkoski has created one of the best collections of AFrame.IO templates. I like how he keeps his examples relatively small. It makes it easier to find a starting point for your project. Under the “quest-extras.html”, you’ll find an approachable example for starting with a “player movement” component that works with Oculus Quest. This example also shows an example for object interactivity via raycasting.
<!DOCTYPE html>
<html>
<head>
<title>A-Frame: Quest movement and interaction</title>
<meta name="description" content="Moving around an A-Frame scene with Quest touch controllers.">
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
<script src="js/aframe-environment-component.js"></script>
<script src="js/controller-listener.js"></script>
<script src="js/player-move.js"></script>
<script src="js/raycaster-extras.js"></script>
</head>
<body>
<script>
// if raycaster is pointing at this object, press trigger to change color
AFRAME.registerComponent("raycaster-color-change", {
init: function ()
{
this.colors = ["red", "orange", "yellow", "green", "blue", "violet"];
this.controllerData = document.querySelector("#controller-data").components["controller-listener"];
this.hoverData = this.el.components["raycaster-target"];
},
tick: function()
{
if (this.hoverData.hasFocus && this.controllerData.rightTrigger.pressed )
{
let index = Math.floor( this.colors.length * Math.random() );
let color = this.colors[index];
this.el.setAttribute("color", color);
}
if (!this.hoverData.hasFocus || this.controllerData.rightTrigger.released)
{
this.el.setAttribute("color", "#CCCCCC");
}
}
});
</script>
<a-scene environment="preset: default;" renderer="antialias: true;">
<a-assets>
<img id="gradient" src="images/gradient-fade.png" />
</a-assets>
<a-sky
color = "#000337">
</a-sky>
<!-- use a simple mesh for raycasting/navigation -->
<a-plane
width="100" height="100"
rotation="-90 0 0"
position="0 0.01 0"
visible="false"
class="groundPlane"
raycaster-target>
</a-plane>
<a-entity
id="player"
position="0 0 0"
player-move="controllerListenerId: #controller-data;
navigationMeshClass: groundPlane;">
<a-camera></a-camera>
<a-entity
id="controller-data"
controller-listener="leftControllerId: #left-controller;
rightControllerId: #right-controller;">
</a-entity>
<a-entity
id="left-controller"
oculus-touch-controls="hand: left">
</a-entity>
<!-- experiment with raycasting interval; slight performance improvement but jittery appearance in world -->
<a-entity
id="right-controller"
oculus-touch-controls="hand: right"
raycaster="objects: .raycaster-target; interval: 0;"
raycaster-extras="controllerListenerId: #controller-data;
beamImageSrc: #gradient; beamLength: 0.5;">
</a-entity>
</a-entity>
<a-torus-knot
p="2" q="3" radius="0.5" radius-tubular="0.1"
position = "-2.5 1.5 -4"
color="#CC3333"
raycaster-target>
</a-torus-knot>
<a-box
width = "2" height = "1" depth = "1"
position = "-1 0.5 -3"
rotation = "0 45 0"
color = "#FF8800"
class = ""
raycaster-target>
</a-box>
<a-sphere
radius = "1.25"
position = "0 1.25 -5"
color = "#DDBB00"
raycaster-target>
</a-sphere>
<a-cylinder
radius = "0.5" height = "1.5"
position = " 1 0.75 -3"
color = "#008800"
raycaster-target>
</a-cylinder>
<a-cone
radius-bottom = "1" radius-top = "0" height = "2"
position = "3 1 -4"
color = "#4444CC"
raycaster-target>
</a-cone>
<a-torus
radius="0.5" radius-tubular="0.1"
position = "2 3 -4"
rotation = "30 -20 0"
color="#8800FF"
raycaster-target>
</a-torus>
<!-- demo interaction boxes -->
<a-dodecahedron
radius = "0.5"
position = "-0.8 1 -2"
color = "#EEEEEE"
raycaster-target="canGrab: true;"
raycaster-color-change>
</a-dodecahedron>
<a-icosahedron
radius = "0.5"
position = "0.8 1 -2"
color = "#EEEEEE"
raycaster-target="canGrab: true;"
raycaster-color-change>
</a-icosahedron>
</a-scene>
</body>
</html>
I also admire the work of Ada Rose Canon too. You can find a very complete starter kit for AFrame.IO here:
https://aframe-xr-starterkit.glitch.me/. This example shows features like collision detection, AR integration, and more.
Let us know if you make anything cool!!
Top Stories on InspiredToEducate.NET