Unless you have a second computer or friends that have nothing to do with their lives except help you prototype your game, you’ve probably run into this scenario: You code a multiplayer SteamVR game, build it so that you can test it, and start the build. Then as soon as you start a second instance of the game, It closes the first one. It makes testing the game Impossible.
Now I know that you can’t run two VR headsets off the same PC without a virtual machine setup so this method is just so that you can run multiple instances without SteamVR shutting them down.
For networking, I’m using the current version of Mirror from the asset store (not Github), and for transform and rigidbody syncing I’m using the Smooth Sync plugin just because it’s a cheap and easy solution to something that would take too long for me to code on my own.
Alright in this one we are going to just be setting up our camera rig so that we can see it and adding my walking script so we can walk around. (Don’t worry I’ll do one on picking stuff up)
First, create a new Unity project and then import in the Mirror and Smooth Sync assets. Then create a plane to use as a floor and drag in the SteamVR [CameraRig] prefab. Add a primitive object as a child to the camera and controller objects so that we can see them. Last, create a camera that has an overhead view of the whole scene to be used by our server.
First, we want to set up Mirror and smooth sync so that we don’t have to worry about networking later, first add an empty game object and attach a NetworkManager and NetworkHud Script too it, these will manage our network for now.
Next, we want to add a NetworkIdentity script to our [CameraRig]. Now we add a Smooth Sync Mirror script to the prefab and set the Variables To Sync settings so it only syncs position and Velocity to save on package size. (as a general rule of thumb most of the time you want to turn off scale syncing as you very rarely change it) Now we want to add three more of the same script, set the Child object to sync variables to the Camera and controllers. This will take care of their position and rotations.
Now that we have all that taken care of, make this [CameraRig] into a new prefab so we can use it as our character. After that set the Network Manager’s Player prefab to the previously created prefab.
If at this point you sent a build to a friend (Ideas on how in this tutorial) and tested it with them it would work, but you would be standing in the same place and it wouldn’t be that fun, that’s why we are going to add the walking script (tutorial for that here). For the most part, the steps are the same as in the tutorial for singleplayer but we change it to a network behavior and we want to inclose all of the stuff inside the update function (except the collider code) with an if statement like this:
//change this:
public class Movement : MonoBehaviour
//to this:
public class Player : NetworkBehaviour
//and this:
void update()
{
//Code
}
//to this:
void update()
{
//collider code here
if(hasAuthority){//makes sure we only move our player
//rest of code here
}
}
After those changes, the script will work just fine for multiplayer. Now that you have that set up we get to the debugging stage. As I stated before if you try to open two instances of a SteamVR game the first one will be closed since SteamVR can’t handle two games at once. The solution? Make a non SteamVR build. But this isn’t as easy as it sounds as there isn’t really a way to just turn it off, but I found a simple workaround that doesn’t require changing the build settings.
First, we go to our project setting and in the player section go to the XR settings and add None as a VR sdk:
This makes it so that when we build our game it has support for a non-VR mode. The last step is to create a .bat file that opens the built game in this non-VR mode. First, build your game to a Builds folder In the root folder of your project, then in the root folder of your project create a file named StartBuild.bat. (A batch file is just a file that contains commands for a command prompt that can be run instead of typing them in to save time.) Now open the file in a text editor and type this in:
cd Builds
"Name of your project here.exe" -vrmode None
First, it navigates to the builds folder then it executes the build In the non-VR mode.
To use it all you have to do is double click the batch file and it will open the build. The best part about this is that the build is unaltered so you can still use the same build in VR mode if you open it the regular way. (Note: To open in Non-VR mode you have to use the bat file, ctrl-b in unity won’t work, that will just open a regular build)
Now how I use this is by opening a Non-VR instance to use as a server and then I use the unity preview as a client, but you could also go as far to make the non-VR mode playable so that you can test multiple clients by yourself.
One last thing, Add this script to the Player prefab’s camera:
using UnityEngine;
using Mirror;
public class SwitchCamera : NetworkBehaviour
{
public NetworkIdentity NI;
void Awake()
{
if (!NI.hasAuthority)
{
GetComponent<Camera>().enabled = false;
GetComponent<AudioListener>().enabled = false;
}
}
}
What this does is turn off the player FPV cam if we aren’t the player so that the server’s overhead view cam doesn’t auto switch to the player view.
And that this completes this tutorial, I hope I was able to help with some of the early obstacles that most people experience when trying to make a VR multiplayer experience and also that I helped you.