Search code examples
c#unity-game-engineunity-networking

Unity Networking: Flipping sprites in Multiplayer doesn't flip host


I'm working on a small multiplayer 2d platformer game. I've managed to get it to replicate animations, movement and flipping sprites across network, but I have a bug I can't get my head around. The code for flipping sprites works perfectly for the host - he can see other players switch sides when turning left or right, but everyone else cannot see the host flip. Also the third player cannot see the second player turn etc. Something is not right and it would be great if someone could take a look at my code.

Code in main Player script:

if (input.x > 0 && !facingRight)
     {
         FlipSprite();
         GetComponent<Player_SyncPosition>().FlipSprite();
     }
     else if (input.x < 0 && facingRight)
     {
         FlipSprite();
         GetComponent<Player_SyncPosition>().FlipSprite();
     }

Code in an additional Player_SyncPosition script on the player:

 [ClientCallback]
 public void FlipSprite()
 {  
     if (isLocalPlayer)
     {
         CmdFlip();
     }
 }
 [Command]
 void CmdFlip()
 {
     if (!isLocalPlayer)
     {
         print("Switching sides");
         facingRight = !facingRight;
         Vector3 SpriteScale = GetComponent<Transform>().localScale;
         SpriteScale.x *= -1;
         GetComponent<Transform>().localScale = SpriteScale;
     }
 }

Edit:

Player

Player_SyncPosition pSync;
void Awake()
{
    pSync = GetComponent<Player_SyncPosition>();
}

void Update () 
{
if ((input.x > 0 && !pSync.facingRight) || (input.x < 0 && pSync.facingRight))
    {
        pSync.FlipSprite();
    }
}

Player_SyncPosition

[SyncVar(hook = "FaceDirCallback")]
public bool facingRight = true;

[ClientCallback]
public void FlipSprite()
{
    if (isLocalPlayer)
    {
        CmdFlip();
    }
}
[Command]
void CmdFlip()
{
    print("Switching sides");
    facingRight = !facingRight;
    Vector3 SpriteScale = transform.localScale;
    SpriteScale.x *= -1;
    transform.localScale = SpriteScale;
}

void FaceDirCallback(bool newValue)
{
    print(facingRight);
    print(newValue);
    facingRight = newValue;
}

Solution

  • I experienced a whole variety of different problems (moving backwards etc.) and this is working:

    Player:

    void Awake()
         {
             syncPos = GetComponent<Player_SyncPosition>();
         }
    
    void Update()
     {
      if ((input.x > 0 && !facingRight) || (input.x < 0 && facingRight))
             {
                 facingRight = !facingRight;
                 syncPos.CmdFlipSprite(facingRight);
             }
     }
    

    Player_SyncPosition:

     [SyncVar(hook = "FacingCallback")]
         public bool netFacingRight = true;
    
     [Command]
         public void CmdFlipSprite(bool facing)
         {
             netFacingRight = facing;
             if (netFacingRight)
             {
                 Vector3 SpriteScale = transform.localScale;
                 SpriteScale.x = 1;
                 transform.localScale = SpriteScale;
             }
             else
             {
                 Vector3 SpriteScale = transform.localScale;
                 SpriteScale.x = -1;
                 transform.localScale = SpriteScale;
             }
         }
    
         void FacingCallback(bool facing)
         {
             netFacingRight = facing;
             if (netFacingRight)
             {
                 Vector3 SpriteScale = transform.localScale;
                 SpriteScale.x = 1;
                 transform.localScale = SpriteScale;
             }
             else
             {
                 Vector3 SpriteScale = transform.localScale;
                 SpriteScale.x = -1;
                 transform.localScale = SpriteScale;
             }
         }