- Home /
How do you add Networked Multiplayer to a game while preserving single player?
I understand how to implement multiplayer. What I am not sure about is how I add it to my game wihtout butchering the single player mode.
All those extra network componenets and script modifications are getting in the way. Seems like the simplest way would be to make 2 games in one by using two sets of scripts and gameobjects but that feels wrong to me.
There must be a better way, how do you pros do it?
To give you an Idea, I am working on a simple game is based on pong. It currently has couch multiplayer implemented using multiple controlers and I have an AI for single player.
Thank you for reading!
Answer by tcz8 · Dec 01, 2016 at 05:15 PM
I did some testing and I think It's much faster to develop for network multiplayer all the way and simply enable an AI or second player object for local games. Actually got that running in no time. I kinda get why a lot of games are built that way now.
Here is what I did for the 2nd local player:
Added the player prefab as an object in the hiearchy, renamed it Player2 and disabled it. Do not remove its network components
Duplicated the player controller script, renamed it and replaced the script on the Player2 obj.
Modified the script to work localy by removing all the isLocalPlayer checks
Modified the script to use different inputs than the player prefab
Added code to my Game Manager script that enables the Player2 object when localGame = true (it's a custom var, I set it to true when launching the game in local mode)
With a little extra modifications you could even have the 2 local players join a network match!
I will do something similar for the AI player. This setup has the advantage of everything else working as is without modifications.
All is left to do is to launch the local network game via script instead of using the network hud, effectively hiding that it's running a local server in the background. I remember reading how its done in the manual.
The proxy solution would work too, modifying the player controller script to work with another gameobject instead of the object its attached too is easy but that's were the simplicity ends.
It doesn't take care of all the network components and scripts that uses NetworkBehaviour instead of MonoBehaviour. A lot of gamobjects would need to be duplicated and modified. It's almost like building two games.
The proxy concept would be excellent when you want network users to control player objects allready in the scene instead of having the network manager spawn them. You could set the Network Manager to spawn empty prefabs with a controller script attached that finds an unused player object in the scene and start controlling it via a gameobject variable.
Hope this answer can help others.
@christoph_r Thank you for getting my brain thinking! Ill upvote you. If you dont agree with my choice of answer please share your thoughts.
EDIT
So I ended up being able to merge all the player controller scripts into one, makes it much easier to maintain things.
@christoph_r 's suggestion of a proxy control scheme is a very good idea, I will definitly use it for vehicules or other controllable objects in the future. There may even be a use for player controls depending on the type of game.
As for starting the game in local mode while being coded as a networked game, all you need to do is put this into a script in your scene and make sure isLocalGame is set to true. Dont forget to put using UnityEngine.Networking; at the top of the script.
void Start () {
if (isLocalGame) {
NetworkManager.singleton.StartHost(); // Starts the game in local host mode
}
}
I'd be a bit tentative to declare what worked best for you to be the general answer to such a broad question. For example, by having two scripts that do very similar / the same things but with different input scales very badly. While this might not be a big issue with small projects you're working on by yourself, this is a huge disadvantage in larger projects. While the setup of the scene may be a bit more complex when separating these two, code maintenance is much, much easier.
Actually, after prototyping the solution with a duplicate player controller script I merged the modifications and now use only one script.
I think I understand what you mean, it allows changing the control scheme easily depending on what you are controlling. I guess for games with vehicules or other controllable objects it's the way to go.
The question was "how to add network multi and preserve singleplayer" and your answer only deals with controls that's why I chose my answer.
Answer by Yay_For_Humzah · Dec 02, 2016 at 06:20 PM
I agree and don't really agree with @christoph_r. Yes there should be different inputs, no...it shouldn't be different scripts. You should basically have an if else statement in your update that chooses what input you have. Then have functions in those if statements. So if (you are using network){//Control with network}, etc.
Answer by christoph_r · Nov 30, 2016 at 10:25 PM
Consider which aspects of your game may be driven/affected by other players. Make sure to create interfaces for those aspects that allow you to easily switch between having AI/other scripts or in fact other players control them. In the example of a pong game, your controller for the racket should take in a very generic input (such as a float for going up or down). Then you can create multiple scripts that drive that controller, one that takes input from a local user's keyboard, one that is AI and one that is driven by a remote player.
So If I understand this right, I need to set the paddle control script to be a kind of "proxy" and use a different script in multiplayer and singleplayer to take control via that proxy.
That makes sense, but what about the whole network manager that wants to instance player prefabs, the network transforms, the network identity and all other network components that require to be on different game objects?
I remember seeing games that in singleplayer were actually running in multiplayer in the background but on a local server with AI. They were simply disabling match making. Is that possible with Unity and should I even go that route?
Yes, that's basically it. As for setting up a system running on a local server: Consider what works better for your individual project. With a relatively simple game like pong swapping out the scripts seems like the quicker and easier option. Your game's focus should also be an important factor, if single player mode is more of a gimmick for when the connection is out, doing it via local server would probably make debugging and testing easier. Either way, abstracting game logic from input, be it local user input, AI or remote input is generally desirable, no matter which path you take.