A small set of components for Wonderland Engine for basic networking functionalities using peer.js.
This project uses a host-client architecture, where the user can simply host a session by calling host()
and a client can then join by calling join()
. It supports voice chat out of the box, handles disconnects and kicking. It can be used as a starter for a variety of multi user WebXR projects with Wonderland Engine.
This repository includes a basic scene that you can use as a template for your projects. Anything within the project not documented here is included as part of the polishing of the scene and has been imported from other repositories with permission. Setup instructions can also be found below.
You can reference the included Project/example-scene.wlp
scene.
To install into an existing project, install the components via npm package and then follow the steps in Project Setup.
Install the components from npm as follows:
npm install --save wle-peerjs-networking
Using the default Wonderland Engine setup, after adding the hand objects, you should have the following scene structure for the user:
Player
├── NonVrCamera
├── EyeLeft
├── EyeRight
├── RightHand
└── LeftHand
This structure is useful for transmitting the positions and rotations of the camera and hands. These are used in the networking component.
Next, we need to create an object that contains all the networked objects and components.
This project uses a technique called object pooling for the connected players. This means that every object(s) for each joining player is already instantiated in the scene on startup.
Create an object on "root" and call it something like PeerNetworkedPlayerPool
. This object will
contain two components from this repository: peer-networked-player-pool
and peer-manager
.
For the peer-manager
, make sure your serverId
is changed to a long and unique string. The
placeholder text will work, but might cause issues if another instance of peer.js is using that id.
The parameter networkSendFrequencyInS
determines how often a client/the host sends packages over,
this can be kept at the default. If you wish to have a higher frequency (means higher refresh rate),
you could also lower it. A value of 0 would send packages every frame, for example. Set the
player's head (eye for VR camera) and hands and also networkPlayerPool
(this can be the same
object).
After this has been done, You need to create the pool objects for each player. These need to be a
child of the previously created object or the pooling will not work. Let's create a child object of
PeerNetworkedPlayerPool
called PeerNetworkedPlayer
and a peer-networked-player
component onto
it. Additionally the following hierarchy (naming important here) needs to be recreated under the
object:
PeerNetworkedPlayer
├── Head
├── RightHand
└── LeftHand
You can add meshes to each object for visualization, if you like. We can now copy the hierarchy of
PeerNetworkedPlayer
and the scene is done. Just call either the host()
or join()
functions
to see your scene in action.
You might want to expose a reference in
peer-manager
's init such aswindow.peerManager = this
for testing via console
Functions | Description |
---|---|
host() | Hosts a server with serverId as id |
join() | Joins a server with serverId as Id |
connect(id) | Joins a server with the supplied id |
disconnect() | Disconnects from the server (client) / Ends the server (host) |
kick(id) | (Host) Kicks the user with the id |
sendPackage(key, data) | Sends a package to all users (host & clients), that calls the correspondingly registered callback in addNetworkDataRecievedCallback |
toggleMute() | Toggles the user's audio input's mute setting. |
setOwnMute(mute) | Sets the user's audio input's mute setting |
setOtherMute(id, mute) | Sets another user's audio output's mute setting. |
addConnectionEstablishedCallback(f) / removeConnectionEstablishedCallback(f) | Adds/removes a function to/from a callback list, that gets called when a connection is established. (host & client) |
addDisconnectCallback(f) / removeDisconnectCallback(f) | Adds/removes a function to/from a callback list, that happens when a disconnection occurs. |
addNetworkDataRecievedCallback(key, f) / removeNetworkDataRecievedCallback(key) | Adds a function callback, that gets called if a package with the registered key is recieved. See sendPackage(key, data) . |
Variables | Description |
---|---|
activePlayers | Object containing currently connected active players. |
peer | Contains the peer.js object with the connection, id, etc. |
- Expanding pool: allow more users to join then the defined amount in the scene via dynamically expanding (and perhaps shrinking) the pool.
peer.js - Copyright (c) 2015 Michelle Bu and Eric Zhang, http://peerjs.com Tone.js - Copyright (c) 2014-2020 Yotam Mann https://github.com/Tonejs/Tone.js