2017-09-18 12 views
1

UnityのNetworkTransportを実装する方法に関する広範なチュートリアルを終えたが、私がフォローしている間は意味があったが、一旦終了して変更を始めたとき、私。私は、サーバとクライアントのスクリプトがどのように関係しているのか、そしてサーバ/クライアントに送るための変数を追加する方法を理解するために少し助けが必要です。NetworkTransport:サーバーとクライアントに複数のデータを送信する

スクリプトは現在、クライアント側に2つの変数(Texture2Dと文字列)を追加して、プレーヤークラスに追加してサーバーや他のクライアントに渡します。

私はこの2つの追加の変数をPlayerクラスに追加し、同じ変数をサーバースクリプトのServerClientクラスに追加することでクライアントスクリプトを開始しました。その後、SpawnPlayer関数のクライアントスクリプトで、私はそれらの2つの追加の変数を渡しますが、最初にこれらの2つの新しい変数を保持するための適切な文字列を作成する方法と混乱しています。誰かが正しい方向に私を指すことができる場合、それは信じられないほど役に立つでしょう。ありがとうございました! 'NetworkServerController.cs'

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

public class ServerClient 
{ 
    public int connectionID; 
    public string playerName; 
    public Texture2D animalTex; 
    public string animalType; 
    public Vector3 position; 
} 

public class NetworkServerController : MonoBehaviour { 

    private const int MAX_CONNECTION = 10; 
    private int port = 5701; 

    private int hostID; 
    private int webHostID; 

    private string networkConnections; 

    private int reliableChannel; 
    private int unreliableChannel; 
    private int reliableFragChannel; 
    private int unreliableFragChannel; 

    private bool isStarted = false; 
    private byte error; 

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

    private float lastMovementUpdate; 
    private float movementUpdateRate = 0.2f; 

    // Onscreen Variables 
    private string connectText; 
    private string dataText; 
    private string clientID; 

    private void Awake() 
    { 
     NetworkServer.Reset(); 
    } 

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

     reliableChannel = cc.AddChannel(QosType.Reliable); 
     unreliableChannel = cc.AddChannel(QosType.Unreliable); 
     reliableFragChannel = cc.AddChannel(QosType.ReliableFragmented); 
     unreliableFragChannel = cc.AddChannel(QosType.UnreliableFragmented); 

     HostTopology topo = new HostTopology(cc, MAX_CONNECTION); 

     hostID = NetworkTransport.AddHost(topo, port); 
     Debug.Log("Socket Open. HostID is : " + hostID); 

     webHostID = NetworkTransport.AddWebsocketHost(topo, port); 
     Debug.Log("Socket Open. webHostID is : " + webHostID); 

     isStarted = true; 
    } 

    int connectionId; 

    private void Update() 
    { 
     if (!isStarted) 
     { 
      return; 
     } 
     else if (isStarted) 
     { 
      // Debug.Log("Server Started."); 

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

      // Network Messenger System 
      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("Receiving from " + connectionId + " : " + 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."); 
        OnDisconnection(connectionId); 
        break; 
      } 

      // Ask player for their position 
      if (Time.time - lastMovementUpdate > movementUpdateRate) 
      { 
       lastMovementUpdate = Time.time; 
       string m = "ASKPOSITION|"; 
       foreach (ServerClient sc in clients) 
        m += sc.connectionID.ToString() + '%' + sc.position.x.ToString() + '%' + sc.position.y.ToString() + '|'; 
       m = m.Trim('|'); 

       Send(m, unreliableChannel, clients); 
      } 
     }  
    } 

    private void OnConnection(int cnnID) 
    { 
     // Add player to list 
     ServerClient c = new ServerClient(); 
     c.connectionID = cnnID; 
     c.playerName = "TEMP"; 
     clients.Add(c); 

     // When player joins server, tell ID 
     // Request player name and send name of all the other players 
     string msg = "ASKNAME|" + cnnID + "|"; 
     foreach (ServerClient sc in clients) 
      msg += sc.playerName + '%' + sc.connectionID + "|"; 

     msg = msg.Trim('|'); 

     // ASKNAME|3|DAVE%1|MIKE%2|TEMP%3 

     Send(msg, reliableChannel, cnnID); 
    } 

    private void OnDisconnection(int cnnId) 
    { 
     // Remove this player from our client list 
     clients.Remove(clients.Find(x => x.connectionID == cnnId)); 

     // Tell everyone that someone has disconnected 
     Send("DC|" + cnnId, reliableChannel, clients); 
    } 

    private void OnNameIs(int cnnID, string playerName) 
    { 
     // Link name to connection ID 
     clients.Find(x => x.connectionID == cnnID).playerName = playerName; 

     // Tell everone that a new player has connected 
     Send("CNN|" + playerName + '|' + cnnID, reliableChannel, clients); 
    } 

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

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

    // overload method 
    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); 
     } 
    } 
} 

「はNetworkClientController'.cs

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

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

public class NetworkClientController : MonoBehaviour { 

    private const int MAX_CONNECTION = 10; 
    private int port = 5701; 
    private string IPAddress = "192.168.1.160"; 

    private int hostID; 
    private int webHostID; 

    private int reliableChannel; 
    private int unreliableChannel; 
    private int reliableFragChannel; 
    private int unreliableFragChannel; 

    private int ourClientID; 
    private int connectionID; 

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

    private string playerName; 

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

    private void Start() 
    { 
     // Connect(); 
    } 

    public void Connect() 
    { 
     // Check player name 
     string pName = GameObject.Find("NameInput").GetComponent<InputField>().text; 

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

     playerName = pName; 

     NetworkTransport.Init(); 
     ConnectionConfig cc = new ConnectionConfig(); 

     reliableChannel = cc.AddChannel(QosType.Reliable); 
     unreliableChannel = cc.AddChannel(QosType.Unreliable); 
     reliableFragChannel = cc.AddChannel(QosType.ReliableFragmented); 
     unreliableFragChannel = cc.AddChannel(QosType.UnreliableFragmented); 

     HostTopology topo = new HostTopology(cc, MAX_CONNECTION); 

     hostID = NetworkTransport.AddHost(topo, port); 
     connectionID = NetworkTransport.Connect(hostID, IPAddress, port, 0, out error); 

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

     // Network Messenger System 
     switch (recData) 
     { 
      case NetworkEventType.DataEvent:  //3 
       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 "ASKPOSITION": 
         OnAskPosition(splitData); 
         break; 

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

        case "DC": 
         PlayerDisconnected(int.Parse(splitData[1])); 
         break; 

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

    private void OnAskName(string[] data) 
    { 
     // Set local client ID 
     ourClientID = int.Parse(data[1]); 

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

     // Create all remote client 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 remote client positions 
     for (int i = 1; i < data.Length - 1; i++) 
     { 
      string[] d = data[i].Split('%'); 

      // Prevent the server from updating local client 
      if (ourClientID != int.Parse(d[0])) 
      { 
       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 local client position 
     Vector3 myPosition = players[ourClientID].avatar.transform.position; 
     string m = "MYPOSITION" + myPosition.x.ToString() + '|' + myPosition.y.ToString(); 
     Send(m, unreliableChannel); 
    } 

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

     // Is this ours? 
     if (cnnId == ourClientID) 
     { 
      // Add mobility 
      go.AddComponent<PlayerMovement>(); 

      // Remove Canvas 
      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; 
     p.animalTex = animalTex; 
     p.animalType = animalType; 
     players.Add(cnnId, p); 
    } 

    private void PlayerDisconnected(int cnnId) 
    { 
     Destroy(players[cnnId].avatar); 
     players.Remove(cnnId); 
    } 

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

こんにちは、あなたはチュートリアル言っへのリンクを提供することができますか? – Fiffe

+0

こんにちは@Fiffeチュートリアルへのリンク、https://www.youtube.com/watch?v=qGkkaNkq8co – greyBow

+0

ありがとう@greyBow – Fiffe

答えて

1

は単にこの、それを受信し、デシリアライズデータをシリアル化して送信します。あなたはまだ混乱している場合は、以下の手順に読んで:あなたの例では

を、あなたはTexture2Dを送りたいとstring

1次回ステップが表現することです:

は、送信側クラスまたは構造体で送信するデータ。

Texture2Dをこのクラスに直接追加したくない場合。バイト配列として格納する必要があります。この例では、Texture2D.GetRawTextureData()を使用しています。サイズを小さくするには、PNGまたはJPEGバイト配列に変換することもできます。

[Serializable] 
public class SendStructure 
{ 
    public byte[] texture; 
    public string message; 

    public SendStructure(Texture2D texture, string message) 
    { 
     this.texture = texture.GetRawTextureData(); 
     this.message = message; 
    } 
} 

.Serializeデータを送信する:データの

例を送信するために:

SendStructure sendStructure = new SendStructure(textureToSend, stringToSend); 

Texture2D textureToSend = new Texture2D(4, 4); 
string stringToSend = "Hello"; 

がにTexture2Dからsturctureと、文字列の新しいインスタンスを作成します。

メモリにシリアル化

MemoryStream memStream = new MemoryStream(); 
IFormatter formatter = new BinaryFormatter(); 
formatter.Serialize(memStream, sendStructure); 

//Array data to send over network 
byte[] serializedStructure = memStream.ToArray(); 

:ネットワーク

int outHostId; 
int outConnectionId; 
int outChannelId; 

int receivedSize; 
byte error; 

//Where to store received data 
byte[] buffer = new byte[400000]; 

NetworkEventType evt = NetworkTransport.Receive(out outHostId, out outConnectionId, out outChannelId, buffer, buffer.Length, out receivedSize, out error); 

.DE-シリアライズ受信データから

.Receive:受信側

NetworkTransport.Send(hostID, sc.connectionID, channelID, serializedStructure, serializedStructure.Length, out error); 

をネットワークに送ります210

switch (evt) { case NetworkEventType.DataEvent: { //De-Serialize recevied byte array into memory MemoryStream stream = new MemoryStream(buffer, 0, receivedSize); IFormatter formatter = new BinaryFormatter(); stream.Seek(0, SeekOrigin.Begin); //Received data now stored as SendStructure SendStructure receivedStructure = formatter.Deserialize(stream) as SendStructure; break; } } 

.accessのは、データを受け取っ:

stringを取得:

string receivedString = receivedStructure.message; 

Texture2Dを取得:

Texture2D receivedtexture = new Texture2D(4, 4); 
receivedtexture.LoadRawTextureData(receivedStructure.texture); 
receivedtexture.Apply(); 
関連する問題