如何在Unity方法中使用UDP
我创建了一个Cube对象并附加了这个脚本。
using UnityEngine; using System.Collections; public class CubeMove : MonoBehaviour { void Start () { } void Update () { } public void Move () { Vector3 moveVector = new Vector3(10, 0, 0); transform.Translate(moveVector); } }
我想使用UDP来控制多维数据集移动,所以我创建了UDPManager。
using UnityEngine; using System.Collections; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; public class UDPManager : MonoBehaviour { static UdpClient udp; Thread thread; public GameObject cube; public CubeMove cubemove; void Start () { udp = new UdpClient(12345); cubemove = cube.GetComponent(); thread = new Thread(new ThreadStart(ThreadMethod)); thread.Start(); } void Update () { } void OnApplicationQuit() { udp.Close(); thread.Abort(); } private void ThreadMethod() { while(true) { IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); byte[] receiveBytes = udp.Receive(ref RemoteIpEndPoint); string returnData = Encoding.ASCII.GetString(receiveBytes); Debug.Log(returnData); if (returnData == "1\n") { cube.SendMessage ("Move"); // or cubemove.Move(); } } } }
但这些不适用于以下错误。
- SendMessage can only be called from the main thread. - get_transform can only be called from the main thread.
收到udp命令后,我可以调用unity方法吗?
您无法从另一个Thread调用Unity API。 如何在Unity中使用Thread:
1 。 启动线程
2 。 进程在该新线程中输入
3 。 告诉Unity您已完成处理。 您可以通过将全局boolean
变量设置为true
来完成此操作。 将output
数据存储在另一个全局变量中
4 。 检查Update()
函数中是否更改了boolean
变量。 如果确实如此,则设置为false
。 流程输出……
同时移动udp = new UdpClient(12345);
从Start
函数到ThreadMethod
函数。
static readonly object lockObject = new object(); string returnData = ""; bool precessData = false; void Start () { cubemove = cube.GetComponent(); thread = new Thread(new ThreadStart(ThreadMethod)); thread.Start(); } void Update() { if (precessData) { /*lock object to make sure there data is *not being accessed from multiple threads at thesame time*/ lock (lockObject) { precessData = false; cube.SendMessage("Move"); // or cubemove.Move(); //Process received data Debug.Log("Received: " + returnData); //Reset it for next read(OPTIONAL) returnData = ""; } } } private void ThreadMethod() { udp = new UdpClient(12345); while (true) { IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); byte[] receiveBytes = udp.Receive(ref RemoteIpEndPoint); /*lock object to make sure there data is *not being accessed from multiple threads at thesame time*/ lock (lockObject) { returnData = Encoding.ASCII.GetString(receiveBytes); Debug.Log(returnData); if (returnData == "1\n") { //Done, notify the Update function precessData = true; } } } }
using UnityEngine; using System.Net.Sockets; using System.Net; using System.Text; using System; public class UDPRT: ScriptableObject { static public string ReceivedMsg; // INPUT DATA static private UdpClient udpc; static IPEndPoint IP; static private object obj; static private AsyncCallback AC; static byte[] DATA; public static UDPRT CreateInstance(int Port) // RECEVE UDP { IP = new IPEndPoint(IPAddress.Any, Port); udpc = new UdpClient(Port); AC = new AsyncCallback(ReceiveIt); StartUdpReceive(); return ScriptableObject.CreateInstance < UDPRT > (); } public static UDPRT CreateInstance(int Port, string Host, string msg) // SEND UDP { udpc = new UdpClient(Host, Port); AC = new AsyncCallback(SendIt); byte[] data = Encoding.UTF8.GetBytes(msg); udpc.BeginSend(data, data.Length, AC, obj); return ScriptableObject.CreateInstance < UDPRT > (); } static void ReceiveIt(IAsyncResult result) { DATA = (udpc.EndReceive(result, ref IP)); Debug.Log(Encoding.UTF8.GetString(DATA)); ReceivedMsg = Encoding.UTF8.GetString(DATA); StartUdpReceive(); } static void SendIt(IAsyncResult result) { udpc.EndSend(result); } static void StartUdpReceive() { udpc.BeginReceive(AC, obj); } }