Unity/Mirror networking no client sync

8.5k views Asked by At

Goal: Object interact-able by both players and its position and rotation is synced(LAN).

Scene setup : simple scene similar to pong example in mirror,when both players are spawned a cube is spawned that is interact-able by both players with sync.

Test cube - Registered as spawn-able prefab in network manager with network identity/network transform and spawned when both players join and simple rotation script that moves it when "z" or "x" is pressed,

public Transform LeftPlayerSpawn;
public Transform RightPlayertSpawn;
GameObject Testcube;

public override void OnServerAddPlayer(NetworkConnection conn)
{
    Transform start = numPlayers == 0 ? LeftPlayerSpawn : RightPlayertSpawn;
    GameObject player = Instantiate(playerPrefab, start.position, start.rotation);
    NetworkServer.AddPlayerForConnection(conn, player);

    if (numPlayers == 2)
    {
        Testcube = Instantiate(spawnPrefabs.Find(prefab => prefab.name == "TestCube"));
        NetworkServer.Spawn(Testcube);
    }
}

Problem : Any change made in server is reflected in clients,and local player has control over the object but not synced with other client. Video of No-Sync

Question : What is the purpose of the bool- client authority in Networktransform component,should it automatically sync that particular transform when client with authority moves it or does it allow user to sync manually through scripts?

From Mirror docs - "By default, Network Transform is server-authoritative unless you check the box for Client Authority. Client Authority applies to player objects as well as non-player objects that have been specifically assigned to a client, but only for this component. With this enabled, position changes are send from the client to the server".

Also tried to update position and rotation through [Command]/[CientRpc] through SyncPosRot script attached to the test cube,

void Update()
{
    if (isLocalPlayer) 
    {
        CmdSyncPosRot(transform.localPosition, transform.localRotation);
    } 
}

[Command]
void CmdSyncPosRot(Vector3 localPosition, Quaternion localRotation)
{
    RpcSyncPosRot(localPosition, localRotation);
}

[ClientRpc]
void RpcSyncPosRot(Vector3 localPosition, Quaternion localRotation)
{
    if (!isLocalPlayer) 
    {
        transform.localPosition = localPosition;
        transform.localRotation = localRotation;
    }
}

Tried and failed :

  1. Tried with and without SyncPosRot script,
  2. Tried with and without bool- client authority in network transform component,
  3. Moving the network identity/network transform to top and bottom of the inspector as this seemed to fix sync for others who had similar issue(not for me),

All the above after multiple builds and no results,

If the fix is something simple as spawning object from server - on which all players have ownership over can anyone please guide me?

Also if there is an easier way(need not be a better way/best practice) please let me know.

3

There are 3 answers

0
sparkblack On

Did not add owner when spawning Test cube :

    if (numPlayers == 0)
    {
        player1 = Instantiate(playerPrefab, LeftPlayerSpawn.position, LeftPlayerSpawn.rotation);
        NetworkServer.AddPlayerForConnection(conn, player1);
        spawn1 = true;
    }
    if (numPlayers == 1)
    {
        player2 = Instantiate(playerPrefab, RightPlayertSpawn.position, RightPlayertSpawn.rotation);
        NetworkServer.AddPlayerForConnection(conn, player2);
        spawn2 = true;
    }
    if (spawn1 && spawn2)
    {
        Testcube = Instantiate(spawnPrefabs.Find(prefab => prefab.name == "TestCube"));
        NetworkServer.Spawn(Testcube,player1);
    }

This Syncs rotation and position from player1 input but not player2.

9
Fatih Aslan On

Try this:

if (isServer)
{
    RpcSyncPosRot(transform.localPosition, transform.localRotation);
}
else
{
    CmdSyncPosRot(transform.localPosition, transform.localRotation);
}
0
CatPawnD20 On

I belive your problem is that you did not change object transform in server.

When you call Command you need to set object transform it does change object transform on the server side

You change object state in LeftClient side and RightClient side (with RPC) but you didn't change your object transform on the server side.

Maybe Network transform takes these transform values from the server and is overriding your ClientRPC, but i am not sure.