我嘗試將Unity中的簡單模擬環境與基於神經網絡的python控制器連接起來。模擬Unity環境中的主要角色應該根據它的經驗學習一種行爲:爲了試點研究的目的,通過TCP連接Unity的模擬與python控制器
- 主要字符掃描環境並將其存儲在數據結構中;
- 此數據結構通過TCP發送到python中的正在運行的服務器;
- 一個複雜的計算(基於從Unity接收到的數據)是在python中執行的,它產生一個結果(action);
- 結果(動作)通過TCP發送回Unity。角色執行與結果相對應的動作。
- 重複步驟1-4直到無限(除非客戶端或服務器停止)。
這個過程可以抽象爲通過TCP發送的乒乓信息,其中Unity發送一個「Ping」,Python進行一些計算併產生一個「Pong」,它將被髮送回Unity,從而更新模擬並再次產生一個「平」,並將其發送到python ...
我目前在一個玩具項目中測試這個過程。我有連接到主攝像頭的團結場景腳本,看起來像這樣:
using UnityEngine;
using System.Collections;
using System;
using System.IO;
using System.Net.Sockets;
using Newtonsoft.Json;
using System.Threading;
public class networkSocketSO : MonoBehaviour
{
public String host = "localhost";
public Int32 port = 50000;
internal Boolean socket_ready = false;
internal String input_buffer = "";
TcpClient tcp_socket;
NetworkStream net_stream;
StreamWriter socket_writer;
StreamReader socket_reader;
private void Start()
{
setupSocket();
}
void Update()
{
string received_data = readSocket();
switch (received_data)
{
case "pong":
Debug.Log("Python controller sent: " + (string)received_data);
writeSocket("ping");
break;
default:
Debug.Log("Nothing received");
break;
}
}
void OnApplicationQuit()
{
closeSocket();
}
// Helper methods for:
//...setting up the communication
public void setupSocket()
{
try
{
tcp_socket = new TcpClient(host, port);
net_stream = tcp_socket.GetStream();
socket_writer = new StreamWriter(net_stream);
socket_reader = new StreamReader(net_stream);
socket_ready = true;
}
catch (Exception e)
{
// Something went wrong
Debug.Log("Socket error: " + e);
}
}
//... writing to a socket...
public void writeSocket(string line)
{
if (!socket_ready)
return;
line = line + "\r\n";
socket_writer.Write(line);
socket_writer.Flush();
}
//... reading from a socket...
public String readSocket()
{
if (!socket_ready)
return "";
if (net_stream.DataAvailable)
return socket_reader.ReadLine();
return "";
}
//... closing a socket...
public void closeSocket()
{
if (!socket_ready)
return;
socket_writer.Close();
socket_reader.Close();
tcp_socket.Close();
socket_ready = false;
}
}
並用下面的代碼蟒蛇服務器:
import socket
import json
host = 'localhost'
port = 50000
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
while 1:
client, address = s.accept()
print "Client connected."
while 1:
data = client.recv(size)
if data == "ping":
print ("Unity Sent: " + str(data))
client.send("pong")
else:
client.send("Bye!")
print ("Unity Sent Something Else: " + str(data))
client.close()
break
如果我啓動服務器,然後運行團結項目我得到奇怪的事情。也就是說,python服務器似乎並不理解Unity客戶端發送的「ping」字符串。此外,我希望Unity模擬中的幀在它從python服務器收到「Pong」消息之前不要更新。
我已經閱讀過有關使用協程或線程的類似問題的解決方案,但我擔心它會建立另一個「時鐘」,並導致沒有真正的乒乓更新幀乒乓更新過程。
任何想法?
在此先感謝!
P.S.請記住,真正的消息不會是「Ping」和「Pong」,而是適當的Json對象。這只是一個簡化。
編輯: 我首先啓動python服務器,然後啓動Unity模擬(在編輯器中)。 蟒控制檯我得到:
Client connected.
Unity Sent Something Else: ping
...這證明我的要求是 「蟒蛇不明白通過Unity(C#)發送字符串」
在統一的控制檯,我得到:
這是一個以上的問題。對於第一個:python服務器是否收到任何東西?你的程序打印什麼? – Dschoni
你能告訴我們當前的代碼會發生什麼嗎? – Programmer
我剛剛用python打印和Unity控制檯日誌編輯了原始問題。並且...感謝回覆的人。 – thecritter