I’m trying to put together a multiplayer game, but the characters are different and I need the network to somehow acknowledge that. One client is suppose to have a fighter, another a ranger, and another a mage. However, I’m not sure how to make it display which of these characters is connected to a certain network because I don’t know how to get a particular field from a particular client’s script over a network.
public class RoomView : MonoBehaviour
{
string currentRoom;
string charClass; //This is the member I want the script to see from other scripts of the same type over a network
// Use this for initialization
void Start()
{
}
void Update()
{
//Get current game name
currentRoom = GameObject.Find("Content").GetComponent<HostList>().getCurrentRoom();
//Constantly update anything with that name
if (currentRoom != null)
{
MasterServer.RequestHostList("The Road to Hell");
}
}
void OnMasterServerEvent(MasterServerEvent msEvent)
{
if (msEvent == MasterServerEvent.HostListReceived)
{
foreach(HostData room in MasterServer.PollHostList())
{
if (room.gameName == currentRoom)
{
/*
Here I want it to cycle through all the clients connected to the host and, based on the "charClass"
member of each script they have, display what kinds of classes are connected to the host. I wanted
to try and do that through the HostData, but there's no function in it that gives me specific data
about clients. It just tells me how many clients are connected.
*/
}
}
}
}
}
I heard a few things about using a NetworkBehavior instead of a MonoBehavior and something about a NetworkView, but I’m not sure where to start learning about how to use these things.
Simple example, made by Unity with step by step info: Unity Learn
I would suggest you start there, if you’re already comfortable with Unity & scripting.
If not, I’d suggest you start much simpler and not a networked game for your first go.
To give a general answer that I think might fit your question, I’d say that the server should know what type of player everyone is , and can in turn notify players as to who’s who.
You said you weren’t sure where to start learning, but posting you some resources about networking isn’t what you’d call helpful for that? I have no idea how to equate such a comment.
These don’t show me how to tell clients apart form each other. You gave me Unity docs that I have to have some idea of where I’m suppose to look to understand and a tutorial that, as far as I can tell, only works if the multiplayer is LAN based which is neither what I want nor is what the tutorial I WAS following was instructing me to make.
The docs and tutorial are a jumping off point for learning the entire UNet networking system. There’s several steps you need to take first before you can even get to the point of sending data to clients with UNet. Its all covered in the documentation and tutorials.
As to your specific question, after you do all the setup steps to get UNet working, you could do something like this on a networkbehavior on your player object. Note that there are many ways you could accomplish a similar result, this is just one.
[SyncVar]
public int CharacterType; //Have each character type be referred to by a different number
void Start()
{
if (isServer)
{
CharacterType = 3; //Change this to whatever mechanism you want for the server to initially set the type of character
}
}
//Use this command from the client that this Player object is associated with to set the type of character on the server, which will then propagate to all clients
//(if you want the client to determine what type of character it is)
[Command]
void CmdSetCharacterTypeFromClient(int newType)
{
CharacterType = newType;
}
The previously linked documentation explains the details of what all the above means.
That just looks like you’re setting the information. I want the client to be able to GET the information from the server so it knows what to display. The tutorial he posted kinda explains what a SyncVar is, but it does nothing to explain what that Command thing is.
Setting a SyncVar on the server sends it to the corresponding script on the same GameObject on all clients. SyncVar’s (and ClientRpc’s) only go from server to client, so to send information from client to server you use a Command. It would be easier if you just read the documentation that covers this. @CubicCBridger posted the direct link to the page that covers Commands. SyncVars are covered here:
Alternatively you can use UNet Messages, which just send a message of almost whatever you want from server to a specific client, or from client to the server, but getting them up and running will require significantly more reading and trial and error than SyncVars and Commands, so I’d suggest you start with those.
I’d really recommend reading the entire HLAPI section in the docs before really diving into this. The top page for that is here, and then continue reading the pages further down the tree:
Ok, so if a game object exists on the server as well as on someone’s client then I should be able to find it and get the script component of the one on the server, right? But no one is telling me how to do that.
Why would you be able to get the one that’s on the server?
I think you’re fundamentally not understanding how networked games are working.
There are GameObject’s on the client, and copies of them on the server. You don’t get the component on the GameObject on the Server while you’re on the client. Instead you get the client object, which is sync’d with the server.
You use the various UNet tools to do this syncing.
…
Read the documentation. You appear to have dived into the deep end and are getting lost real fast. Come back to the shallow end, start from the beginning, and build up your understanding of these concepts.
Ok, then how do I get it someone else’s client object? You keep showing me documentation, but if I understood it then I wouldn’t be here in the first place.
On a single client you can only get objects and components on that client. There is no way to get components and objects on another client or on the server. The only GameObjects that a client can ever directly access are GameObjects on that client.
You instantiate GameObjects and then spawn them on the server, which automatically instantiates copies of them on all connected clients. The server can then keep all client copies of these GameObjects in sync using tools like ClientRpc and SyncVars. So all clients will have copies of all the same GameObjects as the server, all up to date with what the server has. If you don’t use these tools then information will not be synced.
To send information from a Client to the server, you run a Command on the client, which actually executes on the server instead of the client. To do so that client either needs to have authority over that GameObject (can’t send a command to a server version of a GameObject if the server or another client has authority over it), or it needs to be that client’s Player GameObject.
To send information from one client to another client, since the two clients aren’t directly connected you have to bounce that information off the server. To do so you can send a Command to the server, and then have the server send a ClientRpc, a TargetRpc if you only want to send to a specific client, or a SyncVar.
Clients can receive ClientRpc’s and SyncVar updates on any networked GameObjects. Since a client can only send Commands on its Player GameObject or on objects it has authority over, a logical place to locate most or all of your Commands is on scripts attached to the Player object, even for tasks related to other GameObjects.