一般来说:您应该不使用OnGUI!它是一种遗留物,并且已经被您已经在使用的 UI 系统所取代。
如果您希望每帧都发生一些事情,请使用Update
我假设(希望)UdP 在后台线程中运行。我会使用一种通常称为“主线程调度程序”的模式:
您可以使用ConcurrentQueue(先进先出)
private readonly ConcurrentQueue<Action> actions = new ConcurrentQueue<Action>();
private void Update()
{
while(actions.TryDequeue(out var Action)
{
action?.Invoke();
}
}
在这种情况下,您希望处理自上一帧以来附加到队列的所有操作。您可以从您的 UDP 线程中添加相应的操作,例如
...
float value = BitConverter.ToSingle(dest, 0);
string text = value.ToString();
actions.Enqueue(() =>
{
text2 = text;
// print text
print(">> " + text);
}
}
catch(Exception err
{
actions.Enqueue(() => print(err.ToString());
}
或者在您的情况下,您甚至可以对其进行一些优化并节省一些工作/资源:仅使用并显示 last 接收到的字符串,以便您可以使用ConcurrentStack(last-in first -出)
private readonly ConcurrentStack<string> receivedStrings = new ConcurrentStack<string>();
private void Update()
{
if(receivedStrings.TryPop(out var message))
{
text2 = message;
print(">> " + message);
// dump all previous messages
receivedStrings.Clear();
}
}
然后您只需将收到的消息添加到堆栈中,例如
...
float value = BitConverter.ToSingle(dest, 0);
string text = value.ToString();
receivedStrings.Push(text);
至于您对多个文本组件的评论:
是的,您可以使用多个ConcurrentStack。然后我会像这样使用它们:
// First define the IDs you want to use
private enum StackID
{
Text1,
Text2,
Text3,
...
}
// Reference your individual Text components via the Inspector
[SerializeField] private Text _text1;
[SerializeField] private Text _text2;
[SerializeField] private Text _text3;
...
// The special string you use for splitting the receivedessage
// configure via the Inspector
[SerializeField] private string _splitter = "$$";
// This holds all ConcurrentStack addressed by their StackID
private Dictionary<StackID, ConcurrentStack<string>> _stacks = new Dictionary<StackID, ConcurrentStack<string>>();
// This links the given Text components to a certain StackID
// in other words which text shall listen to which stack
private Dictionary<StackID, Text> _texts = new Dictionary<StackID, Text>();
private void Awake ()
{
// Initialize the dictionaries
foreach(var id in (StackID[])Enum.GetValues(typeof(StackID)))
{
_stacks.Add(id, new ConcurrentStack<string>());
}
_texts.Add(StackID.Text1, _text1);
_texts.Add(StackID.Text2, _text2);
_texts.Add(StackID.Text3, _text3);
...
}
private void Start ()
{
// start the Receiver
var thread = new Thread(new ThreadStart(ReceiveData));
thread.Start();
}
private void Update ()
{
// Iterate through all values of StackID
foreach(var id in (StackID[])Enum.GetValues(typeof(StackID)))
{
if(_stacks[id].TryPop(out var message))
{
_texts[id].text = message;
print(">> " + message);
// dump all previous messages
_stacks[id].Clear();
}
}
}
// On Background Thread
void ReceiveData()
{
client = new UdpClient(port);
while (true)
{
try
{
// Bytes received.
IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
byte[] data = new byte[1024];
data = client.Receive(ref anyIP);
//converting bytes to string
var message = Encoding.UTF8.GetString(data);
// Now split the message into your parts and pass them into the individual stacks
var texts = message.Split(new string[]{ _splitter }, message);
_stacks[StackID.Text1]. Enqueue(texts[0]);
_stacks[StackID.Text2]. Enqueue(texts[1]);
_stacks[StackID.Text3]. Enqueue(texts[2]);
...
}
catch (Exception err)
{
foreach(var id in (StackID[])Enum.GetValues(typeof(StackID)))
{
_stacks[id].Enqueue(err.ToString());
}
}
}
}
注意:在智能手机上打字,所以没有保修,但我希望这个想法能清楚