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連接。當字符登錄產生,當它移動時,位置同步良好。所以我能夠更新字符位置,但我無法更新字符旋轉。 我在按下按鈕A
和D
上綁定了角色的旋轉。有上的字符1沒有問題的旋轉,但你不能看到字符2.
的旋轉,我希望我已經解釋了我的問題不夠好。我的錯誤在哪裏? 爲什麼角色位置不更新?
感謝您的回答和建議,但問題仍然是一樣的。輪換沒有更新。 –