Unity3D线程和GameObjects

用户名

我在Unity3D中有一个应用程序(充当服务器),该应用程序从外部应用程序(单个客户端)接收具有以下结构的消息:

数字(浮点数)数字(浮点数)数字(浮点数)

前两个数字代表局部位置(x,z轴),最后一个数字代表旋转值(y轴)。

目标是使用此数据来更新游戏场景中“摄影机”游戏对象的位置(使用LoadPositions方法)。根据我的阅读,在Unity主线程之外无法操纵游戏对象是不可能的。

话虽如此,我该如何在Unity主线程之间来回切换,以便既可以侦听消息,又可以更新游戏对象的位置。另外,有人偶然知道Unity中简单TCP Server的工作示例,而不必求助于线程吗?

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());
        }
   }

}
甲酸

尽管我以前从未尝试做过类似的事情,但假设确实存在您所提到的限制,但我的方法是使用队列存储消息,然后按照它们在统一线程中输入的顺序对其进行处理。因此,与其在调用LoadPositions时将其添加到队列中,不如将其添加到队列中

pendingMessages.Enqueue(msgReceived);

然后在更新方法中对其进行处理:

void Update()
{
    while (pendingMessages.Count() > 0)
        LoadPositions(pendingMessages.Dequeue());
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章