Games with multiple maps

I have a problem, what I want to do Is having player playing with communicating scenes. So a player can leave map 01 and go to map 02 while other players are still present on both maps. When a player enters a map I need to notify (to players in that map only) that a new player is entered. So when a player appears all players in that map gets an RPC wich ask them to show a new man and then start keep it’s position updated. How Can I istantiate objects selectively on various clients? Network.Istantiate will obviously not works since it istantiate something on all clients (also on different scenes!)


Yeah maybe question was ways a bit general. Let me try something more specific. I already did lot of networking stuff in C++ by sending UDP packets and ordering them manually with my code. Seems that unity is ways too higher level for me.

I have a server (wich is already a playing player, just with the difference that his machine is the server) and other 3 players. I have several maps.

What I want to do with unity (already done some more complex stuff with C++).

  • Player 1 Ask to server he want to change map
  • Sever tells to player 1 “ok you can change map” (i don’t need for now to check if player is really at map travel point)
  • Player tells to server “I’m Player Z and moved from map X to map Y. Here’s my POS”
  • Server tells to all players in map X (if any) “Player 1 left this map”
  • Server tells to all players in map Y (if any) “Player 1 entered this map”
  • Server starts sending to player 1 continous position updates of players in map Y.
  • Server starts sending to players in map Y continuos position updates of player 1.

Last 2 points are likely

  • For each map
  • For each player(i) in that map
  • For each player(j) in that map
  • if (player(i) is not travelling) && (player (j) is not traveling).
  • Send player(i).transform to player(j) (of course transform will be, pos,scale,quaternion

Something more about travelling state (wich is triggered on the server)

  • Server receives message of a player entered in a travel point
  • Player(z).travelling = true;
  • Player(z).sendMesagge(“Ok you can change map”);
    And when the server receives the message “I’m player Z and I moved from map Y to map X”

Server gets notified: “I’m Player Z and moved from map X to map Y. Here’s my POS”

  • Player(z).Pos = POS;
  • Map(Y).removePlayer(Y);
  • Map(X).addPlayer(Player(z));
  • Player(z).travelling = false;

I miss something important about that! Even an example on how to achieve something simple like that with unity will help me to understand what is missing.

I already get a working application with only 1 map when I move cubes from N different machine. but that’s sounds kinda like some magic done by unity. MasterServer is simple to understand (really love MasterServer class!) But when NetworkViews comes into play I really hate that everything happens like magic. (and in fact is causing troubles across mutiple maps)

I tried to search examples, but all examples use Network.Istantiate (wich is a method I really hate since istantiate something indipendently of the map a player is in.) And all examples have a single map. The only piece of code that was really of minor help is the NetworkLevelLoader I found on the documentation.

I guess the pseudo code now is specific enough to get some concrete help


For example:

@RPC
function LoadLevel (level : String, levelPrefix : int)
{
    Debug.Log("Loading level " + level + " with prefix " + levelPrefix);
    lastLevelPrefix = levelPrefix;

    // There is no reason to send any more data over the network on the default channel,
    // because we are about to load the level, thus all those objects will get deleted anyway
    Network.SetSendingEnabled(0, false);   

    // We need to stop receiving because first the level must be loaded.
    // Once the level is loaded, RPC's and other state update attached to objects in the level are allowed to fire
    Network.isMessageQueueRunning = false;

    // All network views loaded from a level will get a prefix into their NetworkViewID.
    // This will prevent old updates from clients leaking into a newly created scene.
    Network.SetLevelPrefix(levelPrefix);
    Application.LoadLevel(level);
    yield;
    yield;

    // Allow receiving data again
    Network.isMessageQueueRunning = true;
    // Now the level has been loaded and we can start sending out data
    Network.SetSendingEnabled(0, true);

    // Notify our objects that the level and the network is ready
    for (var go in FindObjectsOfType(GameObject))
       go.SendMessage("OnNetworkLoadedLevel", SendMessageOptions.DontRequireReceiver);   
}

According to documentation the RPC is called from the server and is buffered. That’s mean that every player that will connect to the server will authomatically Load a new level (because RPC was buffered for ALL). And on client side every “go” object will receive the message “OnNetworkLoadedLevel”. Is that correct?

That’s mean that if I don’t clear RPC having players across multiple maps means that something is buffered across multiple maps (says X buffered also for map Y) correct?

You have to do networking using a “hub and spoke” or “server with clients” model.

Set it up so that one of your devices is the “master” or “central HQ” for the game.

#CRITICAL NOTE …
.

Important note the basic of communication in Unity networking is the “normal” RPC call.

function RPC (name:String, target:NetworkPlayer, params args:object) : void
Description
Call a RPC function on a specific player

Unity - Scripting API: NetworkView.RPC – see bottom of page

for normal, usual, everyday, conventional, like-in-any-game-you’ve-ever-played, hub and spoke networking concepts, use only the “normal” talk-to-specific-person mode of RPC.

NOTE Unity ALSO offers a “send this message to everyone!” version of RPC. This “send to everyone” version of RPC is useless for and completely unrelated to conventional networking techniques. it seems to be just a novelty. In conventional networking where the “hub” server is in control, and that server tells the various clients what to do, obviously you individually talk to each person-X in different ways.


Does that explanation make sense? In fact is that how your game works at the moment?

Some new programmers think you can do networking with an “everyone talks to everyone” model. Anything is possible but it would be incredibly difficult to do that.

In networking games you have one “central HQ” device that makes all decisions and commands everything.

You can see that your question happily becomes trivial, if you are working that way.

You mention “Network.Istantiate”. Don’t use it, it’s just a demo function for “hello world” projects. (It’s a bit like “Invoke” which is good for beginners but normally you just use coroutines.)

Just to reiterate the above “important note”, there is also a strange version of RPC that “sends to everyone.” It’s irrelevant, don’t use it. Just use the normal RPC call where you specify who you are sending the command to.


As you can see your question is now happily trivial…

“So when a player appears all players in that map gets an RPC showNewManNow(). How can I instantiate objects selectively on various clients?”

simply, showNewManNow() would instantiate the object as you see fit. That’s all there is to it.

Your server may need to call “showNewPurpleMan()” on some clients, but “hideMan()” on others and “showNewYellowMan()” on others. It’s up to the server to do the logic.

Of course, your server can communicate individually, in different ways, with the different clients. (Using the famous “normal” RPC call I note above.)

(You could well have different routines on your puppets and on the centralHQ, or on different types of puppets or puppets in different scenes or different states. The server may well have to ask what scene is playing on a given client, or whatever.)


Just to be absolutely clear: you see how Unity also offers the novelty “send to all” command. As a thought exercise: say Unity only offered that one, and did not have a normal “send to person X” command.

Then in that case … logically, you could not solve your problem! It would be impossible to solve your problem, and indeed all problems like that. (ie, you “could not make MP games.”) The Unity system would be unusable and there would be no Unity MP games!

(Indeed, it’s like the “network.instantiate” command which is just a novelty and never used.)

The “normal” “send to person X” RPC command is the basis of all Unity MP programming.

(Their whole “state Synchronization” thing is clever, and usable if confusing, but unnecessary.)


This is your gift of some 40 years of computer science - the knowledge of how to do networking (hub and spoke model) !

It is like if you asked on an engineering list “how to build a really long bridge” and the answer was good news! we have this thing called catenary suspension! :wink:

(Incidentally, generally it’s a bit slow to “instantiate” prefabs etc in a video game. Often just use pools of objects and keep them inactive or offscreen. Eg Keeping track of items in a pool? - Unity Answers )