Objects movement for different direction using Mirror

I want to create a 2-player online card game using Unity, but I’m having issues with card movement functionality.

As shown in the diagram, when Player 1 (right side) draws a card from their deck, the card should move to their hand area towards the lower left. For Player 2 (left image), they should see the card moving from Player 1’s deck (opponent’s side) towards the upper right to Player 1’s hand area (opponent’s side).

However, my current issue is that Player 2 sees the card moving in the same direction as Player 1 sees it.

I’m using Mirror for networking. When modifying Sync Direction, the error pattern changes - cards might move from hand to deck instead, and the error can occur on either the Host or Client.

Since the game has multiple zones, I prefer to control card movement start/end points programmatically rather than using animations. I’m trying to implement this using Update() or IEnumerator.

Below is my partial code and the card’s inspector. Currently, the server side is showing errors while the Client side works correctly.

Cards’ script

    void Update()
    {

        NetworkIdentity networkId = NetworkClient.connection.identity;
        playerManager = networkId.GetComponent<PlayerManager>();
        if (isPointing)
        {
            if (Input.GetKeyUp(KeyCode.H) & isControllable & transform.parent.transform != myHandArea.transform)
            {
                playerManager.CmdMoveCard(gameObject, "Hand");                
            }            
            
        }
               
        if (isMoveCard > 1)
        {
            transform.position = Vector2.MoveTowards(transform.position, targetArea.transform.position, 10);
            isMoveCard -= 1;
            
        }
        else if (isMoveCard == 1)
        {
            isMoveCard = 0;
            transform.SetParent(targetArea.transform, false);
            targetArea = null;
        }
    }

PlayerManager

    [Command]
    public void CmdMoveCard(GameObject card, string target)
    {
        RpcMoveCard(card, target);
    }


    [ClientRpc]
    void RpcMoveCard(GameObject card, string target)
    {
        CardBehavier cardBehavier = card.GetComponent<CardBehavier>();
        if (target == "Hand")
        {            
            if (isOwned)
            {
                cardBehavier.targetArea = myHandArea;
            }
            else
            {
                cardBehavier.targetArea = enemyHandArea;
            }            
        }
        cardBehavier.isMoveCard = 30;
    }

my sync direction of card is client to server

I’m not an expert in Mirror, but I’m not sure if you can send a GameObject over an RPC call? Instead, you’d want to send the network id over and have each client find the object based on that id.

Card Script (Just the CMD call line)

playerManager.CmdMoveCard(networkId.netId, "Hand"); 

PlayerManager

    [Command]
    public void CmdMoveCard(uint cardId, string target)
    {
        RpcMoveCard(cardId, target);
    }


    [ClientRpc]
    void RpcMoveCard(uint cardId, string target)
    {
         GameObject card = null;

         //Find the correct object with the netid
         //Card objects will need to be tagged with "Card" tag
         GameObject[] arr = GameObject.FindGameObjectsWithTag("Card");
         foreach(GameObject o in arr)
         {
             if (o.GetComponent<NetworkIdentity>().netId == cardId)
             {
                 card = o;
             }
         }

        if(card == null)
        {
             return;
        }

        CardBehavier cardBehavier = card.GetComponent<CardBehavier>();
        if (target == "Hand")
        {            
            if (isOwned)
            {
                cardBehavier.targetArea = myHandArea;
            }
            else
            {
                cardBehavier.targetArea = enemyHandArea;
            }            
        }
        cardBehavier.isMoveCard = 30;
    }

This is assuming everything else is working/set up correctly. IE, cards are correctly initialized by the server and stuff like that.

You probably get confused by whether the code executes for client/host respectively P1/P2 as you need to account for the switch in perspective. The issue may not even be in the code you provided, at least I can’t spot anything.

I do recommend not to send strings as parameters, since a byte enum suffices and this will conserve bandwidth and avoid any string comparison logic (always problematic).

The isMoveCard being an integer is also odd, since any variable prefixed with “is” is expected to be a bool. This makes the conditionals read very odd like if (isMoveCard > 1) … it’s almost impossible to guess what this means for anyone but you. And even you may get confused by programming things this way.

In any case, use the debugger to see what you get and either side and where the logic fails to meet your expectations.

Thank you both very much for your answers. These aspects were indeed things I hadn’t considered. I should improve my code by using NetID and avoiding strings to achieve better connectivity. This is my first time working with network connections, and I truly hadn’t thought about bandwidth usage and network issues. Additionally, regarding the position synchronization problem, I found the source of the issue - it was that the “Sync position” should not be checked in the card’s Network Transform component. This resolved the problem.