{"id":2555,"date":"2020-07-18T14:30:00","date_gmt":"2020-07-18T14:30:00","guid":{"rendered":"http:\/\/inspiredtoeducate.net\/inspiredtoeducate\/?p=2555"},"modified":"2023-10-28T12:54:51","modified_gmt":"2023-10-28T12:54:51","slug":"build-a-aframe-io-scene-on-oculus-quest-with-teleportation","status":"publish","type":"post","link":"https:\/\/inspiredtoeducate.net\/inspiredtoeducate\/build-a-aframe-io-scene-on-oculus-quest-with-teleportation\/","title":{"rendered":"Build an AFrame.IO Scene on Oculus Quest with Teleportation"},"content":{"rendered":"\n<!-- Facebook Like Button v1.9.6 BEGIN [http:\/\/blog.bottomlessinc.com] -->\n<iframe src=\"http:\/\/www.facebook.com\/plugins\/like.php?href=https%3A%2F%2Finspiredtoeducate.net%2Finspiredtoeducate%2Fbuild-a-aframe-io-scene-on-oculus-quest-with-teleportation%2F&amp;layout=standard&amp;show_faces=false&amp;width=450&amp;action=like&amp;colorscheme=light\" scrolling=\"no\" frameborder=\"0\" allowTransparency=\"true\" style=\"border:none; overflow:hidden; width:450px; height: 30px; align: left; margin: 2px 0px 2px 0px\"><\/iframe>\n<!-- Facebook Like Button END -->\n<p><img src=\"http:\/\/inspiredtoeducate.net\/inspiredtoeducate\/wp-content\/uploads\/2020\/07\/firefox-mixed-reality.png\" alt=\"FireFox Mixed Reality\" \/><\/p>\n<p>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 <a href=\"https:\/\/aframe.io\/\">AFrame.IO<\/a> work well on the Oculus platform.  These are exciting times and trends!<\/p>\n<h2>AFrame.IO Script for Oculus WebXR<\/h2>\n<p>Fork the script at <a href=\"https:\/\/aframeexamples.glitch.me\/\">https:\/\/aframeexamples.glitch.me<\/a>.  In 2023, I feel that <a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/twitter.com\/ProfStemkoski\">@ProfStemkoski<\/a> 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 &#8220;quest-extras.html&#8221;, you&#8217;ll find an approachable example for starting with a &#8220;player movement&#8221; component that works with Oculus Quest.   This example also shows an example for object interactivity via raycasting.<\/p>\n<pre data-language=HTML><code class=\"language-markup \">&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n\n&lt;head&gt;\n    &lt;title&gt;A-Frame: Quest movement and interaction&lt;\/title&gt;\n    &lt;meta name=\"description\" content=\"Moving around an A-Frame scene with Quest touch controllers.\"&gt;\n    &lt;script src=\"https:\/\/aframe.io\/releases\/1.3.0\/aframe.min.js\"&gt;&lt;\/script&gt;\n    &lt;script src=\"js\/aframe-environment-component.js\"&gt;&lt;\/script&gt;\n    &lt;script src=\"js\/controller-listener.js\"&gt;&lt;\/script&gt;\n    &lt;script src=\"js\/player-move.js\"&gt;&lt;\/script&gt;\n    &lt;script src=\"js\/raycaster-extras.js\"&gt;&lt;\/script&gt;\n&lt;\/head&gt;\n\n&lt;body&gt;\n\n&lt;script&gt;\n\/\/ if raycaster is pointing at this object, press trigger to change color\nAFRAME.registerComponent(\"raycaster-color-change\", {\n    init: function () \n    {\n        this.colors = [\"red\", \"orange\", \"yellow\", \"green\", \"blue\", \"violet\"];\n        this.controllerData = document.querySelector(\"#controller-data\").components[\"controller-listener\"];\n        this.hoverData      = this.el.components[\"raycaster-target\"];\n    },\n\n    tick: function()\n    {\n        if (this.hoverData.hasFocus &amp;&amp; this.controllerData.rightTrigger.pressed )\n        {\n            let index = Math.floor( this.colors.length * Math.random() );\n            let color = this.colors[index];\n            this.el.setAttribute(\"color\", color);\n        }\n\n        if (!this.hoverData.hasFocus || this.controllerData.rightTrigger.released)\n        {\n            this.el.setAttribute(\"color\", \"#CCCCCC\");\n        }\n    }\n});\n\n\n&lt;\/script&gt;\n\n&lt;a-scene environment=\"preset: default;\" renderer=\"antialias: true;\"&gt;\n\n    &lt;a-assets&gt;\n        &lt;img id=\"gradient\" src=\"images\/gradient-fade.png\" \/&gt;\n    &lt;\/a-assets&gt;\n\n    &lt;a-sky \n        color = \"#000337\"&gt;\n    &lt;\/a-sky&gt;\n\n    &lt;!-- use a simple mesh for raycasting\/navigation --&gt;\n    &lt;a-plane\n        width=\"100\" height=\"100\"\n        rotation=\"-90 0 0\"\n        position=\"0 0.01 0\"\n        visible=\"false\"\n        class=\"groundPlane\"\n        raycaster-target&gt;\n    &lt;\/a-plane&gt;\n\n    &lt;a-entity \n        id=\"player\" \n        position=\"0 0 0\" \n        player-move=\"controllerListenerId: #controller-data;\n                     navigationMeshClass: groundPlane;\"&gt;\n\n        &lt;a-camera&gt;&lt;\/a-camera&gt;\n\n        &lt;a-entity \n            id=\"controller-data\" \n            controller-listener=\"leftControllerId:  #left-controller; \n                                 rightControllerId: #right-controller;\"&gt;\n        &lt;\/a-entity&gt;\n\n        &lt;a-entity \n            id=\"left-controller\"\n            oculus-touch-controls=\"hand: left\"&gt;\n        &lt;\/a-entity&gt;\n\n        &lt;!-- experiment with raycasting interval; slight performance improvement but jittery appearance in world --&gt;\n        &lt;a-entity\n            id=\"right-controller\"\n            oculus-touch-controls=\"hand: right\"\n            raycaster=\"objects: .raycaster-target; interval: 0;\"\n            raycaster-extras=\"controllerListenerId: #controller-data; \n                              beamImageSrc: #gradient; beamLength: 0.5;\"&gt;\n        &lt;\/a-entity&gt;\n\n    &lt;\/a-entity&gt;\n\n    &lt;a-torus-knot \n        p=\"2\" q=\"3\" radius=\"0.5\" radius-tubular=\"0.1\"\n        position = \"-2.5 1.5 -4\"\n        color=\"#CC3333\"\n        raycaster-target&gt;\n    &lt;\/a-torus-knot&gt;\n\n    &lt;a-box\n        width = \"2\" height = \"1\" depth = \"1\"\n        position = \"-1 0.5 -3\"\n        rotation = \"0 45 0\"  \n        color = \"#FF8800\"\n        class = \"\"\n        raycaster-target&gt;\n    &lt;\/a-box&gt;\n\n    &lt;a-sphere\n        radius = \"1.25\"\n        position = \"0 1.25 -5\"\n        color = \"#DDBB00\"\n        raycaster-target&gt;\n    &lt;\/a-sphere&gt;\n\n    &lt;a-cylinder\n        radius = \"0.5\" height = \"1.5\"\n        position = \" 1 0.75 -3\"\n        color = \"#008800\" \n        raycaster-target&gt;\n    &lt;\/a-cylinder&gt;\n\n    &lt;a-cone\n        radius-bottom = \"1\" radius-top = \"0\" height = \"2\"\n        position = \"3 1 -4\"\n        color = \"#4444CC\"\n        raycaster-target&gt;\n    &lt;\/a-cone&gt;\n\n    &lt;a-torus \n        radius=\"0.5\" radius-tubular=\"0.1\"\n        position = \"2 3 -4\"\n        rotation = \"30 -20 0\"\n        color=\"#8800FF\"\n        raycaster-target&gt;\n    &lt;\/a-torus&gt;\n\n    &lt;!-- demo interaction boxes --&gt;\n\n    &lt;a-dodecahedron\n        radius = \"0.5\"\n        position = \"-0.8 1 -2\"\n        color = \"#EEEEEE\"\n        raycaster-target=\"canGrab: true;\"\n        raycaster-color-change&gt;\n    &lt;\/a-dodecahedron&gt;\n\n    &lt;a-icosahedron\n        radius = \"0.5\"\n        position = \"0.8 1 -2\"\n        color = \"#EEEEEE\"\n        raycaster-target=\"canGrab: true;\"\n        raycaster-color-change&gt;\n    &lt;\/a-icosahedron&gt;\n\n&lt;\/a-scene&gt;\n\n&lt;\/body&gt;\n&lt;\/html&gt;\n<\/code><\/pre>\n<p>I also admire the work of <a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/ada.is\/index.html\">Ada Rose Canon<\/a> too.  You can find a very complete starter kit for AFrame.IO here:<br \/>\n<a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/aframe-xr-starterkit.glitch.me\/\">https:\/\/aframe-xr-starterkit.glitch.me\/<\/a>.   This example shows features like collision detection, AR integration, and more.<\/p>\n<p>Let us know if you make anything cool!!<\/p>\n<p><strong>Top Stories on InspiredToEducate.NET<\/strong><\/p>\n<ul>\n<li><a href=\"http:\/\/inspiredtoeducate.net\/inspiredtoeducate\/sonic-pi-sound-synth-application-for-learning-coding-and-music\/\">Sonic-PI: Sound synth application for learning coding and music<\/a><\/li>\n<li><a href=\"http:\/\/inspiredtoeducate.net\/inspiredtoeducate\/using-android-javascript-and-arduino-to-control-your-robot-makered-javascript-android\/\">Using Android, JavaScript, and Arduino to control your robot.<\/a><\/li>\n<\/ul>\n\n<!-- Facebook Like Button v1.9.6 BEGIN [http:\/\/blog.bottomlessinc.com] -->\n<iframe src=\"http:\/\/www.facebook.com\/plugins\/like.php?href=https%3A%2F%2Finspiredtoeducate.net%2Finspiredtoeducate%2Fbuild-a-aframe-io-scene-on-oculus-quest-with-teleportation%2F&amp;layout=standard&amp;show_faces=false&amp;width=450&amp;action=like&amp;colorscheme=light\" scrolling=\"no\" frameborder=\"0\" allowTransparency=\"true\" style=\"border:none; overflow:hidden; width:450px; height: 30px; align: left; margin: 2px 0px 2px 0px\"><\/iframe>\n<!-- Facebook Like Button END -->\n","protected":false},"excerpt":{"rendered":"<p>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 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,23,8],"tags":[],"_links":{"self":[{"href":"https:\/\/inspiredtoeducate.net\/inspiredtoeducate\/wp-json\/wp\/v2\/posts\/2555"}],"collection":[{"href":"https:\/\/inspiredtoeducate.net\/inspiredtoeducate\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/inspiredtoeducate.net\/inspiredtoeducate\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/inspiredtoeducate.net\/inspiredtoeducate\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/inspiredtoeducate.net\/inspiredtoeducate\/wp-json\/wp\/v2\/comments?post=2555"}],"version-history":[{"count":18,"href":"https:\/\/inspiredtoeducate.net\/inspiredtoeducate\/wp-json\/wp\/v2\/posts\/2555\/revisions"}],"predecessor-version":[{"id":2791,"href":"https:\/\/inspiredtoeducate.net\/inspiredtoeducate\/wp-json\/wp\/v2\/posts\/2555\/revisions\/2791"}],"wp:attachment":[{"href":"https:\/\/inspiredtoeducate.net\/inspiredtoeducate\/wp-json\/wp\/v2\/media?parent=2555"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/inspiredtoeducate.net\/inspiredtoeducate\/wp-json\/wp\/v2\/categories?post=2555"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/inspiredtoeducate.net\/inspiredtoeducate\/wp-json\/wp\/v2\/tags?post=2555"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}