Hello all
We’ve been putting together a new doc for getting started with unity multiplayer. We hope this better helps everyone but we want to hear from you if this was indeed helpful. Please check out the doc linked here and let us know what you think. We ask that you look past the current formatting, placeholder screenshots, misspellings, bad grammar, etc. This is a rough first draft to see if we are going about this the right way for you guys and actually making it easier to get started with Unity Multiplayer.
While I worked all that out myself, I can see how much of a massive, massive time saver it would have been to have a digestible doc that just says how it is, so that would have helped me a great deal - certainly more helpful than trying to pick part demos which all have different styles and no real overview of explaining why decisions were made (fairly important to explain why given the number of multiple ways to skin this fish).
The doc needs work for formatting but I think you know that already. Please keep it up for tackling different areas of networking!
EDIT: Note that this version is to be included for those developers who wanted to just “scan” or “give a glance” to find relevant information/references without needing to read the entire doc. Please understand.
Can you also add an ELI5 condensed version of the code (given below) to that doc, like an Appendix or, SSCCE version?
using UnityEngine.Networking;
public class CustomScript : NetworkBehaviour {
[ServerCallback]
public void ServerStuff(GameObject newObject, Vector3 newObjectPosition){
//Do server-side stuff. Initializing all game stuffs can be used here. Syncing objects can also be used here.
//Let's pretend "newObject" has NetworkTransform attached.
newObject.transform.position = newObjectPosition;
//Now newObject's NetworkTransform will sync the new position across all connected clients. The values are updated on the server
//side, all clients will have their old positions marked as Dirty() and will update to the server's values.
}
[ClientCallback]
public void ClientStuff(){
//Do client-side stuff.
//Client may have this registered prefab from the Network Manager, but usually it's better to have it available in the Hierarchy before continuing. Usually, it's assigned directly through the Inspector, but let's go with this.
GameObject prefabObject = GameObject.FindGameObjectWithTag("SamplePrefab");
if (prefabObject != null){
//Always check for null. In UNET, there may be times where the object is not spawned through NetworkServer, thus the object will be missing.
CmdDoAction(prefabObject);
}
}
[Command]
public void CmdDoAction(GameObject objectToUse){
//This is where you would do stuffs that the client wants the server to do.
GameObject obj = Instantiate<GameObject>(objectToUse);
NetworkServer.SpawnWithClientAuthority(obj, this.connectionToClient);
//Or just have the server do something for the client.
obj = Instantiate<GameObject>(objectToUse);
NetworkServer.Spawn(obj);
ServerStuff(obj, new Vector3(0f, 10f, 0f));
//Once the server has done whatever it needs to do, you can choose if you want to have all clients do other actions.
RpcDoAction();
}
[ClientRpc]
public void RpcDoAction(){
//Do broadcasting stuffs. Stuffs where all clients (local clients = LAN host, and remote clients = LAN clients) will do.
//Because there exists a game object with client authority (meaning the game object's NetworkIdentity has "Local Player Authority" property
//enabled), it means it's better to check for NetworkBehaviour.hasAuthority, rather than NetworkBehaviour.isLocalPlayer.
if (!this.hasAuthority){
//Clients with no authority do stuffs here.
//Or if you want, you can do something that all other clients without authority of this game object can do.
Ping(new Vector3(0f, 10f, 0f), Color.red);
}
else {
//Do something in which the client itself has control over the game object of local authority.
//Then do whatever you need to do that tells the player the unit has spawned, and all other enemies have taken notice of it.
Ping(new Vector3(0f, 10f, 0f), Color.green);
}
return;
}
public void Ping(Vector3 position, Color color){
//Pretend this is a function which pings a colored ! symbol on a minimap.
}
public void Update(){
//Because this is a custom NetworkBehaviour script, this is attached to a game object that the client may use.
if (Input.GetMouseButtonUp(0)){
//When something occurred...
ClientStuff();
}
}
}
I have some scripts I’ve been working on for my game here.
I built it for the new UI, if you know a bit about coding and linking buttons with functions you can have a look here.
Codes!
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class NetworkHelper : MonoBehaviour {
public NetworkManager manager;
public void StartHost()
{
manager.StartHost();
}
public void StartClient()
{
manager.StartClient();
}
public void StartServer()
{
manager.StartServer();
}
public void Stop()
{
manager.StopHost();
}
}
^SInce the functions are public you can directly tie them to button functions. Easy!
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class NetworkPanel : MonoBehaviour {
[Tooltip("The main NetworkManager you have in your scene")]
public NetworkManager manager;
[Tooltip("The panel the player sees before they are in-game")]
public GameObject startPanel;
[Tooltip("The panel the player sees whilst in the game (usually a stop button and some information)")]
public GameObject inGamePanel;
void Update()
{
if (!NetworkClient.active && !NetworkServer.active && manager.matchMaker == null)
{
startPanel.SetActive(true);
inGamePanel.SetActive(false);
}
if (NetworkServer.active || NetworkClient.active)
{
startPanel.SetActive(false);
inGamePanel.SetActive(true);
}
}
}
^Another script I made for you to enable and disable UI panels, so it isn’t as cluttered!
If you like these it would be awesome if I can get some feedback on them. I’m a student learning coding for a hobby and potential career.
I did this tutorial this morning. Itd very good. Nice job. The only thing that needs rework is the last page. I could not find the package to import for your lobby. Still the people at photon have much better tutorials, but this is one of the better tutorials I have seen from unity. I hate tutorials where they just give you the code and your left to reverse engineer it.
Thanks for this.
Looking forward to the lobby updates.
Secondly, a lot of the example on the web, including this one are for FPS, but what if I’m writing a board game where each player (and there can be more than 2), gets a turn to select their own pawns and select which tile they should move to.
Not sure if a concept like that could be touched upon in the docs.
I’m guessing that the pawns should be created on the server only and spawned, then hit detection made from the client, but acknowledged on the server.
Hence, the pawns should have a network identity and network transport component.
Anyway, Thanks again, and eagerly awaiting the updates
I’m not completely sure I know what you are asking. But I think the answer is from the editor. Maybe this can better explain it. The cube shooting game, if you could finish that off by doing step by step lobby and Match Making, that would be awesome. And include how to create a matchmaking project Id.
Yes, that was the intention. The end of the doc should be thought of as placeholder for this content. We wanted to get a rough draft out sooner to get your feedback in order to make that last bit more to your liking. A new version will be available as soon as we can.
Before I start asking a ton of questions over the course of this thread, let me say THANK YOU for making this.
Okay, got a bunch of questions on this subject and a lot of it is really because much of uNet doesn’t answer the “why” questions.
Some understanding/explanation of the NetworkTransform bits would be very useful including why one would want to use it. Many of the other tutorials out there pretty much ignore the NetworkTransform because its not clear what all the bits and switches are and subsequently just implement a series of SyncVar to sync transform state around. Similarly within the documentation, it suggests doing things like setting the sendInterval to 0 (for bullets) and using SetDirtyBits() to cause the updates to be sent. Why would I choose one over the other?
Why would I set the snapThreshold and what are some good values for it?
Good stuff, thank you guys. Although it will be a starter guide it would be good to see a matchmaking setup that includes a custom UI demonstrating a few overrides, as I imagine that will be the direction most will be heading.
I’m currently picking apart the uNet asset on the asset store that comes with pong as a demo.
It’s kinda hard to pick apart because there’s several areas / scripts that hard wire it to 2 players only. As soon as you want more than 2 players it’s a lot of work to make sense of where things are going wrong (using a byte value for player numbers was a bit inflexible to put it mildly)
So a comprehensive doc is very very much appreciated!