Multithreading Unity3D线程和游戏对象
我在Unity3D中有一个应用程序(充当服务器),它接收来自外部应用程序(单个客户端)的消息,其结构如下: 数字(浮动)数字(浮动)数字(浮动) 前两个数字表示局部位置(x、z轴),最后一个数字表示旋转值(y轴) 目标是使用此数据更新游戏场景中的摄影机游戏对象位置(使用LoadPositions方法)。从我所读到的内容来看,在Unity的主线程之外操纵游戏对象是不可能的 说到这里,我怎样才能从Unity主线程和切换到Unity主线程,这样我就可以同时监听消息和更新游戏对象的位置。 另外,有谁知道Unity中一个简单TCP服务器的工作示例,而不必求助于线程Multithreading Unity3D线程和游戏对象,multithreading,unity3d,gameobject,Multithreading,Unity3d,Gameobject,我在Unity3D中有一个应用程序(充当服务器),它接收来自外部应用程序(单个客户端)的消息,其结构如下: 数字(浮动)数字(浮动)数字(浮动) 前两个数字表示局部位置(x、z轴),最后一个数字表示旋转值(y轴) 目标是使用此数据更新游戏场景中的摄影机游戏对象位置(使用LoadPositions方法)。从我所读到的内容来看,在Unity的主线程之外操纵游戏对象是不可能的 说到这里,我怎样才能从Unity主线程和切换到Unity主线程,这样我就可以同时监听消息和更新游戏对象的位置。 另外,有谁知道
using UnityEngine;
using System.Collections;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System;
using System.Text;
using System.Collections.Generic;
public class ProxyThreadServer : MonoBehaviour {
float x;
float z;
float rot;
Vector3 updatePos;
Vector3 updateRot;
string ip_address = "127.0.0.1";
string msgReceived;
string[] words;
int wordsNum;
int port = 8000;
int numSurf;
int jumpInterval;
Thread listen_thread;
TcpListener tcp_listener;
Thread clientThread;
TcpClient tcp_client;
bool isTrue = true;
// Use this for initialization
void Start ()
{
IPAddress ip_addy = IPAddress.Parse(ip_address);
tcp_listener = new TcpListener(ip_addy, port);
listen_thread = new Thread(new ThreadStart(ListenForClients));
listen_thread.Start();
}
private void ListenForClients()
{
this.tcp_listener.Start();
while(isTrue == true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcp_listener.AcceptTcpClient();
//create a thread to handle communication
//with connected client
clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
Debug.Log("Got client " + client);
}
}
private void HandleClientComm(object client)
{
tcp_client = (TcpClient)client;
NetworkStream client_stream = tcp_client.GetStream();
byte[] message = new byte[4096];
int bytes_read;
while(isTrue == true)
{
bytes_read = 0;
try
{
//blocks until a client sends a message
bytes_read = client_stream.Read(message, 0, 4096);
//Debug.Log(message);
}
catch (Exception e)
{
//a socket error has occurred
Debug.Log(e.Message);
break;
}
if(bytes_read == 0)
{
//client has disconnected
Debug.Log("Disconnected");
tcp_client.Close();
break;
}
ASCIIEncoding encoder = new ASCIIEncoding();
Debug.Log(encoder.GetString(message,0,bytes_read));
msgReceived = encoder.GetString(message,0,bytes_read);
LoadPositions(msgReceived);
}
if(isTrue == false)
{
tcp_client.Close();
Debug.Log("closing tcp client");
}
}
void OnApplicationQuit()
{
try
{
tcp_client.Close();
isTrue = false;
}
catch(Exception e)
{
Debug.Log(e.Message);
}
// You must close the tcp listener
try
{
tcp_listener.Stop();
isTrue = false;
}
catch(Exception e)
{
Debug.Log(e.Message);
}
}
void LoadPositions(string positions){
// Split string on spaces. This will separate all the words.
words = positions.Split(' ');
wordsNum = words.Length;
for (int i = 0; i <= wordsNum; i++) {
x = float.Parse(words[0], System.Globalization.CultureInfo.InvariantCulture);
z = float.Parse(words[1], System.Globalization.CultureInfo.InvariantCulture);
rot = float.Parse(words[2], System.Globalization.CultureInfo.InvariantCulture);
Debug.Log("Reading position: " + "x: " + x + " z: " + z + " yRot: " + rot);
updatePos = new Vector3(x, this.gameObject.transform.position.y, z);
this.gameObject.transform.position = updatePos;
updateRot = new Vector3(this.gameObject.transform.rotation.x, rot / 4, this.gameObject.transform.rotation.z);
this.transform.localEulerAngles = updateRot;
//UpdateCameraMatrix();
//StartCoroutine(UpdateSurfs());
}
}
}
使用UnityEngine;
使用系统集合;
使用System.Net.Sockets;
使用系统线程;
Net系统;
使用制度;
使用系统文本;
使用System.Collections.Generic;
公共类ProxyThreadServer:MonoBehavior{
浮动x;
浮动z;
漂浮腐烂;
矢量3更新;
矢量3更新;
字符串ip_address=“127.0.0.1”;
字符串msgReceived;
字符串[]个单词;
int-wordsNum;
int端口=8000;
国际努姆苏尔夫;
int跳跃间隔;
线听线;
TcpListener-tcp\u侦听器;
线程clientThread;
TcpClient tcp_客户端;
bool isTrue=真;
//用于初始化
无效开始()
{
IPAddress ip_addy=IPAddress.Parse(ip_地址);
tcp_侦听器=新的TcpListener(ip_地址,端口);
listen_thread=新线程(新线程开始(ListenForClients));
听一听;
}
私有void listenforcients()
{
这个.tcp_listener.Start();
while(isTrue==true)
{
//阻止,直到客户端连接到服务器
TcpClient client=this.tcp_listener.AcceptTcpClient();
//创建一个线程来处理通信
//使用连接的客户端
clientThread=新线程(新的参数化ThreadStart(HandleClientCommand));
clientThread.Start(客户端);
Log(“获得客户机”+客户机);
}
}
私有void HandleClientCommand(对象客户端)
{
tcp_客户端=(TcpClient)客户端;
NetworkStream client_stream=tcp_client.GetStream();
字节[]消息=新字节[4096];
读取整数字节;
while(isTrue==true)
{
字节读取=0;
尝试
{
//阻塞,直到客户端发送消息
bytes\u read=客户端\u stream.read(消息,04096);
//Debug.Log(消息);
}
捕获(例外e)
{
//发生套接字错误
Debug.Log(e.Message);
打破
}
如果(字节数_读取==0)
{
//客户端已断开连接
Debug.Log(“断开”);
tcp_client.Close();
打破
}
ascienceoding编码器=新的ascienceoding();
Log(encoder.GetString(消息,0,字节读取));
msgReceived=encoder.GetString(消息,0,字节\读取);
装载位置(msgReceived);
}
if(isTrue==false)
{
tcp_client.Close();
Log(“关闭tcp客户端”);
}
}
在Application Quit()上无效
{
尝试
{
tcp_client.Close();
isTrue=假;
}
捕获(例外e)
{
Debug.Log(e.Message);
}
//您必须关闭tcp侦听器
尝试
{
tcp_listener.Stop();
isTrue=假;
}
捕获(例外e)
{
Debug.Log(e.Message);
}
}
无效加载位置(字符串位置){
//拆分空格上的字符串。这将分隔所有单词。
单词=位置。拆分(“”);
wordsNum=单词长度;
对于(int i=0;i虽然我以前没有尝试过这样做,但假设您提到的限制确实存在,我的方法是使用队列来存储消息,然后按照消息在unity线程中的顺序处理它们。因此,与其调用LoadPositions,不如将其添加到
然后在更新方法中处理它:
void Update()
{
while (pendingMessages.Count() > 0)
LoadPositions(pendingMessages.Dequeue());
}
您可以使用.NET的异步TCP。它基于回调委托。(使用它有点棘手)最终完成了与您描述的类似的操作。感谢您的反馈!
void Update()
{
while (pendingMessages.Count() > 0)
LoadPositions(pendingMessages.Dequeue());
}