C# 使用Socket IO在Unity中执行UI相关操作的正确方法是什么
我已经使用socket io几个月了。在unity中实现socket时,我遇到了很多问题。但我的主要问题是,当我从套接字连接接收消息/数据时,我不能仅仅调用一个方法来执行一些与UI相关的操作。我想出了一个布尔变量,当bool为true时执行特定的操作,并在C# 使用Socket IO在Unity中执行UI相关操作的正确方法是什么,c#,unity3d,socket.io,C#,Unity3d,Socket.io,我已经使用socket io几个月了。在unity中实现socket时,我遇到了很多问题。但我的主要问题是,当我从套接字连接接收消息/数据时,我不能仅仅调用一个方法来执行一些与UI相关的操作。我想出了一个布尔变量,当bool为true时执行特定的操作,并在Update()中执行一些我觉得不是有效的方法 例如: public GameObject IdleGo; bool isDone = false; Socket socket; // Start is called before the f
Update()
中执行一些我觉得不是有效的方法
例如:
public GameObject IdleGo;
bool isDone = false;
Socket socket;
// Start is called before the first frame update
void Start()
{
InitSocket();
}
// Update is called once per frame
void Update()
{
if(isDone)
{
isDone = false;
IdleGo.SetActive(true);
}
}
void InitSocket()
{
if (socket == null)
{
socket = IO.Socket(ServerURL);
socket.On(Socket.EVENT_CONNECT, () =>
{
Debug.Log("connecting..");
socket.On("response", (data) =>
{
Debug.Log("response: " + data);
if (data == "connected")
{
isDone = true;
}
});
});
}
}
我很想知道socket的整个过程是如何与Unity一起完成的,因为我将在不久的将来制作一个多人游戏
谢谢。我会将整个套接字移动到后台线程,以避免任何阻塞 为了在Unity主线程中等待结果,使用
Update
和bool
标志是可以的,但我通常使用
public GameObject IdleGo;
private Socket socket;
// A thread-safe queue for passing a callback into the next Update call
private readonly ConcurrentQueue<Action> _mainThreadhActions = new ConcurrentQueue<Action>();
// Yes! You can make Start return IEnumerator
// In this case Unity automatically starts it as a Coroutine instead
private IEnumerator Start()
{
// Create a new thread in order to run the InitSocketThread method
var thread = new Thread(InitSocketThread);
// start the thread
thread.Start();
// Wait until a callback action is added to the queue
yield return new WaitUntil(() => _mainThreadhActions.Count > 0);
// If this fails something is wrong ^^
// simply get the first added callback
if(!_mainThreadhActions.TryDequeue(out var action))
{
Debug.LogError("Whoops something went wrong!", this);
yield break;
}
// Execute the code of the added callback
action?.Invoke();
}
void InitSocketThread()
{
if (socket == null)
{
socket = IO.Socket(ServerURL);
socket.On(Socket.EVENT_CONNECT, () =>
{
Debug.Log("connecting..");
socket.On("response", (data) =>
{
// Simply wrap your main thread code by wrapping it in a lambda expression
// which is enqueued to the thread-safe queue
_mainThreadhActions.Enqueue(()=>
{
// This will be executed after the next Update call
Debug.Log("response: " + data);
if (data == "connected")
{
IdleGo.SetActive(true);
}
}
});
});
}
}
公共游戏对象IdleGo;
专用插座;
//用于将回调传递到下一个更新调用的线程安全队列
私有只读ConcurrentQueue_mainThreadhActions=new ConcurrentQueue();
//对!!您可以使开始返回IEnumerator
//在这种情况下,Unity会自动将其作为协同程序启动
私有IEnumerator Start()
{
//创建一个新线程以运行InitSocketThread方法
var thread=新线程(InitSocketThread);
//开线
thread.Start();
//等待回调操作添加到队列中
返回新的等待时间(()=>_mainThreadhActions.Count>0);
//如果失败了,就有问题了^^
//只需获取第一个添加的回调
if(!\u mainThreadhActions.TryDequeue(out var action))
{
LogError(“哎呀,出问题了!”,这个);
屈服断裂;
}
//执行添加的回调函数的代码
action?.Invoke();
}
void InitSocketThread()
{
if(套接字==null)
{
socket=IO.socket(ServerURL);
socket.On(socket.EVENT_CONNECT,()=>
{
Debug.Log(“连接…”);
socket.On(“响应”,(数据)=>
{
//只需将主线程代码包装在lambda表达式中即可
//将其排入线程安全队列
_mainThreadhActions.Enqueue(()=>
{
//这将在下一次更新调用后执行
Log(“响应:+数据”);
如果(数据==“已连接”)
{
IdleGo.SetActive(true);
}
}
});
});
}
}
你应该独立于UI线程执行cpu/io/网络绑定操作,在这里同步调用update会导致UI响应差这是一种方法,但实际上你应该喜欢将整个套接字代码放入一个线程/任务中,这样就不会导致任何冻结。我不知道为什么它会被否决,因为我似乎找不到n回答。stackoverflow中已经有一些常见的问题,它们是最热门的问题,也是投票最多的问题。@derHugo谢谢你的建议。你能告诉我如何在unity中安全地做到这一点吗?谢谢@derHugo。我会尝试一下,并让你知道。