我需要一副新鲜的眼睛来帮助解决我收到的解析错误。在整个网络中更新玩家移动期间会出现此问题。我得到的错误是:
FormatException: Unknown char: %
System.Double.Parse (System.String s, NumberStyles style, IFormatProvider provider) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Double.cs:209)
System.Single.Parse (System.String s) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Single.cs:183)
Server.Update () (at Assets/Scripts/Server.cs:85)
我认为错误源自Client.cs中的OnAskPosition()
,但我没有使用%来解析该字符串。
我正在调试进入服务器的所有邮件,并且当服务器收到MYPOSITION时发生错误:
Player 1 has sent : MYPOSITION|0%-0.003983478
UnityEngine.Debug:Log(Object)
Server:Update() (at Assets/Scripts/Server.cs:74)
我的位置不应该包含%符号,它应该只是一个x和y浮点数。我无法弄清楚流氓%来自哪里,真的很感激任何帮助来追踪这个问题。谢谢!
Client.cs
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
public class Player
{
public string playerName;
public GameObject avatar;
public int connectionId;
}
public class Client : MonoBehaviour {
public Dictionary<int, Player> players = new Dictionary<int, Player>();
public GameObject playerPrefab;
private const int MAX_CONNECTION = 100;
private string serverIP = "127.0.0.1";
private int port = 5701;
private int hostId;
private int webHostId;
private int reliableChannel;
private int unreliableChannel;
private int ourClientId;
private string playerName;
private int connectionId;
private float connectionTime;
private bool isStarted = false;
private bool isConnected = false;
private byte error;
private string GetPlayerName()
{
switch (Network.player.ipAddress.ToString())
{
case "192.168.1.160":
playerName = "SMO Server";
break;
case "192.168.1.161":
playerName = "SMO Client 1";
break;
case "192.168.1.162":
playerName = "SMO Client 2";
break;
case "192.168.1.163":
playerName = "SMO Client 3";
break;
case "192.168.1.164":
playerName = "SMO Client 4";
break;
default:
playerName = "SMO UNREG";
break;
}
return playerName;
}
public void Connect()
{
string pName = GetPlayerName();
if (pName == "")
return;
playerName = pName;
NetworkTransport.Init();
ConnectionConfig cc = new ConnectionConfig();
reliableChannel = cc.AddChannel(QosType.ReliableSequenced);
unreliableChannel = cc.AddChannel(QosType.UnreliableSequenced);
HostTopology topo = new HostTopology(cc, MAX_CONNECTION);
// Run client/server locally for testing
hostId = NetworkTransport.AddHost(topo, 0);
// Run client/server on different machines
//hostID = NetworkTransport.AddHost(topo, port, null);
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:
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 client ID
ourClientId = int.Parse(data[1]);
// Send our name to the server
Send("NAMEIS|" + playerName, reliableChannel);
Debug.Log("The player name sent to server is : " + playerName);
// 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 all other players
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;
position.x = float.Parse(d[1]);
position.y = float.Parse(d[2]);
players[int.Parse(d[0])].avatar.transform.position = position;
}
}
// Send our own position
Vector3 myPosition = players[ourClientId].avatar.transform.position;
string moveMsg = "MYPOSIION|" + myPosition.x.ToString() + '|' + myPosition.y.ToString();
Send(moveMsg, unreliableChannel);
}
private void SpawnPlayer(string pName, int cnnId)
{
GameObject go = Instantiate(playerPrefab) as GameObject;
// Is this our player?
if (cnnId == ourClientId)
{
// Add mobility
go.AddComponent<Movement>();
// Remove Canvas
if(GameObject.Find("Canvas").activeInHierarchy == true)
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 = pName;
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, msg.Length * sizeof(char), out error);
}
}
Server.cs
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
// Define the definition of a client on the server
public class ServerClient
{
public int connectionId;
public string playerName;
public Vector3 playerPosition;
}
public class Server : MonoBehaviour {
private const int MAX_CONNECTION = 100;
private int port = 5701;
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 float lastMovementUpdate;
private float movementUpdateRate = 0.1f;
private void Start()
{
NetworkTransport.Init();
ConnectionConfig cc = new ConnectionConfig();
reliableChannel = cc.AddChannel(QosType.ReliableSequenced);
unreliableChannel = cc.AddChannel(QosType.UnreliableSequenced);
HostTopology topo = new HostTopology(cc, MAX_CONNECTION);
hostId = 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.ConnectEvent:
Debug.Log("Player " + connectionId + " has connected");
OnConnection(connectionId);
break;
case NetworkEventType.DataEvent:
string msg = Encoding.Unicode.GetString(recBuffer, 0, dataSize);
Debug.Log("Player " + 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:
Debug.Log("Player " + connectionId + " has disconnected");
OnDisconnection(connectionId);
break;
}
// Ask player for their position
if (Time.time - lastMovementUpdate > movementUpdateRate)
{
lastMovementUpdate = Time.time;
string moveMsg = "ASKPOSITION|";
foreach (ServerClient sc in clients)
moveMsg += sc.connectionId.ToString() + '%' + sc.playerPosition.x.ToString() + '%' + sc.playerPosition.y.ToString() + '|';
moveMsg = moveMsg.Trim('|');
Send(moveMsg, unreliableChannel, clients);
}
}
private void OnConnection(int cnnId)
{
// Add him to a list
ServerClient c = new ServerClient();
c.connectionId = cnnId;
c.playerName = "TEMP";
clients.Add(c);
// When player joins server, tell player id, request name and send name to other players
string msg = "ASKNAME|" + cnnId + "|";
foreach (ServerClient sc in clients)
{
msg += sc.playerName + '%' + sc.connectionId + '|';
}
msg = msg.Trim('|');
Send(msg, reliableChannel, cnnId);
}
private void OnDisconnection(int cnnId)
{
// Remove this player from client list
clients.Remove(clients.Find(x => x.connectionId == cnnId));
// Tell all clients that a player has disconnected
Send("DC|" + cnnId, reliableChannel, clients);
}
private void OnNameIs(int cnnId, string pName)
{
// Link the name to the connection ID
clients.Find(x => x.connectionId == cnnId).playerName = pName;
// Tell everybody that a new player has connected
Send("CNN|" + pName + '|' + cnnId, reliableChannel, clients);
}
private void OnMyPosition(int cnnId, float x, float y)
{
clients.Find(c => c.connectionId == cnnId).playerPosition = new Vector3(x, y, 0);
}
private void Send(string message, int channelId, int cnnId) // send to one player
{
List<ServerClient> c = new List<ServerClient>();
c.Add(clients.Find(x => x.connectionId == cnnId)); // target only one user based on connectionID
Send(message, channelId, c);
}
private void Send(string message, int channelId, List<ServerClient> c) // send to all players
{
Debug.Log("Sending : " + message);
byte[] msg = Encoding.Unicode.GetBytes(message);
foreach (ServerClient sc in c)
{
NetworkTransport.Send(hostId, sc.connectionId, channelId, msg, msg.Length * sizeof(char), out error);
}
}
}
答案 0 :(得分:1)
它在float.parse
上崩溃了OnMyPosition(connectionId, float.Parse(splitData[1]), float.Parse(splitData[2]));
你可以:
1)打印出splitData的所有内容,看看为什么没有解析。
2)将它包装在try / catch
中3)使用TryParse