2

我正在关注 YouTube 上的统一多人游戏教程(UNET),但与视频中的人相比,我得到了不同的结果。你看我跟着他的教程去喝茶了,但是在我的服务器脚本中的更新函数中,我在 switch 语句默认函数中使用了 debug.log 来告诉我是否收到了无效的消息,我就是。我认为我的信息并没有真正被正确发送,尽管我仔细遵循了那个人的教程!我的服务器脚本中是否缺少某些内容?

这是我的代码:

public class ServerClient
 {
  public int connectionId;
  public string playerName;
 }

public class Server : MonoBehaviour {

private const int MAX_CONNECTION = 4;

private int port = 8888;

private int hostId;
private int webHostId;

private int reliableChannel;
private int unreliableChannel;

private bool isStarted = false;
private byte error;

private List<ServerClient> clients = new List<ServerClient>();

private void Start()
{
    NetworkTransport.Init ();
    ConnectionConfig cc = new ConnectionConfig ();

    reliableChannel = cc.AddChannel (QosType.Reliable);
    unreliableChannel = cc.AddChannel (QosType.Unreliable);

    HostTopology topo = new HostTopology (cc, MAX_CONNECTION);

    hostId = NetworkTransport.AddHost (topo, port); // null
    Debug.Log ("Socket Open. hostId is: " + hostId);
    webHostId = NetworkTransport.AddWebsocketHost (topo, port, null); //, port, null

    isStarted = true;
}

private void Update()
{
    if (!isStarted)
        return;

    int recHostId;
    int connectionId;
    int channelId;
    byte[] recBuffer = new byte[1024];
    int bufferSize = 1024;
    int dataSize;
    byte error;
    NetworkEventType recData = NetworkTransport.Receive (out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
    switch (recData) {
    case NetworkEventType.ConnectEvent:   //2
        Debug.Log ("Player " + connectionId + "has connected");
        OnConnection (connectionId);
        break;
    case NetworkEventType.DataEvent:      //3
        string msg = Encoding.Unicode.GetString(recBuffer, 0, dataSize);
        //Debug.Log("Player" + connectionId + " has sent :  " + msg);
        Debug.Log("Recieving from " + connectionId + " : " + msg);

        string[] splitData = msg.Split ('|');

        switch (splitData[0])
        {
        case "OnNameIs":
            OnNameIs (connectionId, splitData [1]);
                break;

            default:
                Debug.Log ("Invalid message:  " + msg);
                break;
        }

        break;

        case NetworkEventType.DisconnectEvent:     // 4
        Debug.Log("Player " + connectionId + "has disconnected");
        break;
    }
}


private void OnConnection(int cnnId)
{
    // This may add a thrid player 
     ServerClient c = new ServerClient();
     c.connectionId = cnnId;
     c.playerName = "TEMP";
     clients.Add(c);
     //So you might want to change this later 

    string msg = "AskName|" + cnnId + "|";
    foreach (ServerClient sc in clients) 
        msg += sc.playerName + '%' + sc.connectionId + '|';

    msg = msg.Trim ('|');

    Send (msg, reliableChannel, cnnId); 
}

private void OnNameIs(int cnnId, string playerName)
{
    clients.Find (x => x.connectionId == cnnId).playerName = playerName;

    Send ("CNN|" + playerName + '|' + cnnId, reliableChannel, clients);
}

private void Send(string message, int channelId, int cnnId)
{
    List<ServerClient> c = new List<ServerClient>();
    c.Add (clients.Find (x => x.connectionId == cnnId));
    Send (message, channelId, c);
}

private void Send(string message, int channelId, List<ServerClient> c)
{
    Debug.Log ("Sending  : " + message);
    byte[] msg = Encoding.Unicode.GetBytes (message);
    foreach (ServerClient sc in c) 
    {
        NetworkTransport.Send (hostId, sc.connectionId, channelId, msg, message.Length * sizeof(char), out error);
    }
}

}

下面的脚本是我的客户端脚本:

public class Player
{
  public string playerName;
  public GameObject avatar;
  public int connectionId;
}

public class Client : MonoBehaviour {


private const int MAX_CONNECTION = 4;

private int port = 8888; //5701

private int hostId;
private int webHostId;

private int connectionId;
private int ourClientId;

private int reliableChannel;
private int unreliableChannel;

private float connectionTime;
private bool isConnected = false;
private bool isStarted = false;
private byte error;

private string playerName;

public GameObject playerPrefab;

public List<Player> players = new List<Player>();

public void Connect()
{
    //Does the player have a name?
    //take this part out
    string pName = GameObject.Find("NameInput").GetComponent<InputField>().text;

    if (pName == "") {
        Debug.Log ("you must enter a name");
        return;
    }

    playerName = pName;

    //

    // place this is the Start fuction
    NetworkTransport.Init ();
    ConnectionConfig cc = new ConnectionConfig ();

    reliableChannel = cc.AddChannel (QosType.Reliable);
    unreliableChannel = cc.AddChannel (QosType.Unreliable);

    HostTopology topo = new HostTopology (cc, MAX_CONNECTION);

    hostId = NetworkTransport.AddHost (topo, 0);
    //

    byte error;
    connectionId = NetworkTransport.Connect (hostId, "127.0.0.1", port, 0, out error);
    Debug.Log ("Connection to server. ConnectionId: " + connectionId);
    connectionTime = Time.time;
    isConnected = true;
}

private void Update()
{
    if (!isConnected)
        return;

    int recHostId;
    int connectionId;
    int channelId;
    byte[] recBuffer = new byte[1024];
    int bufferSize = 1024;
    int dataSize;
    byte error;
    NetworkEventType recData = NetworkTransport.Receive (out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
    switch (recData) {
    case NetworkEventType.DataEvent:      //1
        string msg = Encoding.Unicode.GetString (recBuffer, 0, dataSize);
        Debug.Log ("Recieving : " + msg);
        string[] splitData = msg.Split ('|');

        switch (splitData[0])
        {
        case "AskName":
            OnAskName (splitData);
            break;

        case "CNN":
            SpawnPlayer (splitData[1], int.Parse(splitData[2]));
            break;

        case "DC":
            break;

        default:
            Debug.Log ("Invalid message:  " + msg);
            break;
        }

        break;
    }
}

private void OnAskName(string[] data)
{ 
    ourClientId = int.Parse (data [1]);

    Send ("OnNameis|" + playerName, reliableChannel);

    for (int i = 2; i < data.Length - 1; i++)
    {
        string[] d = data[i].Split('%');
        SpawnPlayer(d[0], int.Parse(d[1]));
    }
}

private void SpawnPlayer(string playerName, int cnnId)
{
    GameObject go = Instantiate (playerPrefab) as GameObject;
    Debug.Log ("Object has been spawn", go);

    if (cnnId == ourClientId)  // the problem //
    {
        GameObject.Find("Canvas").SetActive (false);
        isStarted = true;
    }

    Player p = new Player ();
    p.avatar = go;
    p.playerName = playerName;
    p.connectionId = cnnId;
    p.avatar.GetComponentInChildren<TextMesh>().text = playerName;
    players.Add (p);
}

private void Send(string message, int channelId)
{
    Debug.Log ("Sending  : " + message);
    byte[] msg = Encoding.Unicode.GetBytes (message);
    NetworkTransport.Send (hostId, connectionId, channelId, msg, message.Length * sizeof(char), out error);
}

先感谢您!

4

1 回答 1

1

不完全是茶。如果你仔细观察,你会发现:

  • 客户端发送一个带有名字的命令OnNameis
  • 虽然服务器需要一个名为的命令OnNameIs

这几乎说明了将字符串用于命令的危险。请改用枚举。

于 2017-04-19T20:32:15.657 回答