I need help. I have a gameobject with two scripts in a client server setting that’s correctly spawning the level and the clients (took the scripts almost straight out the official tutorial).
One of the scripts in the client needs to set and get variables from the server.
Well, I’m becoming stupid trying to figure out why the fuck this doesn’t work as intended.
I’m stuck to the point that my client needs a single variable value from the server, but there’s no way to get it.
Is it a timing issue? How am I supposed to pass a fucking variable from the client to the server, and viceversa?
I feel like I’m the only retard who ever faced this problem such is the difficulty to find an answer to this after two days of (possibly bad) research and study.
Here’s the code
private int variable = 0;
void OnNetworkLoadedLevel () {
if (Network.isServer) {
print("As a server");
variable = returnvariable();
}
else {
print("As a client");
networkView.RPC("returnvariableRPC",RPCMode.Server, Network.player);
}
print ("variable doesn't hold the value it should");
}
private int returnvariable() {
do_stuff();
}
[RPC]
public void returnvariableRPC(NetworkPlayer player) {
int localvariable = do_stuff();
networkView.RPC("assignvariableRPC",player,localvariable);
}
[RPC]
public void assignvariableRPC(int parameter) {
variable = parameter;
}
The logic step if something doesn’t work would be debugging, which is quite easy with RPC’s.
You can add some debug strings in the functions and you can turn the network debugging on for the project in the editor.
Also you might want to leave out the f* words from future posts, it turns people off.
I correctly get into the onnetworkloadedlevel function. Up until there it’s part of the official networking tutorial so it’s working correctly
The tutorial however very stupidly misses to address variable passing. Each RPC instantiation and interaction is parameter-less. I can’t believe that I’m wasting two fucking days after this issue, which should be so idiotically basic.
As per debugging, thanks for the suggestion, but the debugger simply shows that as a client the function call is performed correctly, but my ‘variable’ value remains unchanged after both the call and call-back.
I’m suspecting a timing issue, but how should I know? It’s not documented anywhere.
It is my conclusion that RPC calls are asynchronous, and that the client script gets focus immediately after issuing them, and without waiting for their completion, but without confirmation from someone with experience…
I was just hoping that I was not the first poor fucker that faced this problem for the stupidest network - server need that ever existed: passing a fucking variable between one and the other.
passing variables between client and server is very simple, and by the looks of it, your rpcs should work correctly. I have a feeling that you have an error elsewhere related to generating your value that you’re attempting to send to the client, which, as you say, could be a ‘timing issue’. Are you watching your debugs and seeing if the server makes the value before it receives a client request? Why don’t you just store the value on the server and then send that to a client when they request it?
The simplest thing to do so that you know if your rpcs are working correctly:
void OnConnectedToServer() //this is a monobehaviour function, and is run upon a client connecting to a server
{
Debug.Log("I am a client, I connected to the server");
networkView.RPC("RequestValue", RPCMode.Server);
}
[RPC]
void RequestValue(NetworkMessageInfo info) //networkmessageinfo is always sent with every rpc, and is always the last parameter, but is optional
{
var someVal = 3;
Debug.Log("I am a server. I just got a request from a client")
networkView.RPC("SendValue", info.sender, someVal);
}
[RPC]
void SendValue(int receiveValue)
{
Debug.Log("I am a client. I just got a value from the server. That value is " + receiveValue);
}
I’ve debugged the fuck outta the issue (after implementing a gui log thingie that should never have been needed) and can confirm that networkView.RPC is asynchronous. It will immediately return control to the caller, and the call-back trick to receive a value is just FUNDAMENTAL if you want to exchange variable values to and from the server (I initially thought that, since you have a call back to the client script, it would not yield, but it does).
So this raises another question: how do you ‘stop’ your script until RPC finishes execution?
I’ve looked at the ‘waitforseconds’ instruction, but I haven’t found a way to call it without the yield command.
How the fuck is one supposed to know when the RPC has completed its routine call?
what do you mean ‘completed its routine call’? Rpc’s are instant, of course, because it only is a send. It doesn’t ‘return’ when it’s been run on the receiver, that’d just be plain weird, considering it’d be additional overhead.
You have to think of this as a message queuing system, not as an actual method call. Did you look at the code I posted? that’s how you get a value from the server.
If you want to stop your script so it’s not executing until it gets the value, you COULD just disable the script, as this only stops frame-based monobehaviour functions (update, fixedupdate, lateupdate), but does not affect things like RPC’s, Sendmessage, etc. Once you receive the value, just re-enable the script. You cannot, however stop in the middle of a function. That’s just bad design. I suggest you write your code that you want to continue on in the function that gets called once you receive the value.