- Home /
Sending int value owned by Masterclient to other client
My game has 2 scenes named "menu" and "game". There is an int value that players can change in the menu. (this value is 1-2 or 3). The room is set up, the players join the room, and when the players are ready, masterclient start the game and the "game" scene is loaded. What I want in this part: The int value belonging to the masterclient is initially taken, this value is sent to all other players, and the int value of the other players equals the int value of the masterclient. I tried doing this with rpc, I don't get any errors but the values are not synchronized. Anyone know why?
public class xcontrol : MonoBehaviourPunCallbacks {
private int x;
public GameObject c1,c2,c3;
[PunRPC]
private void xkaç(int x)
{
if (PhotonNetwork.IsMasterClient)
{
x= PlayerPrefs.GetInt("xset");
Debug.Log(x);
PlayerPrefs.SetInt("xset", x);
}
}
void Start()
{
photonView.RPC("xkaç", RpcTarget.OthersBuffered, x);
xkaç(x);
if (x == 1)
{
c1.SetActive(true);
c2.SetActive(false);
c3.SetActive(false);
}
if (x == 2)
{
c1.SetActive(false);
c2.SetActive(true);
c3.SetActive(false);
}
if (x== 3)
{
c1.SetActive(false);
c2.SetActive(false);
c3.SetActive(true);
}
}
}
Answer by Captain_Pineapple · Apr 07 at 06:39 AM
Yes.
your function xkaç
might be called on all clients but it does nothing with the value you receive. Only the master client will save it to the playerprefs. All other players do nothing at all.
May i propose some changes to your code - please DON'T blindly copy it, understand it and then use it if you deem it good:
public class xcontrol : MonoBehaviourPunCallbacks {
private int x;
public GameObject[] cObjects; //assign former c1,c2,c3 in order to this array
[PunRPC]
private void xkaç(int receivedX)
{
Debug.Log($"Setting new value for x: {receivedX}");
x = receivedX;
if (!PhotonNetwork.IsMasterClient)
{
//could set x for all non-master clients here:
//PlayerPrefs.SetInt("xset", receivedX);
}
setCObjectsActiveState();
}
void Start()
{
if (PhotonNetwork.IsMasterClient)
{
// give x as second argument here to return it as default if "xset" is not present as key:
x = PlayerPrefs.GetInt("xset", x);
photonView.RPC("xkaç", RpcTarget.OthersBuffered, x);
xkaç(x);
}
}
private void setCObjectsActiveState()
{
for(int i=0;i<cObjects.Length;i++)
{
cObjects[i].SetActive(i==x);
}
}
}
Also as a sidenote: you should work on your variable names. Variables, functions and classes must always describe what they are doing. This helps you and others to understand the code. e.g. c1
, c2
... or x
and xcontrol
are bad names. same for xkaç
Also i changed c1, c2 and c3 to be a list instead. this helps to keep your code maintainable as you can now simply add more objects by adding just one element to the array and you don't have to change any code for it to still work.
EDIT: For clean complete solution added the IsMasterClient
check in Start as this was indeed missing.
Thank you for your suggestions and edits. If I remove this, I can't access the x value : x = PlayerPrefs.GetInt("xset")
thanks to debug.log i see x is always 0. And I only see x value in masterclient's console, For other clients debug.log is invalid. Result: each player gets his own x value. I still can't equate x value to masterclient's x value
Hey, i updated the answer with some "Lit" changes. This should now work as intended as everything in Start
should only be executed on the masterclient, this is now the case. Let me know if something is unclear.
Thank you very much, it works fine with its updated version
Answer by GetLitGames · Apr 07 at 01:00 PM
You only want the Master client to send the RPC with the x value to the other clients. Move "if (PhotonNetwork.IsMasterClient)" down to the line above "photo view.RPC" so only Master client sends it. Then all you need inside "xkaç(int" function is this.x = x; and setCObjectsActiveState();.. So, your master sends it's x value to all the other clients and they set their this.x to be that value and call setCObjectsActiveState() but it might be slightly better if that function took a parameter instead of using this.x do setCObjectsActiveState(x)
Hey man,
this is a funny one indeed. Not sure what your understanding of up/downvoting is... Please leave a comment and explain what is wrong about an answer when you downvote something.
This will help people a lot.
Either way, as your answer is a extension to the code i posted it might be helpful to note that with your answer. Your addition here is indeed a good idea.
I think he downvoted your answer because, you downvoted his answer on this thread... but again this is just purely assumption.
I'll upvote to make it neutral until @Omerduru checks out the answer or @GetLitGames replies why he think your answer is wrong :)
The fact that you gave someone new code, that they will not understand, and you asked them not to just copy/paste but to understand it shows that you already knew you did something wrong. The fact you put things in bold like they are orders is also pretty ridiculous.
Your answer was completely wrong. The root of the problem is that only the MasterClient should send the RPC with the value and your code wasn't even correct in any way, shape, or form. Furthermore adding the array was pointless and increases code complexity, you don't even know if he needs more than 3 objects.
It was instant karma that you downvoted my correct answer (that in your opinion had some kind of misleading part to it) and I happened to look into what kind of other answers you give only to find an atrocious answer like this.
Nice of you to imply that @Omerduru is not smart enough to understand the code changes - i want to make sure that people do this as this is imo the crucial part of a learning experience. I take things in bold as emphasis on information, not as orders but whatever. Especially since when does an order begin with a please?
2. Man in my last comment i even chose to give you credit for givin good and correct input but ok if you want to s%&! all over it here we go again: No, the original version of xkac
did nothing but print x. Simply changing the remote execution to only master client would not (emphasis - not an order) have solved the issue of x not being changed on the non-master clients. Only the combined changes of your version and mine will fix all issues in here.
I am also not really sure if you are aware of the definition of code complexity. Yes an array is more "complex" in a way but 3 if statements with bad maintainabilty are not better in any way.
3. I feel sorry for you if a downvote in some forum means that much to you personally that you are like: "Man this guy downvoted my answer. Instead of considering that half of my answer is indeed incorrect and standing by some mistake i made i'll go and downvote some answer of them! That'll show them!".
Idk, if that is a profilepic of you then telling you to grow up wont help here i guess.
Say whatever you like, i will not continue this discussion any further.
[PunRPC]
private void xkaç(int x)
{
this.x=x;
// x= PlayerPrefs.GetInt("xset);
setCObjectsActiveState(x);
}
void Start()
{ if (PhotonNetwork.IsMasterClient)
photonView.RPC("xkaç", RpcTarget.OthersBuffered, x);
xkaç(x);
}
private void setCObjectsActiveState(int x)
{
for(int i=0;i<cObjects.Length;i++)
{
cObjects[i].SetActive(i==x);
}
}
If I don't use this, the x value shows up as 0 every time. x = PlayerPrefs.GetInt("xset")
I couldn't understand why I shouldn't use this. Isn't this how I need to get the int value that the players save in the "menu" scene? But the result is still the same unfortunately. Result: each player gets his own x value. I still can't sync x to masterclient's x.
You were almost there, remember the MasterClient is telling the other clients what value to use. So you need one more line added like shown below to read the value from PlayerPrefs and send that value to the other clients. The other clients will receive the value in your xkaç RPC function call, and you can do whatever you need to there. Hopefully you have a little better understanding now - have you MasterClient issue RPCs to the other clients to give them values or ask them to do something. To improve your code you may want to remove "x" class field, since it is better habit to use function parameters and pass things around rather than using "global" fields/variables.
void Start()
{
if (PhotonNetwork.IsMasterClient)
{
var masterValue = PlayerPrefs.GetInt("xset");
photonView.RPC("xkaç", RpcTarget.OthersBuffered, masterValue);
xkaç(masterValue);
}
a "class member field" is a variable you declared at the class scope: private int x;