0

您好我正在尝试使用 UNet 设置通过浏览器播放的多人游戏。在编辑器中一切正常,我按照教程(https://www.youtube.com/watch?v=qGkkaNkq8co)说它应该在 webgl 中工作,但遗憾的是它没有。目前有两个脚本,一个用于客户端,一个用于下面链接的服务器。这主要使用 LLAPI。

我是否使用 networkServer.usewebsocket = true 结果是一样的。

“完成连接”的调试确实显示,因此它完成了 OnConnection 功能。

从编辑器一切正常,但从浏览器我收到以下错误:

“尝试发送到未连接的连接 {1}”——因为我在询问 ASKNAME 和询问 ASKPOSITION 时收到此错误,所以我怀疑 SEND 函数是我试图发送浏览器无法理解的内容的问题。但我不知道为什么。

private int port = 3001;
private List<ServerClient> clients = new List<ServerClient>();
private float lastMovementUpdate;
private float movementUpdateRate = 0.05f;
private int socketId;
private int webHostId;
private int reliableChannel;
private int unReliableChannel;
private bool isStarted = false;
private byte error;

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);
 socketId = NetworkTransport.AddHost(topo, port, null);
 webHostId = NetworkTransport.AddWebsocketHost(topo, 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.Nothing:         //1
         break;
     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("Receiving From " + connectionId + "has sent : " + msg);
         string[] splitData = msg.Split('|');
         switch (splitData[0])
         {
             case "NAMEIS":
                 OnNameIS(connectionId, splitData[1]);
                 break;
             case "MYPOSITION":
                 OnMyPosition(connectionId, float.Parse(splitData[1]), float.Parse(splitData[2]));
                 break;
             default:
                 Debug.Log("invalid message : " + msg);
                 break;
         }

         break;

     case NetworkEventType.DisconnectEvent: //4
         Debug.Log("Player " + connectionId + "has disconnected");
         OnDiconnection(connectionId);
         break;
 }
 if (clients.Count > 0)
 {
     if (Time.time - lastMovementUpdate > movementUpdateRate)
     {
         lastMovementUpdate = Time.time;
         string posMsg = "ASKPOSITION|";
         foreach (ServerClient sc in clients)
             posMsg += sc.connectionId.ToString() + '%' + sc.position.x.ToString() + '%' + sc.position.y.ToString() + '|';
         posMsg = posMsg.Trim('|');
         Send(posMsg, unReliableChannel, clients);
     }
 }
 }

 private void OnConnection(int cnnId)
 {
 Debug.Log("Arrived at connection");
 ServerClient c = new ServerClient();
 c.connectionId = cnnId;
 c.playerName = "TEMP";
 clients.Add(c);
 string msg = "ASKNAME|" + cnnId + "|";
 foreach (ServerClient sc in clients)
     msg += sc.playerName + '%' + sc.connectionId + '|';
     msg = msg.Trim('|');
 Send(msg, reliableChannel, cnnId);
 Debug.Log("Finished at connection");
 }

 private void OnNameIS(int cnnId, string playerName)
 {
 // link the name to the connection ID
 clients.Find(x => x.connectionId == cnnId).playerName = playerName;
 // Tell evertone that a new player has connected
 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(socketId, sc.connectionId, channelId, msg, message.Length * sizeof(char), out error);
 }
 }

 private void OnDiconnection(int cnnId)
 {
 clients.Remove(clients.Find(x => x.connectionId == cnnId));
 string msg = "DC|" + cnnId;
 Send(msg, reliableChannel, clients);
 }

 private void OnMyPosition(int cnnId, float x, float y)
 {
 clients.Find(clientInQuestion => clientInQuestion.connectionId == cnnId).position = new Vector3(x, y, 0);
 }

然后是客户端:

     private const int MAX_CONNECTION = 100;

 private int port = 3001;

 private int hostId;
 private int webHostId;
 private int reliableChannel;
 private int unReliableChannel;

 private int connectionId;
 private int clientId;


 private bool isConnected = false;

 public bool isStarted = false;

 private float connectionTime;

 private string playerName;

 private byte error;

 public GameObject playerPrefab;
 public Dictionary<int, player> players = new Dictionary<int, player>();

 public void Connect()
 {
     Debug.Log("connecting...");
     // does player have a name?
     string pName = GameObject.Find("NameInput").GetComponent<InputField>().text;
     if (pName == "")
     {
         Debug.Log("Enter a name");
         return;
     }

     playerName = pName;



     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);

     connectionId = NetworkTransport.Connect(hostId, "127.0.0.1", port, 0, out error);

     connectionTime = Time.time;

     isConnected = true;

     Debug.Log("connected");
 }

 private void Update()
 {
     connectionTime += Time.deltaTime;

     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:
             string msg = Encoding.Unicode.GetString(recBuffer, 0, dataSize);
             Debug.Log("receiving : " + 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":
                     playerDisconnected(int.Parse(splitData[1]));
                     break;
                 case "ASKPOSITION":
                     OnAskPosition(splitData);
                     break;

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

             break;

     }
 }

 private void OnAskName(string[] data)
 {
     // set the client ID
     clientId = int.Parse(data[1]);

     // send our name to the server
     Send("NAMEIS|" + playerName, reliableChannel);

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

 private void OnAskPosition(string[] data)
 {

     if (!isStarted)
         return;

     //update everyone else
     for (int i = 1; i <= data.Length-1; i++)
     {
         string[] d = data[i].Split('%');

         //prevent the server from updating us
         if (clientId != int.Parse(d[0]))
         {
             Debug.Log("updating position");
             Vector3 position = Vector3.zero;
             position.x = float.Parse(d[1]);
             position.y = float.Parse(d[2]);
             players[int.Parse(d[0])].avatar.transform.position = position;
         }
     }

     //send out own position
     Vector3 myPosition = players[clientId].avatar.transform.position;
     string m = "MYPOSITION|" + myPosition.x.ToString() + '|' + myPosition.y.ToString();
     Send(m, unReliableChannel);

 }

 private void SpawnPlayer(string playerName, int cnnId)
 {
     GameObject go = Instantiate(playerPrefab) as GameObject;

     // is this ours?

     if(cnnId == clientId)
     {
         // add mobility
         go.AddComponent<PlayerController>();

         // remove Canvas
         GameObject.Find("Canvas").SetActive(false);

         isStarted = true;
     }

     player p = new player();
     p.avatar = go;
     p.playerName = playerName;
     p.avatar.GetComponentInChildren<TextMesh>().text = playerName;
     p.connectionId = cnnId;

     players.Add(cnnId, 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);
 }

 private void playerDisconnected(int cnnId)
 {
     Destroy(players[cnnId].avatar);
     Debug.Log("player : " + players[cnnId].playerName + " has disconnected");
     players.Remove(cnnId);
 }
}

任何反馈都将不胜感激,我已经尝试过查看文档,但我觉得我已经完成了它所说的所有事情(https://docs.unity3d.com/Manual/UNetUsingTransport.html)在它谈话的底部关于 webgl 支持,但它似乎没有奏效。

非常感谢您。

4

1 回答 1

0

修复了这个问题,

答案是我发送到 HostID 而不是 webSocketId

所以这:

    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);
    }
}

改为:

    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(webSocketId, sc.connectionId, channelId, msg, message.Length * sizeof(char), out error);
    }
}
于 2017-08-08T15:02:32.207 回答