Unity Mirror - How To Perform Individual Scene Traveling?

5.1k views Asked by At

I'm a little stuck on what to do here. I haven't gotten any help from the discord server so I'm turning here in hopes someone has some insight for me.

Background:

Here is what I'm trying to accomplish. I want to have a server+client host (using Unity Mirror) but allow all clients to travel back and forth between scenes separately. The concept seems simple enough but I haven't found a good solution yet. Please note that I have server reconciliation setup for player movement.

What I Have Tried:

Every time a client wants to travel to a new scene he sends a request to the server. The server will additively load the scene and send an RPC back to the client who will also additively load the scene. Then the scene has been successfully loaded, either by the client or the server it will call the MoveObjects command (on the SceneManager) to move the player character to the new scene. So that means that reconcilation should* still be okay. If you're not the server then unload the old scene. If you're the server keep all scenes additively loaded when there are still clients in that scene.

The only issue with my above approach is that I can't disable/hide scenes on the server (or at least I don't know how to do that yet).

My Request

Is this the best approach? Are there free code examples I could look at? Tutorials that might explain a better approach? Has anyone else done this with a better method? I would really appreciate any help I could get on this.

Final Thoughts

The last thing I thought about what dynamically starting a new server and connecting to the new server for every new unity scene to separate players that way. The only problem with this approach is it breaks cross scene communication. Like if I wanted to display the scene the player was in and their current health to all players in a party across multiple scenes.

1

There are 1 answers

0
wesleywh On BEST ANSWER

This is somewhat complicated. However, I was able to achieve it like the following:

  1. Make a travel function, this function will have the clients simply send a request to the server to have the server load the scene itself and then tell the clients to do the same. In the travel function it will just have a simple call like this:
NetworkClient.Send(new ClientRequestLoadScene() { sceneName = sceneName, travelPoint = travelPoint }); 
  1. On the server register a custom handler that will expect this message type. Load the scene yourself if it isn't already loaded, then tell the client to load a scene using the built in handler that is registered with clients out of the box like so:
conn.Send(new SceneMessage() { sceneName = msg.sceneName, sceneOperation = SceneOperation.LoadAdditive });
  1. When the server has finished loading that scene move that clients player to the new scene:
SceneManager.MoveGameObjectToScene(character, SceneManager.GetSceneByName(GetCleanedSceneName(msg.sceneName)));
  1. Include the NetworkSceneChecker to have visibility only when you're in that particular scene
  2. (Optional) Include the PhysicsSimulator component if you have the scene loaded with 3d physics.

Now this doesn't give every tiny little detail on how to do this but this is a good starting point to understand how you might be able to accomplish this. The big take aways are the following:

  • The clients will not load the scenes themselves unless they explicity receive a request to do so from the server
  • clients need to tell the server what scene they need to load
  • clients need to tell the server when they're done loading
  • the server needs to load all requested scenes
  • the server is responsible for moving the player to the new scene