Networked Coroutine DOESNT behave on client

I have a simple networking issue right now, where I have an authoritative server calling all the shots in a multiplayer game, and when the server calls an RPC (just a simple method to start a coroutine locally) the coroutine runs fine on the server (or in single player) but the client doesnt run the coroutine, even though debug shows the code reaches the same point on client and server!

Heres exactly what happens:

  1. The server send out an update to a “planet” (gameobject/scripts running it) like this

    networkView.RPC(“SendPlanetMessage”, RPCMode.OthersBuffered, i, Teams_, Units*); // update clients of this status*_
    2) The RPC fires on the client, and performs the following
    [RPC]
    * void SendPlanetMessage(int planetNumber, int team, int units)*
    * {*
    // Debug.Log("RPC: SendPlanetMessage - ID: " + networkView.viewID.ToString());
    * // send all connected users the updates planetary info*
    * if(Teams[planetNumber] != team)*
    * SimpleSwitchColor(planetNumber, team);*
    * Teams[planetNumber] = team;*
    * Units[planetNumber] = units;*
    * }*
    3) This starts another method locally (client) “SimpleSwitchColor()” like below
    void SimpleSwitchColor(int planetNumber, int team)
    * {*
    * Debug.Log("RPC: SimpleSwitchColor " + planetNumber + " to " + team);*
    * // use it like: networkView.RPC(SimpleSwitchColor(planetNumberString, someColor), RPCMode.AllBuffered);*
    * StartCoroutine(ChangePlanetColor(planetNumber, Planets[planetNumber].renderer.material.color, team, Time.time));*
    * }*
    4) Which in turn starts this Coroutine for “fading” the gameobjects color (works on server every time)
    IEnumerator ChangePlanetColor(int planetNumber, Color startColor, int endTeam, float startTime)
    * {*
    * Debug.Log(“Changing planet color”);*

* // change planet colors*
* if(endTeam == 1)*
* {*
* while(Planets[planetNumber].renderer.material.color != GreenColor && Teams[planetNumber] == endTeam)*
* {*
* Color lerpedColor = Color.Lerp(startColor, GreenColor, (Time.time - startTime) / 5);*
* Planets[planetNumber].renderer.material.color = lerpedColor;*
* yield return new WaitForSeconds(0.15f);*
* }*
* }*
* if(endTeam == 2)*
* {*
* while(Planets[planetNumber].renderer.material.color != RedColor && Teams[planetNumber] == endTeam)*
* {*
* Color lerpedColor = Color.Lerp(startColor, RedColor, (Time.time - startTime) / 5);*
* Planets[planetNumber].renderer.material.color = lerpedColor;*
* yield return new WaitForSeconds(0.15f);*
* }*
* }*
* if(endTeam == 3)*
* {*
* while(Planets[planetNumber].renderer.material.color != BlueColor && Teams[planetNumber] == endTeam)*
* {*
* Color lerpedColor = Color.Lerp(startColor, BlueColor, (Time.time - startTime) / 5);*
* Planets[planetNumber].renderer.material.color = lerpedColor;*
* yield return new WaitForSeconds(0.15f);*
* }*
* }*
* }*
Now, why in the world does it work just fine (locally) when called on server, yet even when its LOCALLY called (through the steps above) on the client, with correct vars, it does NOT change the color of the GO whatsoever… stays the default color…
Is this something strange about unity networking? the console debug entry shows me that the coroutine is getting the right information… maybe im a tired coffee filled coder who needs a break? Am I missing something obvious here?
A couple notes: the server ALSO calles SimpleSwitchColor() when doing this, just not from planet message… I am using Unity 3x latest… testing with both android and windows standalones, sometimes two builds, sometimes a build as server and editor as client, vice versa sometimes…

So what Debug.Logs are you actually seeing? Does SimpleSwitchColor get executed? Does the coroutine get started? What value has “endTeam” on the server / client? Why do you actually check if the “endTeam” is Teams[planetNumber] in the while loop? is it a termination condition? Also is there a reason why you want 6.666 color changes per second?

I would implement this coroutine like this:

IEnumerator ChangePlanetColor(int planetNumber, int endTeam)
{
    if (Teams[planetNumber] != endTeam)
        yield break;
    
    Material mat = Planets[planetNumber].renderer.material;
    Color startColor = mat.color;
    Color targetColor = Color.black;
    if (endTeam == 1)
        targetColor = GreenColor;
    else if (endTeam == 2)
        targetColor = RedColor;
    else if (endTeam == 3)
        targetColor = BlueColor;
    float t = 0;
    while(t < 1.0f)
    {
        t += Time.deltaTime / 5;
        mat.color = Color.Lerp(startColor, targetColor, t);
        yield return null;
    }
}

I think that’s a bit easier and more readable. Also a bit more effecient.

There’s nothing wrong the way you call your coroutine. Just add some more debug logs to see what actually get’s executed. Just to be sure: Are you sure that the GameObject and the script are activated / enabled? Coroutines won’t run on disabled GameObjects / MonoBehaviours.