Hi to everyone, I have this problem: I have an RPC function, called RPC_FoodInGameSync(bool), which is called by a client when this one takes the pick up in the scene. This function should set the value of the boolean variable “food_ingame” in every client, but it doesn’t change its value (false if the pick up is taken, true if the pick up is instantiated, so it is in the scene). Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
public class PUN2_FoodSync : MonoBehaviourPun
{
PhotonView PV;
public GameObject[] food_prefabs; // array that contains the food prefabs
Vector3[] positions = {new Vector3(10,0,1),new Vector3(10,0,5),new Vector3(2,0,6),
new Vector3(4,0,9),new Vector3(0,0,-10),new Vector3(-4,0,-5),
new Vector3(-7,0,-8),new Vector3(-5,0,-5)}; // Vector that contains the spawn points of the food
public Vector3 position; // current position of the food in the scene
public bool food_ingame; // variable which says if there is a food in the scene or not
// Start is called before the first frame update
void Start()
{
PV = GetComponent<PhotonView>();
food_ingame = false; // initially, there is no food in scen, so this variable is set to false
}
// Update is called once per frame
void Update()
{
if(photonView.IsMine)
{spawn_food();} // this is the fuction for instantiating the food
}
void spawn_food()
{
if(food_ingame == false) // if there is no food, let's spwan one
{
if(PhotonNetwork.IsMasterClient) // only the Master can define the position of the food
{
Vector3 pos = positions[Random.Range(0,positions.Length)]; // choose the food position
PV.RPC("RPC_FoodInGameSync",RpcTarget.AllBuffered, true); // say to every client that there is a food in the scene
PV.RPC("RPC_FoodPositionSync",RpcTarget.AllBuffered,pos); // send the position of the new food, in order to the clients
// know where to instantiate the new food
}
}
}
void OnTriggerEnter(Collider col)// this method check if there are object that are collinding with the player (OnCollisionEnter(Collision col))
{
if(col.gameObject.tag == "Food") // if a player touch a food
{
if(photonView.IsMine) // if it was the local player, then:
{
// Controllore2 is a scipt attached to the player, which is use to move the player and to do others things
GetComponent<Controllore2>().old_size = GetComponent<Controllore2>().scala.x; // save the old size
if(GetComponent<Controllore2>().timer_array[0].activated == true) // timer_array[0] is a timer for slowly increasing the size of the player
{GetComponent<Controllore2>().old_size = GetComponent<Controllore2>().old_size + GetComponent<Controllore2>().add_size;}
GetComponent<Controllore2>().add_size = col.gameObject.GetComponent<Food>().add_size; // pass the value to be added to the player size
PV.RPC("RPC_FoodInGameSync",RpcTarget.AllBuffered, false); // say to every client that we have eaten the food
}
else // another client has taken the food
{
Debug.Log("the enemy has eaten the food!!!");
}
Destroy(col.gameObject); // destroy the local food
}
}
[PunRPC]
void RPC_FoodPositionSync(Vector3 positionSync)
{
position = positionSync;
// every client spawn a local food
Instantiate(food_prefabs[0],position, Quaternion.identity);
}
[PunRPC]
void RPC_FoodInGameSync(bool puInGameSync)
{
// update this variable on every client
food_ingame = puInGameSync;
}
}
When a client takes the pick up, it will call the RPC_FoodInGameSync(bool) rpc function in order to set the variable “food_ingame” to false in every client. When the Master receives this RPC function, it will see food_ingame=false, so then it will generate a position with the function spawn_food(), which will be sent through the networks by means of the rpc function RPC_FoodPositionSync(Vector3), in order to every client will instantiate the pick up in local and in the same position. There is no problem the first time these rpc functions are called (when the game starts), so the pick up is istantiated locally in each client in the correct position, but when a client (also the master) takes the pick up, the value of “food_ingame” will not change from true to false. The pick up, when it is taken, it is correctly destroyied in each client.
Maybe is there some concurrency problem between the RPC calls of the client (when it takes the pick up) and of the master (when it instantiates the pick up)? Maybe should I use another RpcTarget? Thank you!