I have solved it using photon custom properties. When I am changing the color of a target using raycasting, I am storing its photonViewId and color value in a Hashtable. Late-joining players use this Hashtable in OnJoinedRoom() callback to synchronize all changes in that room.
Here is my sample code:
step 01: while creating a new room, initialize the room’s custom properties
private void CreateNewRoom()
{
int randomRoomNumber = 100;
RoomOptions roomOptions =
new RoomOptions()
{
IsVisible = true,
IsOpen = true,
MaxPlayers = 5,
};
Hashtable roomHT = new Hashtable();
string photonViewid = "0";
roomHT.Add(photonViewid, new Vector3(0, 0, 0)); // key should be a string
roomOptions.CustomRoomProperties = roomHT;
PhotonNetwork.CreateRoom("RoomName_" + randomRoomNumber, roomOptions);
}
step02: store target’s photonViewId and color value in the hashtable during rpc
[PunRPC]
void ShootRPC()
{
particalSys.Play();
Ray ray = new Ray(gunTransform.position, gunTransform.forward);
LayerMask mask = LayerMask.GetMask("targets");
if (Physics.Raycast(ray, out RaycastHit hit, 100f, mask))
{
raycastGO = hit.collider.gameObject;
var enemyHealth = gameManager.GetComponent<ScoreBoard>();
var menuManager = gameManager.GetComponent<MenuManager>();
if (enemyHealth && menuManager)
{
if (menuManager.command == "red")
{
raycastGO.GetComponent<MeshRenderer>().material = red;
int photonViewId = raycastGO.GetComponent<PhotonView>().ViewID;
Vector3 color = new Vector3(241, 19, 19);
PhotonNetwork.CurrentRoom.SetCustomProperties
(new Hashtable() { { photonViewId.ToString(), color } });
}
if (menuManager.command == "green")
{
raycastGO.GetComponent<MeshRenderer>().material = green;
int photonViewId = raycastGO.GetComponent<PhotonView>().ViewID;
Vector3 color = new Vector3(20, 91, 17);
PhotonNetwork.CurrentRoom.SetCustomProperties
(new Hashtable() { { photonViewId.ToString(), color } });
}
}
}
}
step03: when a new player joins, use that Hashtable in OnJoinedRoom() callback to synchronize all changes
public override void OnJoinedRoom()
{
Hashtable customProperties = PhotonNetwork.CurrentRoom.CustomProperties;
foreach (string key in customProperties.Keys)
{
if (key.Contains("0") || key.Contains("curScn"))
{
//do nothing
}
else
{
int photonViewID = int.Parse(key);
PhotonView photonView = PhotonView.Find(photonViewID);
GameObject gameObject = null;
if (photonView != null)
{
gameObject = photonView.gameObject;
}
var colorInfo = (Vector3)customProperties[key];
float r = colorInfo.x / 255;
float g = colorInfo.y / 255;
float b = colorInfo.z / 255;
if (gameObject != null)
{
gameObject.GetComponent<MeshRenderer>().material.color
= new Color(r, g, b);
}
}
}
}