首先,您必须实现此类,以在Unity的UI线程上调用方法.实施此操作时,只需创建一个类:public class CommunicationManager{ static readonly object syncRoot = new object(); static CommunicationManager _Instance; public static CommunicationManager Instance { get { if ( _Instance == null ) { lock ( syncRoot ) { if ( _Instance == null ) { _Instance = new CommunicationManager(); } } } return _Instance; } } volatile bool working = false; Queue<Message> _messages; private CommunicationManager() { _messages = new Queue<Message>(); InitializeCommunication(); } void InitializeCommunication() { Thread t = new Thread(CommunicationLoop); t.Start(); } void CommunicationLoop() { Socket s = null; try { Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); s.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1337)); working = true; } catch(Exception ex) { working = false; } while ( working ) { lock ( syncRoot ) { while ( _messages.Count > 0 ) { Message message = _messages.Dequeue(); MessageResult result = message.Process(s); result.Notify(); } } Thread.Sleep(100); } } public void EnqueueMessage(Message message) { lock ( syncRoot ) { _messages.Enqueue( message ); } }}现在您必须制作Message和MessageResult对象:public class Message{ const string REQUEST_SCHEME = "{0} {1} HTTP/1.1\r\nHost: {hostname}\r\nContent-Length: 0\r\n\r\n"; string request; Action<MessageResult> whenCompleted; public Message(string requestUri, string requestType, Action<MessageResult> whenCompleted) { request = string.Format(REQUEST_SCHEME, requestType, requestUri); this.whenCompleted = whenCompleted; } public MessageResult Process(Socket s) { IPEndPoint endPoint = (IPEndPoint)s.RemoteEndPoint; IPAddress ipAddress = endPoint.Address; request = request.Replace("{hostname}", ipAddress.ToString()); s.Send(Encoding.UTF8.GetBytes(request)); // receive header here which should look somewhat like this : /* HTTP/1.1 <status> Date: <date> <some additional info> Accept-Ranges: bytes Content-Length: <CONTENT_LENGTH> <some additional info> Content-Type: <content mime type> */ // when you receive this all that matters is <CONTENT_LENGTH> int contentLength = <CONTENT_LENGTH>; byte[] msgBuffer = new byte[contentLength]; if (s.Receive(msgBuffer) != contentLength ) { return null; } return new MessageResult(msgBuffer, whenCompleted); }}最后创建MessageResult对象:public class MessageResult{ Action<MessageResult> notifier; byte[] messageBuffer; public MessageResult(byte[] message, Action<MessageResult> notifier) { notifier = notifier; messageBuffer = message; } public void Notify() { UnityThread.executeInUpdate(() => { notifier(this); }); }}此方法将在您的主应用程序之外运行,这样就不会产生任何冻结和其他任何情况.要使用此功能,您只需调用类似这样的内容即可:Message message = new Message("/index.html", "GET", IndexDownloaded);CommunicationManager.Instance.EnqueueMessage(message);// ...public void IndexDownloaded(MessageResult result){ // result available here}有关更多信息,请阅读这篇关于HTTP的维基百科文章.Is there a way to have a simple webserver send messages to Unity? At the moment, we're doing a GET using UnityWebRequest.Get() in the update method. Here's the code:// Update is called once per framevoid Update () { StartCoroutine(GetData());}IEnumerator GetData(){ UnityWebRequest uwr = UnityWebRequest.Get(url); yield return uwr.Send(); if (uwr.isError) { Debug.Log(uwr.error); }else { Debug.Log((float.Parse(uwr.downloadHandler.text) / 100)); fnumber = ((float.Parse(uwr.downloadHandler.text) / 100)); transform.position.Set(oldX, fnumber, oldZ); }}However, this throws this error: I found this bug-report, which states, it would have been fixed, which doesn't seem so. So, is there a way to have the server send messages to Unity? Thanks 解决方案 Expanding my comment to be more descriptive and concrete, my suggestion is to create a simple Thread that will serve as the communication manager with your server.First of all you have to implement this class to call methods on Unity's UI thread.When you implement this just create a class :public class CommunicationManager{ static readonly object syncRoot = new object(); static CommunicationManager _Instance; public static CommunicationManager Instance { get { if ( _Instance == null ) { lock ( syncRoot ) { if ( _Instance == null ) { _Instance = new CommunicationManager(); } } } return _Instance; } } volatile bool working = false; Queue<Message> _messages; private CommunicationManager() { _messages = new Queue<Message>(); InitializeCommunication(); } void InitializeCommunication() { Thread t = new Thread(CommunicationLoop); t.Start(); } void CommunicationLoop() { Socket s = null; try { Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); s.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1337)); working = true; } catch(Exception ex) { working = false; } while ( working ) { lock ( syncRoot ) { while ( _messages.Count > 0 ) { Message message = _messages.Dequeue(); MessageResult result = message.Process(s); result.Notify(); } } Thread.Sleep(100); } } public void EnqueueMessage(Message message) { lock ( syncRoot ) { _messages.Enqueue( message ); } }}Now you have to make Message and MessageResult objects :public class Message{ const string REQUEST_SCHEME = "{0} {1} HTTP/1.1\r\nHost: {hostname}\r\nContent-Length: 0\r\n\r\n"; string request; Action<MessageResult> whenCompleted; public Message(string requestUri, string requestType, Action<MessageResult> whenCompleted) { request = string.Format(REQUEST_SCHEME, requestType, requestUri); this.whenCompleted = whenCompleted; } public MessageResult Process(Socket s) { IPEndPoint endPoint = (IPEndPoint)s.RemoteEndPoint; IPAddress ipAddress = endPoint.Address; request = request.Replace("{hostname}", ipAddress.ToString()); s.Send(Encoding.UTF8.GetBytes(request)); // receive header here which should look somewhat like this : /* HTTP/1.1 <status> Date: <date> <some additional info> Accept-Ranges: bytes Content-Length: <CONTENT_LENGTH> <some additional info> Content-Type: <content mime type> */ // when you receive this all that matters is <CONTENT_LENGTH> int contentLength = <CONTENT_LENGTH>; byte[] msgBuffer = new byte[contentLength]; if (s.Receive(msgBuffer) != contentLength ) { return null; } return new MessageResult(msgBuffer, whenCompleted); }}And lastly create MessageResult object :public class MessageResult{ Action<MessageResult> notifier; byte[] messageBuffer; public MessageResult(byte[] message, Action<MessageResult> notifier) { notifier = notifier; messageBuffer = message; } public void Notify() { UnityThread.executeInUpdate(() => { notifier(this); }); }}This method will run aside from your main application so that wont produce any freezes and whatever.To use this you can just call something like this :Message message = new Message("/index.html", "GET", IndexDownloaded);CommunicationManager.Instance.EnqueueMessage(message);// ...public void IndexDownloaded(MessageResult result){ // result available here}For more informations read this wikipedia article about HTTP. 这篇关于REST在Unity中(将消息从Web服务器发送到unity)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
09-26 05:06