I have an application within Unity3D (acting as a server) that receives messages from an exterior application (single client) with the following structure:
number(float) number(float) number(float)
The first two numbers represent the local position (x,z axis) and the last one a rotation value (y axis).
The goal is to use this data to update the Camera gameobject position (using the LoadPositions method) within the game scene. From what I've read manipulating gameobjects while outside Unity's main thread is not possible.
With that being said how can I change from and to Unity main thread so that I can both listen for messages and update the gameobjects position. Also, anyone happens to know of a working example of a simple TCP Server in Unity without having to resort to threads?
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());
}
}
}