How to do multiuser in A-Frame? - aframe

What are the options I can incorporate multiuser into A-Frame?
Below is example code where I want the black sphere to represent each player:
<script src="https://aframe.io/releases/0.5.0/aframe.min.js"></script>
<a-scene>
<a-sphere id="player" color="black"></a-sphere>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>

Multiuser is still being fleshed out as the community and the team continue to experiment. Networked physics is something that needs to be implemented well and there are a few methods from the game industry that can be ported to the Web. There are a few initial options as of time of writing:
https://github.com/haydenjameslee/networked-aframe - Networked A-Frame by Hayden Lee that uses WebRTC and a server. Here's a Glitch we can remix to get started: https://glitch.com/~networked-aframe
<script src="https://aframe.io/releases/0.5.0/aframe.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.5/socket.io.min.js"></script>
<script src="easyrtc/easyrtc.js"></script>
<script src="https://unpkg.com/networked-aframe/dist/networked-aframe.min.js"></script>
<script>
function onConnect() {
NAF.entities.createAvatar('#avatar-template', '0 1.6 0', '0 0 0');
}
</script>
<a-scene network-scene>
<a-assets>
<script id="avatar-template" type="text/html">
<a-sphere color="black"></a-sphere>
</script>
</a-assets>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>
Another option is http://lance.gg/ , a real-time multiplayer game server. It provides an extendible Node.JS based server, on which game logic runs, as well as a client-side library which synchronizes the client's game state with the server game state. In order to provide a smooth visual experience for each connected client, Lance implements efficient networking methods, position interpolation and extrapolation, user input coordination, shadow objects, physics and pseudo-physical movement, automatic handling of network spikes.
An older option is https://github.com/ngokevin/kframe/tree/master/components/firebase - Firebase component using Firebase real-time database server so you don't need to host your own server.

Related

Multiple Distinct Cameras in A-Frame

I am working on a scene with multiple cameras set at distinct predefined positions and rotations. I noticed when I look around using the mouse (or in VR mode), the camera rotation is linked between cameras. So I thought this could be avoided by using the attribute active: false but both cameras still rotate together. Below is an example scene where both cameras are at the same position and feature an <a-box> in their field of view, notice that when you look around the scene box cubes (children of two separate cameras) move in unison. Is there a way to prevent the inactive camera from following the rotation of the active camera so that the blue cube (with the inactive camera) would stay stationary?
Also, there are no console errors related to A-Frame in this script. Your assistance is greatly appreciated, many thanks in advance for your time.
<!DOCTYPE html>
<html>
<head>
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
</head>
<body>
<a-scene>
<a-camera active="true" look-controls>
<a-box color="red" position="-2 0 -10"></a-box>
</a-camera>
<a-camera active="false" look-controls>
<a-box color="blue" position="2 0 -10"></a-box>
</a-camera>
<a-plane color="gray" rotation="-90 0 0" width="20" height="20"></a-plane>
</a-scene>
</body>
</html>
A viable solution for this is to enable and disable the look-controls on the cameras when switching between them. This can be done in JavaScript with : newCameraElement.setAttribute('look-controls', 'enabled', true); and oldCameraElement.setAttribute('look-controls', 'enabled', false); Here's a revised version of the question's example that initially disables the other camera's look-controls to provide the desired behaviour of having distinct cameras:
<!DOCTYPE html>
<html>
<head>
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
</head>
<body>
<a-scene>
<a-camera active="true" look-controls>
<a-box color="red" position="-2 0 -10"></a-box>
</a-camera>
<a-camera active="false" look-controls="enabled: false">
<a-box color="blue" position="2 0 -10"></a-box>
</a-camera>
<a-plane color="gray" rotation="-90 0 0" width="20" height="20"></a-plane>
</a-scene>
</body>
</html>

AFrame Animation Start\End Condition

I'm trying to get the cylinder to begin and pause rotating on mouse click but I can only get it to begin, not stop. I'm not sure what else would work? When I add the end condition it stops working all together. My question is, how can I get the begin and end conditions to be the same input?
<<html>
<head>
<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-environment-component/dist/aframe-
environment-component.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/annyang/2.5.0/annyang.min.js">
</script>
<script src="/components/voice-commands.js"></script>
</head>
<body>
<button>Go</button>
<a-scene>
<a-assets>
<img id="sky" src="sky2.0.jpg">
</a-assets>
<a-camera position="0 1.6 0">
<a-cursor></a-cursor>
</a-camera>
<a-box position="0 -2 0" color="grey" scale="30 2.5 20"></a-box>
<a-cylinder id="center" position="17 0 0" color="grey" scale="4 4 4"
rotation="0 0 90">
<a-sphere position="0 -0.375 0" color="grey" scale="1 1 1"
rotation="0 0 90"></a-sphere>
<a-box position="8 0 0" color="grey" scale="15 0.25 1" rotation="-20
0 0"></a-box>
<a-box position="-3.5 0 6" color="grey" scale="15 0.25 1"
rotation="-20 240 0"></a-box>
<a-box position="-3.5 0 -6" color="grey" scale="15 0.25 1"
rotation="-20 -240 0"></a-box>
<a-animation attribute="rotation" begin="click" end="click"
dur="20000" to="360 0 90" repeat="indefinite" easing="linear"></a-animation>
</a-cylinder>
<a-sky src="#sky"></a-sky>
<a-cylinder position="0 -402 0" color="grey" scale="5 800 5" rotation="0 0
0">
<a-entity id="annyang" annyang-voice-recognition></a-entity>
</a-scene>
</body>
</html>
I would threw the logic to a seperate a-frame component.
Having a setup like this:
<a-cylinder animation-controller
animation="resumeEvents: start; pauseEvents: pause">
</a-cylinder>
When clicked - switch a boolean, and depending on the value start or stop the animation:
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
<script>
AFRAME.registerComponent("animation-controller", {
init: function() {
this.running = false
this.el.addEventListener("click", (e) => {
if (!this.running) {
this.el.emit("start") // animation not running - start it
} else {
this.el.emit("pause") // animation running - stop it
}
this.running = !this.running // flip the flag
})
}
})
</script>
<a-scene cursor="rayOrigin: mouse">
<a-cylinder animation-controller position="0 1 -3" color="red"
animation="property: rotation; to: 0 0 360; dur:1000; loop: true; resumeEvents: start; pauseEvents: pause">
</a-cylinder>
</a-scene>
Original answer - for aframe < 1.0.0
I would threw the logic to a seperate a-frame component.
Having a setup like this:
<a-cylinder anim-controller>
<a-animation begin="start" end="stop" (...)></a-animation>
</a-cylinder>
When clicked - switch a boolean, and depending on the value start or stop the animation:
AFRAME.registerComponent("anim-controller", {
init: function() {
this.running = false
this.animComp = document.querySelector("a-animation")
this.el.addEventListener("click", (e) => {
if (!this.running) {
this.animComp.emit("start") // animation not running - start it
} else {
this.animComp.emit("stop") // animation running - stop it
}
this.running = !this.running // flip the flag
})
}
})
Simple - if the animation is running - start it. Otherwise stop it.
Fiddle here.

Unable to Control Camera Position in VR on Oculus Go

I am using aframe to create an experience for Oculus Go. I have a simple "world" and I am able to move around it using the Oculus Go controller. However, I don't seem to be able to set the initial camera position or reset the camera location at any point. The initial problem means that my viewpoint is always close to the ground.
Here is my code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Pailou Gate</title>
<meta name="description" content="Pailou Gate">
<script src="../aframe/dist/aframe-master.js"></script>
<script src="//cdn.rawgit.com/donmccurdy/aframe-extras/v4.1.2/dist/aframe-extras.min.js"></script>
</head>
<body>
<a-scene background="color: #9cf" antialias="true">
<a-assets>
<a-asset-item id="pl" src="pl.dae"></a-asset-item>
</a-assets>
<a-entity wasd-controls mouse-controls look-controls movement-controls="fly: false" position="0 0 0">
<a-entity camera position="0 4 0"></a-entity>
<a-entity oculus-go-controls></a-entity>
<a-entity laser-controls="hand: right"></a-entity>
</a-entity>
<a-light position="0 0.5 1" intensity="0.8"></a-light>
<a-light type="point" position="20 30 -40" intensity="0.9" light="castShadow: true;"></a-light>
<a-collada-model src="#pl" position="0 0.4 0" rotation="0 0 0" scale="1 1 1" shadow="cast: true; receive: false"></a-collada-model>
<a-circle rotation="-90 0 0" radius="40" color="#393" position="0 -0.1 0" shadow="receive: true" roughness="1"></a-circle>
<a-torus radius="40" arc="360" color="#6c6" rotation="-90 0 0"></a-torus>
</a-scene>
</body>
</html>
I think the relevant bit is the entity surrounding the camera and the camera itself. Notice that I do set the camera high, but this seems to be ignored.
Any thoughts?
Sean
Set the position and movement controls on the camera rig (parent entity of the camera) and look-controls on the camera:
<a-entity wasd-controls position="0 4 0">
<a-entity camera look-controls></a-entity>
</a-entity>

Aframe audio issue

I have included below audio asset in my scene. In two ways tried it....
<audio id="hover" src="resources/assets_data/hover.mp3"></audio>
and
<a-asset-item id="hover" src="resources/assets_data/hover.mp3" response-type="arraybuffer"></a-asset-item>
When I am trying to play this sound in four menu elements I am getting below error... and hover sound is playing only on first menu curved image....
components:sound:warn Sound not loaded yet. It will be played once it
finished loading
Code:
<a-curvedimage src="#a" transparent="true"
height="0.5" radius="0.9" theta-length="40" rotation="0 240 0" position="0 1.74 -1.4" sound="on: mouseenter; src: #hover" selectable>
</a-curvedimage>
<a-curvedimage src="#b" transparent="true"
height="0.5" radius="0.9" theta-length="40" rotation="0 190 0" position="0 1.74 -1.4" sound="on: mouseenter; src: #hover" selectable>
</a-curvedimage>
<a-curvedimage src="#c" transparent="true"
height="0.5" radius="0.9" theta-length="40" rotation="0 130 0" position="0 1.74 -1.4" sound="on: mouseenter; src: #hover" selectable>
</a-curvedimage>
<a-curvedimage src="#d" transparent="true"
height="0.5" radius="0.9" theta-length="40" rotation="0 80 0" position="0 1.74 -1.4" sound="on: mouseenter; src: #hover" selectable>
</a-curvedimage>
seems to be working when i used an audio tag with the preload: auto attribute:
<a-assets>
<audio id="mysound" crossorigin="anonymous" src="...">
</a-assets>
Try it out here.

Texture Aframe Object

I am loading an Aframe object in the wavefront format, but the texture remains invisible, that means the object appears all black:
<!doctype html>
<head>
<meta charset="utf-8">
<script src="https://aframe.io/releases/0.3.2/aframe.min.js"></script>
</head>
<body>
<a-scene>
<a-assets>
<a-asset-item id="test-obj" src="test.obj"></a-asset-item>
<a-asset-item id="test-mtl" src="test.mtl"></a-asset-item>
</a-assets>
<a-entity position="1.75 0 1.2" rotation="0 28 0">
<a-camera near="0.1" user-height="0"></a-camera>
</a-entity>
<a-obj-model src="#test-obj" mtl="#test-mtl" scale="0.1 0.1 0.1"></a-obj-model>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>
</body>
</html>
How can I make the texture of this model visible?
Here's a solution that may work if the object was created in Magica Voxel or a similar editor.
Open your .mtl file in a text editor, look for the line that starts with map_Kd. Just after it is the name of another file such as "test.png".
That file must also be in the same directory as your .mtl and .obj files, so make sure you include it. It's the texture map that maps colors to locations on the object.
More information about the Wavefront .mtl file format can be found here:
https://people.cs.clemson.edu/~dhouse/courses/405/docs/brief-mtl-file-format.html

Resources