FreshRSS

Zobrazení pro čtení

Jsou dostupné nové články, klikněte pro obnovení stránky.

In Unity/UNet: How do you properly spawn a `NetworkPlayer`?

In Unity/UNet: How do you properly spawn a NetworkPlayer? Right now, I'm doing it like this from inside a NetworkManager derived class:

   public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId) {
        NetworkPlayer newPlayer = Instantiate<NetworkPlayer>(m_NetworkPlayerPrefab);
        DontDestroyOnLoad(newPlayer);
        NetworkServer.AddPlayerForConnection(conn, newPlayer.gameObject, playerControllerId);
   }

This code snippet works pretty well and both clients can communicate with each other. However, there are a few little issues that arise only on the host:

  1. In Unity's hierarchy-view on the host, there are only two NetworkPlayer instances. Shouldn't there be four NetworkPlayer instances on the host? Two client instances and two server instances? If so, do you have any ideas what could cause the missing NetworkPlayer instances?
  2. The two NetworkPlayer instances have both, their isClient and isServer flags set to true. But only one of the has it's isLocalPlayer flag set. Now I wonder if this behavior is as intended? And if so, how do you distinguish between the client and the server instance of a NetworkPlayer?
  3. Two player behavior: If the remote client sends a [Command] that changes a [SyncVar] on the server, then on the host, the [SyncVar]-hook is called only on the NetworkPlayer instance that represents the remote NetworkPlayer. The [SyncVar]-hook is not called on the host's "isLocalPlayer-NetworkPlayer" instance. Shouldn't the [SyncVar]-hook be called on both NetworkPlayer instances?

Any advise is welcome. Thank you!

Is this enough calculation on server-side to be secure?

I'm a beginner about client/server calculations and relationships (never trust the client), and I would like to know if I did or didn't get the concept right.

My weapons are calling this function inside their OnTriggerEnter2D:

[Rpc(SendTo.Server, RequireOwnership = false)]
public void TakeDamageServerRpc()
{
    //Calculate damage and stuff


    //then send to Rpc client
    TakeDamageClientRpc(1, RpcTarget.Single(OwnerClientId, RpcTargetUse.Temp));
}

This means the damage calculation (here it just sends 1) is done on the servers; afterwards, I call the function on the corresponding client side which looks like this:

[Rpc(SendTo.SpecifiedInParams)]
private void TakeDamageClientRpc(int damage, RpcParams rpcParams = default)
{
    if (state == STATE.DEAD)
        return;

    if (damage >= 1)
        state = STATE.DEAD;
}

My questions here are :

  1. Is the state variable on the player safe here? (I'd say yes.)
  2. Can the integer damage sent to the client be manipulated? (I'd say no.)
  3. Should TakeDamageServerRpc have an entry variable, can I trust it? (I'd say no.)
❌