Unity网络服务器和客户端通信问题

时间:2020-10-14 14:36:28

标签: c# unity3d

这是我的第一个多人游戏,我想知道如何使服务器和客户端进行通信。我在下面尝试过此代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class PlayerPrefabScript : NetworkBehaviour
{
public bool isHostPlayer;
public static string PlayerName;
public int PlayerScore;
private bool updateNames = true;

void Start()
{
    LoadData();
 
    if (!isServer)
    {
        Debug.Log("Host");
        CmdSendInfo(PlayerName, PlayerScore);
    }
    else if(isServer)
    {
        Debug.Log("Server");
        transform.name = PlayerName;
    }
}

void Update()
{
  
}

[Command]
public void CmdSendInfo(string name, int points)
{
    RpcUpdateInfo(name, points);
}

[ClientRpc]
void RpcUpdateInfo(string name, int points)
{
    transform.name = name;
}

public void SaveData()
{
    SaveSystem.SaveData();
}

public void LoadData()
{
    PlayerData data = SaveSystem.LoadData();

    PlayerName = data.PlayerName;
}

}

每当我构建项目并通过电话连接到unity builder时,它总是在电话上运行,因为客户端调试2次“主机”,在unity builder中调试为服务器“ Server” 2次。现在,我只希望能够更改开始时可以选择的玩家名称,但现在仅更改客户端名称,我如何才能实现服务器也更改其名称?

1 个答案:

答案 0 :(得分:0)

Afaik有三点:

  1. Afaik RPC仅在客户端上执行,而不在主机本身上执行(尽管那可能是错误的)

    =>您还应该在CMD内部进行相同的更改

  2. PlayerName可能应该static,以便只有自己的播放器对象才能实际执行加载,并且只有它会使用它。

    =>您应该检查自己是否isLocalPlayer,并且仅对此一个实例进行加载

  3. 玩家仍然有问题,稍后再连接

    =>您应该使用SyncVar,以便始终将数据从主机传递到所有客户端,以及以后连接的客户端。

    =>您实际上不需要RPC

所以也许像

public string PlayerName;
public int PlayerScore;

[SyncVar(hook = nameof(OnRemoteChangedName))] public string SyncedPlayerName;
[SyncVar(hook = nameof(OnRemoteChangedPoints))] public int SyncedPlayerScore;

void Start()
{
   // Important: Check if this is even your own player 
   // we don't want to set the data for the other players
   if(isLocalPlayer)
   {
       LoadData();
 
       name = PlayerName;

       if (!isServer)
       {
           Debug.Log("Client");
           // Tell the server and other clients our name
           CmdSendInfo(PlayerName, PlayerScore);
       }
       else 
       {
           Debug.Log("Server");
           
           // Tell all clients our values even later connected ones
           SyncedPlayerName = name;
           SyncedPlayerScore = PlayerScore;
       }
    }
}

[Command]
public void CmdSendInfo(string newName, int points)
{
    name = newName;
    PlayerName = newName;
    PlayerScore = points;

    // By setting these the values are automatically synced down to all clients
    // even to those that connect later
    SyncedPlayerName = newName;
    SyncedPlayerScore = points;
}

// Will be executed on the client when the host changes the value of SyncedPlayerName
private void OnRemoteChangedName(string newName)
{
    PlayerName = newName;
    name = newName;
}

// Will be executed on the client when the host changes the PlayerScore
private void OnRemoteChangedPoints(int newPoints)
{
    PlayerScore = newPoints;
}