yield return for Photon RPC Coroutine
Hi,
I am calling a photon RPC Coroutine from within another unity Coroutine.
I need the execution of the unity Coroutine to pause "i.e. Yield Return" until the Photon Coroutine has finished execution, but yield return does not work when calling a Photon RPC
In the code example below you can see how unity would ordinarily pause execution in the 2nd statement by using yield return StartCoroutine().
But how do I achieve the same for the 1st Statement where I call Photon RPC Coroutine?
private IEnumerator GameLoop ()
{
// Start off by running the 'RoundStarting' coroutine but don't return until fin
view.RPC("RoundStarting", RpcTarget.AllBufferedViaServer);
// Once the 'RoundStarting' fin run 'RoundPlaying' but don't return until fin
yield return StartCoroutine (RoundPlaying());
// Once execution has returned here, run the 'RoundEnding'
yield return StartCoroutine (RoundEnding());
// This code is not run until 'RoundEnding' has finished.
if (m_GameWinner != null)
{
// If there is a game winner, restart the level.
SceneManager.LoadScene (1);
}
else
{
// If there isn't a winner yet, restart this coroutine so the loop continues.
StartCoroutine (GameLoop ());
}
}
I have some troubles to understand what you mean by "Photon Coroutine". As you already stated this does not really exsist right? Can you specify what you mean by that? Do you mean that you want to wait until the RoundStarting
function has terminated for all players and only then want to go on in the coroutine you posted to start the RoundPlaying
Routine for everyone?
@Captain_Pineapple What I mean is, "RoundStarting" is a Coroutine itself. The reason I want to call it with view.RPC("RoundStarting", RpcTarget.AllBufferedViaServer); is simply so that it executes for all clients connected.
But in short my real problem is that I cannot "yield return" when calling the Coroutine as an RPC (that is what I mean by "Photon Coroutine")
I would like to change "RoundPlaying" and "RoundEnding" to eventually be called as RPC's as well, however as I cannot use yield return this just means they would execute one after another and not wait for each to finish. I just left them in the code snippet as normal Coroutines so you can see how they yield return until given Coroutine finishes
So just to be extra clear the issue is basically that Gameloop() Coroutine needs to pause execution with something like a yield return but when calling an RPC hope this makes sense
Answer by Captain_Pineapple · Apr 05 at 05:23 AM
Well then, given the additional information:
What you are trying to do here does not work. There is no way to have a RPC "return" in a way that you can directly yield for it.
So what can we do instead?
What you need to implement here is some kind of "acknowledgement" which is sent from all players to the master. So you can still send the start command for your "GameStart" state but the state ends once the master player has received the "ack" call for "GameStarting" from all players in the room. Then you can send the next RPC out.
This for example could be done in a simple manner with a counter which is incremented by one for each "ack" message for the current game state:
private int acksRecievedForCurrentState = 0;
[RPC]
public void acknowledgeState()
{
//increment acksRecievedForCurrentState
}
Given this you can then change your yield statement for:
view.RPC("RoundStarting", RpcTarget.AllBufferedViaServer);
yield return new WaitUntil(acksRecievedForCurrentState >= playernumberInRoom);
acksRecievedForCurrentState = 0; // don't forget to reset once you enter the next stage
view.RPC("RoundPlaying", RpcTarget.AllBufferedViaServer);
Let me know if that helped or something was unclear.