- Home /
[PhotonUnityNetwork] Synchronize colors among players.
Hi! Im trying to make a simple scene, where i can spawn up to 6 players, each with different color, but colors cannot repeat themeselves and look the same on different clients.
(RPV -> RoomPhotonView) The idea was to:
In UI:
void OnJoinedRoom(){
GameLogics.SetActive(true);
int id1 = PhotonNetwork.AllocateViewID();
PhotonView photonView = this.GetComponent<PhotonView>();
player = new PhotonPlayer(true, Random.Range(0, 1000), "Player" + Random.Range(0, 1000));
if (!PhotonNetwork.isMasterClient)
RPV.RPC("RequestColor", PhotonTargets.MasterClient, player);
RPV.RPC("SpawnOnNetwork", PhotonTargets.AllBuffered, transform.position, transform.rotation, id1, player);
Menu.SetActive(false);
}
On ServerSide:
[RPC]
void RequestColor(PhotonPlayer pp)
{
Debug.Log("hehe");
RPV.RPC("SetColor",pp,isColorTaken);
for (int i = 0; i < isColorTaken.Length; i++)
Debug.Log(isColorTaken[i]);
}
[RPC]
void SetColor(bool[] arr)
{
isColorTaken = arr;
}
[RPC]
void SpawnOnNetwork(Vector3 pos, Quaternion rot, int id1, PhotonPlayer np)
{
Transform newPlayer = Instantiate(playerPrefab, pos, rot) as Transform;
PhotonView[] nViews = newPlayer.GetComponentsInChildren<PhotonView>();
nViews[0].viewID = id1;
newPlayer.GetComponentInChildren<MeshRenderer>().material.color = randomNotTakenColor();
}
Color randomNotTakenColor(){
int r = Random.Range(0, 5);
if (!isColorTaken[r])
{
isColorTaken[r] = true;
return colorArray[r];
}
else
return randomNotTakenColor();
}
I know that in this sample we get problems when someone connects then disconnects due to not 'falseing' isColorTaken of his color, but for now I just want to make it work in any way.
I'm sure the solution is really easy, but im afraid i got some kind of mindblock.
Thank you.
I made it to synchronize colors on each client, but still i got some problems with making each color unique. Shall i pass something like 'RandomUnusedColor' via RPC from masterClient? is this idea any good?
Answer by Navigatron · Dec 26, 2014 at 11:27 PM
After thinking about this for a couple of minutes, I have had an idea. Photon instantiates all other players on your client as soon as you join a room, And I believe it does it in order. Therefore, we don't need any network calls to solve this.
On any script in the game, throw in this code:
private static int colorIndex = -1;
public static int ColorIndex{
get{
colorIndex+=1;
if(colorIndex>=colorsDefined){colorIndex=0;}//where colorsDefined is the number of defined Colors
return experience;
}
}
That provides an int that can be accessed by anything in the scene, and increments itself whenever retrieved.
Finally, On your player Object:
public Color[] colors; //Public so colors can be assigned in the Inspector.
void Awake(){//As soon as the GameObject is Instantiated
renderer.material.color = colors[OtherClass.ColorIndex];
}
Where OtherClass is whatever other class you threw the other code into. If you wait a tad before instantiating the local player, (Put Photon.Instantiate into the Start rather than Awake functions), then All other players should instantiate on your client and grab their colors in the correct order. Woohoo!
Unfortunately, this also does not help when a Player leaves the room. In order to include that feature, I would assign each players color index to their custom properties. Then you can find their color index when they leave, and use a more complicated system of boolean arrays to determine if an index is available.
On Photon Player Disconnected:
A final thought: If the players cannot change their color in-game, then do they really need to be synchronized? If not, then the above code should work perfectly.
Best of Luck, ~Navi
I know this post is super old, but thank you! This was very helpful.
Old post but I I don't get the "return experience;" What variable do I want to use instead of experience if I m just changing the multi player character color.
Also as the first bit can be "On any script in the game" could it go on the second script?
Updated with new render call as the old method is depreciated.
using UnityEngine;
public class ColorIndexPicker : $$anonymous$$onoBehaviour
{
Renderer ObjectRender;
public Color[] colors; //Public so colors can be assigned in the Inspector.
void Awake()
{//As soon as the GameObject is Instantiated
ObjectRender = GetComponent<Renderer>();
ObjectRender.material.color = colors[ColorIndex];
}
private static int colorIndex = -1;
public static int ColorIndex
{
get
{
colorIndex += 1;
if (colorIndex >= 6) { colorIndex = 0; }//where colorsDefined is the number of defined Colors
return What?;
}
}
}
Your answer
Follow this Question
Related Questions
Unity networking tutorial? 6 Answers
Client can't spawn GameObject's 0 Answers
[Command] Attribute Returning Warnings and Errors 0 Answers
Unity3d Csharp Networking Error 3 Answers
How To Deal With Lingering Prefabs in Multiplayer Scene ? 0 Answers