【Unity / Thread】Unity 中子线程回调主线程的方法

您所在的位置:网站首页 unity多窗口同步 【Unity / Thread】Unity 中子线程回调主线程的方法

【Unity / Thread】Unity 中子线程回调主线程的方法

2023-08-10 12:50| 来源: 网络整理| 查看: 265

Unity 引擎的游戏逻辑和渲染,都是在主线程中进行的,和大多数其他游戏引擎一样,Unity 也是一个单线程的引擎。这与常规开发的思路可能不太一样,通常认为多线程能够很大程度上提升程序的性能效率,何况是游戏这种需要大量资源和大量计算的复杂程序。其实不然,单线程能为游戏引擎开发和游戏开发带来很多好处,未经过精心设计的多线程也可能会为中后期开发带来灾难性的后果。但这不是本文要讨论的重点,感兴趣的话可以自行搜索游戏引擎设计和多线程相关的资料。

综合考虑众多因素,大量游戏引擎都采用了单线程的设计,但这也带来了一些问题,Unity 提供的大多数非值类型对象都是不允许在主线程之外访问的,但很多时候应该使用或者无法避免使用多线程,同时子线程也必须要和主线程发生交互,例如:

1.相对独立且运算复杂的独立模块,比如网络通讯。游戏与服务端的数据交互,解析结果最终需要反馈到游戏逻辑中呈现给玩家。2.支付、广告、统计分析等众多第三方SDK的逻辑代码会在各自的线程上执行,但SDK各种功能的状态和结果是需要通知游戏主线程的。

目前我使用的方法是利用 C# 的委托功能,将子线程回调主线程的函数以事件形式注册到委托上,主线程使用一个管理类,按一定频率去查询尚未执行的子线程事件,并依次执行。

定义待执行的子线程事件队列:

private static bool NoUpdate = true; private static List UpdateQueue = new List(); private static List UpdateRunQueue = new List();

添加待执行子线程事件的接口:

public static void ExecuteUpdate(Action action) { lock (UpdateQueue) { UpdateQueue.Add(action); NoUpdate = false; } }

主线程上的轮询方法:

private void Update() { lock (UpdateQueue) { if (NoUpdate) return; UpdateRunQueue.AddRange(UpdateQueue); UpdateQueue.Clear(); NoUpdate = true; for (var i = 0; i ExecuteCoroutine(DelayCoroutine(action, delayTime, timeScale)); } private static IEnumerator DelayCoroutine(Action action, float delayTime, bool timeScale = true) { if (timeScale) { yield return new WaitForSeconds(delayTime); } else { yield return new WaitForSecondsRealtime(delayTime); } action(); }


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3