我在Unity中有腳本,與另一個Python應用程序交換數據。它有一個while循環來偵聽UDP消息作爲後臺線程。此外,該腳本通過更新功能每幀請求新數據。Unity - 如何減少在更新和GC中花費的時間
當我收到一條消息後,腳本將其解析爲一個字符串,並且需要通過製表符來分割字符串以檢索所有值。目前,該字符串包含Unity作爲玩家輸入所需的眼球跟蹤器和遊戲杆數據。
UDPController.cs
private void init()
{
// define address to send data to
pythonEndPoint = new IPEndPoint(IPAddress.Parse(IP), pythonPort);
unityEndPoint = new IPEndPoint (IPAddress.Parse (IP), unityPort);
pythonSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//define client to receive data at
client = new UdpClient(unityPort);
client.Client.ReceiveTimeout = 1;
client.Client.SendTimeout = 1;
// start background thread to receive information
receiveThread = new Thread(new ThreadStart(ReceiveData));
receiveThread.IsBackground = true;
receiveThread.Start();
}
void Update(){
if (Calibration.calibrationFinished && startRequestNewFrame) {
RequestData();
}
}
private void RequestData() {
// Sends this to the UDP server written in Python
SendString("NEWFRAME");
}
// receive thread which listens for messages from Python UDP Server
private void ReceiveData()
{
while (true)
{
try
{
if(client.Available > 0) {
double unixRecvTimeStamp = DataManager.ConvertToUnixTimestamp(DateTime.Now);
byte[] data = client.Receive(ref pythonEndPoint);
string rawtext = Encoding.UTF8.GetString(data);
string[] msgs = rawtext.Split('\t');
string msgType = msgs[0];
double pythonSentTimeStamp = double.Parse(msgs[msgs.Length-1].Split(' ')[1]);
DataManager.UdpRecvBuffer += '"' + rawtext + '"' + "\t" + pythonSentTimeStamp + "\t" + unixRecvTimeStamp + "\t" + DataManager.ConvertToUnixTimestamp(DateTime.Now) + "\n";
if (String.Equals(msgType, "FRAMEDATA"))
{
DataManager.gazeAdcsPos = new Vector2(float.Parse(msgs[1].Split(' ')[1]), float.Parse(msgs[2].Split(' ')[1]));
float GazeTimeStamp = float.Parse(msgs[3].Split(' ')[1]);
DataManager.rawJoy = new Vector2(float.Parse(msgs[4].Split(' ')[1]), 255 - float.Parse(msgs[5].Split(' ')[1]));
float joyC = float.Parse(msgs[6].Split(' ')[1]);
float ArduinoTimeStamp = float.Parse(msgs[7].Split(' ')[1]);
}
}
}
catch (Exception err)
{
print(err.ToString());
}
}
}
所以根據統一探查,好像有一個巨大的行爲更新所花費的時間量,尤其是裏面UDPController.Update()和GC.Collect的。我最初的假設是,也許我創造了太多的字符串和數組超時,垃圾收集器經常踢,以刪除未使用的內存空間。
所以我的問題是,是我的假設嗎?如果是這樣,我如何重寫這段代碼來提高我的表現,並減少FPS和感知滯後的下降。如果不是,問題在哪裏,因爲目前遊戲開始滯後10分鐘左右。
此外,有沒有更好的數據傳輸方式或格式?看起來我可以使用JSON,Google Protocol Buffer或msgpack之類的對象,或者這會是一種矯枉過正的行爲?
如果你會跳過一些更新?你需要每幀還是每秒兩次就足夠了? – Everts
@Everts是的,我需要它的每一幀。基本上數據包含打開門和移動玩家的眼睛座標和操縱桿位置。 –