Search code examples
unity-game-engineunity3d-unet

Sync Sprite renderer's flip with unet


I am very new to Unity. I am working on a simple multiplayer game.

Problem I am facing is I am not able to sync the sprite renderer's flip state when we press left and right arrow keys.

Below is the code I tried.

[SerializeField] 
private SpriteRenderer spriteRenderer;

[Command]
void CmdProvideFlipStateToServer(bool state)
{
    spriteRenderer.flipX = state;
}

[ClientRpc]
void RpcSendFlipState(bool state)
{
    CmdProvideFlipStateToServer(state);
}

private void Flip()
{
    facingRight = !facingRight;
    if(isClient){
        spriteRenderer.flipX = !facingRight;
    }
    if(isLocalPlayer){
        RpcSendFlipState(spriteRenderer.flipX);
    }
}

Solution

  • I'm assuming what you want is:

    In any moment the function Flip() is called on a Client.

    => his local Sprite is changed and you want to synchronize this over a server to the other clients.


    If this is the case you re using Command and ClientRpc the wrong way:

    • Command: is invoked on the Client but only executed on the Server
    • ClientRpc: is invoked on the Server but only executed on (ALL) clients

    => your script should rather look somehow like

    [SerializeField] 
    private SpriteRenderer spriteRenderer;
    
    // invoked by clients but executed on the server only
    [Command]
    void CmdProvideFlipStateToServer(bool state)
    {
        // make the change local on the server
        spriteRenderer.flipX = state;
    
        // forward the change also to all clients
        RpcSendFlipState(state)
    }
    
    // invoked by the server only but executed on ALL clients
    [ClientRpc]
    void RpcSendFlipState(bool state)
    {
        // skip this function on the LocalPlayer 
        // because he is the one who originally invoked this
        if(isLocalPlayer) return;
    
        //make the change local on all clients
        spriteRenderer.flipX = state;
    }
    
    // Client makes sure this function is only executed on clients
    // If called on the server it will throw an warning
    // https://docs.unity3d.com/ScriptReference/Networking.ClientAttribute.html
    [Client]
    private void Flip()
    {
        //Only go on for the LocalPlayer
        if(!isLocalPlayer) return;
    
        // make the change local on this client
        facingRight = !facingRight;
        spriteRenderer.flipX = !facingRight;
    
        // invoke the change on the Server as you already named the function
        CmdProvideFlipStateToServer(spriteRenderer.flipX);
    }