- Home /
How to properly use [ClientRPC] and [Command]?
I am currently making a multiplayer game. I am currently on the lobby, where I have stumbled upon a problem that I cannot solve. I have been searching for some kind of clearer explanation of [ClientRPC] and [Command], but I just can't seem to grab a hold of it.
Note: I am working on a local multiplayer game, I am not using the matchmaker
The problem is, I am currently working on the lobby, where the players can join, and upon, joining, the PlayerLobby will load a string and an image. It works fine, except, when a client connects to the lobby, it will load the same string and image as the server. I am currently at a loss on what to do, and I am unsure if my approach toward this multiplayer lobby is correct.
This is my current approach: upon conection to the lobby,
// if server, load data using ClientRpc
if(isServer) {
RpcLoadData ();
}
// if not the server (client), tell the server to load
else {
CmdLoadData ();
}
And this is the actual code of the Command and ClientRpc
[Command]
public void CmdLoadData() {
RpcLoadData ();
}
[ClientRpc]
public void RpcLoadData() {
BinaryFormatter bf = new BinaryFormatter();
FileStream playerFile = File.Open(Application.persistentDataPath + "/" + playerFileName, FileMode.Open);
playerData = (PlayerData)bf.Deserialize(playerFile);
monsterData = playerData.getCurrentMonster ();
OnMyPlayerName(playerData.getPlayerName ());
OnMyMonsterName(playerData.getCurrentMonster ().getMonsterName ());
OnMyPortrait(MonsterType.IMAGE[monsterData.getMonsterTypeID()]);
playerFile.Close();
}
Thanks for any help in advance!
Edit: I updated the code that I have posted, to have an accurate information of what I am actually doing.
Have you watched the $$anonymous$$erry Fragmas 2.0 live training session? I believe $$anonymous$$ike covers all of that in detail. Basically you have to disable almost all of the components on your prefabs and instantiate them locally ONLY upon joining, so that each local player has their own instance of a component.
Here is a link to the video (it's at the bottom of the page for some reason).
I hope that helps.
Thank you very much for that tutorial, it was very clear, and the [Command] and [ClientRpc] is explained very well.
As the tutorial mentioned, the player 1 shot player 2, so the client of player 1, will tell the server, that he shot player 2, then the server will tell every client that player 1 shot player 2.
Now in my case, let's assume we have two players, player 1 as the server, and player 2 as the client
Initially, player 1 will create the lobby, so, he needs to load his data. He will simply call the function RpcLoadData()
, because he is the server himself. But, when player 2 joins the lobby, since he is not the server, he needs to tell the server that he needs to load his own data as well, and to do that, the client will call CmdLoadData()
, which then calls RpcLoadData()
, in order for the server, to load the data of player 2.
$$anonymous$$y problem is, when the player 2 calls CmdLoadData()
, which calls RpcLoadData()
on the server, the data that will be loaded on the player 2 is the player 1's data. What I need is some way of making player 2 tell the server, like "hey I need to load $$anonymous$$Y data", which then loads player 2's data, and telling every player that player 2, loaded his data.
Thanks for any help in advance!
http://docs.unity3d.com/$$anonymous$$anual/UNet.html
Its all in the manual you know. You cant read it selectively though. Read the ENTIRE section from start to finish.
Answer by Salmjak · Feb 14, 2016 at 09:32 PM
[Command] runs the function on the server using data on the client. [ClientRpc] runs the function on all clients using data from the server. Atleast thats the basic idea I've got.
I think what you're doing doesn't work because when you run your RpcLoadData() the function is run at the server, and thus uses the server variables (which would be the same as Player 1). Just use an identical function but just make it a [Command] instead (tell the server to run this function, but with the data from the client) or pass all your local variables via the [Command] to the [ClientRpc] function.
Yes, that's the problem I have faced, and the solution I came up with (since I was using serialized data), was storing them in a variable, and passing it to the [Command] and [ClientRpc] functions.
Note that when you are doing this, there is a certain limitation on how big a variable you can send through the network, you should use a channel that can support the size of the data that you will pass.
Thank you very much for your help!
Answer by jordan787878 · Nov 21, 2016 at 06:52 AM
@nyaw Hey. I have the same problem with you. How do you solve it?
My case is that I have two players to shoot arrow. The arrow speed is depends on "Local Player" charge time. I wonder if I can send the localplayer data to server?
Your answer
![](https://koobas.hobune.stream/wayback/20220612063931im_/https://answers.unity.com/themes/thub/images/avi.jpg)