Best practice in multiplayer to handle an object that many players can take turns controlling

Hi everyone

I ave a multiplayer game that is moving along nicely but Ive hit a snag on how to implement one part of it.

I have several turrets in game that many players can use. They are originally owned by the host but they can be controlled by other players. My experience so far is that objects are syncd to the position the owner of the object “decides”.

So is the best way to go from here is to change ownership of the turret to the interacting player as soon as they try use it so that everyone else will now receive updates from that player? This will then repeat once the player leaves the turret and a different one tries to use it and they become the owner.

If this is the way to go, is the best way to do it just doing an RPC to everyone else passing the new owner ID or send your own ID to the owner who then updates it for everyone. This is a non-authoritative setup btw.

Any other options are appreciated! thanks!

Im using Photon Network if its relevant at all.

Ok… here we go (the short version):
Please excuse some miss-wordings :wink:

My method for multiplayer in Unity using the built-in multiplayer capability centres around one single system that expands out to sub-systems. Generally I would have one script/Object, generally called “NetworkManager”, which as it’s name dictates, manages the network. I like to leave the least amount of work for the Unity Networking, so that I have full control over what happens and what can’t. This NetworkManager tis basically a controller. It has a lot of features and does a whole lot of stuff, but by itself it does nothing.
It needs subsystems to take control over what it does, namely a client and server scripts. One of the main reasons for splitting up the server and the client, is because that allows for complete control over what one instance of the game actually does. We could only have a server and no client, we could have both or we could just have a client. It’s faster and normally easier to work with.
These two subsystems use the NetworkManager to act as either an authoritative server or a game client. These two systems should be completely independent of each other and neither should use NetworkView functions directly because of conflicts in functionality depending on the situation. For instance you can’t send an RPC to yourself unless you use RPCMode.All.
Now with these 3 high level systems, we can build more sub-systems or integrated systems, such as the player itself. No matter if you build a sub-systems, meaning that it’s more generalised, such as the implementation of MonoBehaviour (slower, harder but easier later on) or if you integrate it, meaning it’s tightly bound to the client-server scripts with very specific events etc (faster, easier but more code and only works for one sub-system), either of these methods allow you to create fully functional multiplayer objects for any feature you want.

Within this system, lets say you have an object with an owner “component” (attribute). Using your game logic, you can then determine the current owner of that object on the server. When that is evaluated to a new owner, this new information is sent to every client. The only reason the clients even need to know this, is because they can then perform prediction if they are the owner of that object, allowing for smoother movement on the owners side only. Depending on what the meaning of ownership of the object means, the object is then updated (on change) to all clients, including owner. Everything non-visual is evaluated on the server only. If the object can damage players, then that is only done on the server. The server has therefore full control over literally… everything. This means that unless a player either is the server or has access to it, the system is un-hackable.
You might be able to give yourself infinite ammo… but on the server it will still run out and no bullets will be fired anywhere but on your side.

That is how I would do it. It’s a quick explanation and I don’t go into much depth, but it should give you enough of an idea as to other methods you can use :slight_smile:
On that note, I have implemented this exact system in another project (Thats why I can write it out like this). It takes a lot of time, planning and knowledge to finish off and make it work, but it is so worth it :wink:

Hope this helps,