2017-06-21 47 views
0

我使用的是統一的5.5。unity3d - 無法在UNET上傳輸旋轉

這是我的代碼。

Client.cs:

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

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


public class Client : MonoBehaviour 
{ 

    private const int MAX_CONNECTION = 100; 

    private string ServerIp = "127.0.0.1"; 

    private int port = 5701; 
    private int hostId; 

    private int ourClientId; 

    private int reliableChannel; 
    private int unreliableChannel; 

    private int connectionId; 

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

    private string PlayerName; 


    public GameObject characterPrefab; 
    public Dictionary<int,Player> Players = new Dictionary<int, Player>(); 

    private byte error; 

    public void Connect() 
    { 
     // Does the player have a name ? 

     string pName = GameObject.Find("NameInput").GetComponent<InputField>().text; 

     if(PlayerName == "") 
     { 
      Debug.Log("You must write you 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,ServerIp,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); 
     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 "ASKPLAYERNAME": 
         OnAskName(splitData); 
        break; 

        case "CNN": 
         SpawnPlayer(splitData[1],int.Parse(splitData[2])); 
         break; 
        case "DC": 
         CharacterDisconnected(int.Parse(splitData[1])); 
         break; 
        case "ASKCHARACTERPOSITION": 
         OnAskPosition(splitData); 
         break; 
        default: 
         Debug.Log("Invalid Client meesage : " + msg); 
         break; 

       } 

       break; 

     } 
    } 

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

     //Send our name to the server. 

     Send("PLAYERNAME|" + 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 position; 
     for (int i = 1; i <= data.Length - 1; i++) 
     { 
      string[] d = data[i].Split('%'); 
      //Prevent the server from updating us. 
      if (ourClientId != int.Parse(d[0])) 
      { 
       Vector3 position = Vector3.zero; 
       Quaternion rotation = Quaternion.Euler(float.Parse(d[4]), float.Parse(d[5]), float.Parse(d[6])); 
       position.x = float.Parse(d[1]); 
       position.y = float.Parse(d[2]); 
       position.z = float.Parse(d[3]); 
       Players[int.Parse(d[0])].avatar.transform.position = position; 
       //Debug.Log("My position" + transform.position + "- Going to:" + position); 
       Players[int.Parse(d[0])].avatar.transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 10); 
      } 


     } 
     //Send our own position; 
     Vector3 myPosition = Players[ourClientId].avatar.transform.position; //Taking my position. 
     Quaternion myRotation = Players[ourClientId].avatar.transform.rotation; //Taking my rotaion. 
     Debug.Log("Character rotation:" + myRotation); 
     string m = "CHARACTERPOSITION|" + myPosition.x.ToString() + '|' + myPosition.y.ToString() + '|' + myPosition.z.ToString() + '|' + myRotation.x.ToString() + '|' + myRotation.y.ToString() + '|' + myRotation.z.ToString(); 
     Send(m, unreliableChannel); 


    } 

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

     // Is this ours? 
     if(cnnid == ourClientId) 
     { 
      // Add mobility. 
      go.AddComponent<CharacterMovement>(); 
      go.AddComponent<Character>(); 
      // 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; 
     Players.Add(cnnid,p); 

    } 

    private void CharacterDisconnected(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); 

    } 
} 

這裏是我的Server.cs:

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

public class ServerClient 
{ 
    public int connectionId; 
    public string playerName; 
    public Vector3 playerPosition; 
    public Quaternion playerRotation; 
} 

public class Server : MonoBehaviour 
{ 
    private const int MAX_CONNECTION = 100; 

    private int port = 5701; 
    private int hostId; 

    private int reliableChannel; 
    private int unreliableChannel; 

    private bool isStarted = false; 
    private byte error; 

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

    private float lastMovementUpdate; 
    private float movementUpdateRate = 0.05f; 

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

     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("Receiving from " + connectionId + " has sent : " + msg); 
       string[] splitData = msg.Split('|'); 

       switch (splitData[0]) 
       { 
        case "PLAYERNAME": 
         OnPlayerName(connectionId, splitData[1]); 
         break; 
        case "CHARACTERPOSITION": 
         OnCharacterPosition(connectionId, float.Parse(splitData[1]), float.Parse(splitData[2]), float.Parse(splitData[3]), float.Parse(splitData[4]), float.Parse(splitData[5]), float.Parse(splitData[6])); 
         break; 
        default: 
         Debug.Log("Invalid Server meesage : " + msg); 
         break; 

       } 

       break; 

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

     //Ask player for position. 
     if(Time.time - lastMovementUpdate > movementUpdateRate) 
     { 
      lastMovementUpdate = Time.time; 
      string m = "ASKCHARACTERPOSITION|"; 

      foreach (ServerClient sc in clients) 
      { 
       m += sc.connectionId.ToString() + '%' + sc.playerPosition.x.ToString() + '%' + sc.playerPosition.y.ToString() + '%' + sc.playerPosition.z.ToString() + '%' + sc.playerRotation.x.ToString() + '%' + sc.playerRotation.y.ToString() + '%' + sc.playerRotation.z.ToString() + '|'; 
      } 
      m = m.Trim('|'); 
      Send(m, unreliableChannel, clients); 
     } 
    } 
    private void OnConnection(int cnnId) 
    { 
     // Add him to online list 
     ServerClient c = new ServerClient(); 
     c.connectionId = cnnId; 
     c.playerName = "TEMP"; 
     clients.Add(c); 


     // Assing player id 

     // Request player name and send to all players 

     string msg = "ASKPLAYERNAME|" + cnnId + "|"; 
     foreach (ServerClient sc in clients) 
     { 
      msg += sc.playerName + '%' + sc.connectionId + '|'; 
     } 
      msg = msg.Trim('|'); 
      Send(msg, reliableChannel, cnnId); 


    } 
    private void OnDisconnection(int cnnId) 
    { 
     // Remove player from our client list 
     clients.Remove(clients.Find(x => x.connectionId == cnnId)); 
     //Tell everyone somebody dissconnected 
     Send("DC|" + cnnId, reliableChannel, clients); 
    } 
    private void OnPlayerName(int cnnId, string playerName) 
    { 
     // Ling the name to the connection id. 
     clients.Find(x => x.connectionId == cnnId).playerName = playerName; 
     // Tell everybody new player has connected. 
     Send("CNN|" + playerName + '|' + cnnId, reliableChannel, clients); 
    } 
    private void OnCharacterPosition(int cnnId, float x, float y, float z, float rx, float ry, float rz) 
    { 
     Quaternion characterRotation = Quaternion.Euler(rx,ry,rz); 
     Debug.Log("Character rotation: " + characterRotation); 
     clients.Find(c => c.connectionId == cnnId).playerPosition = new Vector3(x, y, z); 
     //clients.Find(c => c.connectionId == cnnId).playerRotation = Quaternion.Euler(new Vector3(0, 30, 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); 
     } 
    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); 
      } 
     } 

    } 

這裏是我的CharacterMovement.cs:

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

public class CharacterMovement : MonoBehaviour 
{ 
    private CharacterController controller; 
    private float verticalVelocity; 

    private void Start() 
    { 
     controller = GetComponent<CharacterController>(); 


    } 

    private void Update() 
    { 
     //inputs = location variable 
     Vector3 location = Vector3.zero; 

     location.x = Input.GetAxis("Horizontal"); 

     if (controller.isGrounded) 
     { 
      verticalVelocity = -1; 
      if (Input.GetButton("Jump")) 
      { 
       verticalVelocity = 10; 
      } 

      if (Input.GetKey(KeyCode.W)) 
      { 
       transform.position += transform.forward * Time.deltaTime * CharacterGlobals.CharacterMovementSpeed; 
       Debug.Log("Location: " + transform.position); 
       //Debug.Log("Character speed is: " + CharacterGlobals.CharacterMovementSpeed); 
      } 

      if (Input.GetKey(KeyCode.S)) 
      { 
       transform.position -= transform.forward * Time.deltaTime * CharacterGlobals.CharacterMovementSpeed; 
       // Decrease character speed by - CharacterGlobals.CharacterMovementSpeed -= 1; 
       Debug.Log("Location: " + transform.position); 
      } 

      if (Input.GetKey(KeyCode.A)) 
      { 
       transform.Rotate(0, -3, 0); 
      } 

      if (Input.GetKey(KeyCode.D)) 
      { 
       transform.Rotate(0, 3, 0); 
      } 
     } 
     else 
     { 
      verticalVelocity -= 14.0f * Time.deltaTime; 
     } 

     location.y = verticalVelocity; 

     controller.Move(location * Time.deltaTime); 
    } 
} 

我創建了一個成功multyplayer連接。當字符登錄產生,當它移動時,位置同步良好。所以我能夠更新字符位置,但我無法更新字符旋轉。 我在按下按鈕AD上綁定了角色的旋轉。有上的字符1沒有問題的旋轉,但你不能看到字符2.

的旋轉,我希望我已經解釋了我的問題不夠好。我的錯誤在哪裏? 爲什麼角色位置不更新?

回答

1

一眼就看到你並沒有真正設置Quaternion服務器端。

private void OnCharacterPosition(int cnnId, float x, float y, float z, float rx, float ry, float rz) 
{ 
    Quaternion characterRotation = Quaternion.Euler(rx,ry,rz); 
    Debug.Log("Character rotation: " + characterRotation); 
    clients.Find(c => c.connectionId == cnnId).playerPosition = new Vector3(x, y, z); 
    //clients.Find(c => c.connectionId == cnnId).playerRotation = Quaternion.Euler(new Vector3(0, 30, 0)); 
} 

嘗試在底部取消註釋您的行並將其替換爲您創建的characterRotation四元數。

private void OnCharacterPosition(int cnnId, float x, float y, float z, float rx, float ry, float rz) 
    { 
     Quaternion characterRotation = Quaternion.Euler(rx,ry,rz); 
     clients.Find(c => c.connectionId == cnnId).playerPosition = new Vector3(x, y, z); 
     clients.Find(c => c.connectionId == cnnId).playerRotation = characterRotation; 
    } 

這可能會解決這一問題,但我強烈建議您嘗試潛入網絡之前更好地瞭解統一。從你編寫的代碼中可以看到很多證據表明你對Unity非常陌生(例如,在Update()中旋轉而沒有通過類似Time.deltaTime的東西來增加值,這意味着你的角色移動是幀速率依賴的,一個經典的菜鳥錯誤)。

+0

感謝您的回答和建議,但問題仍然是一樣的。輪換沒有更新。 –