Unity中后台线程如何向主线程发回调并根据服务端数据实例化Prefab
Unity 后台线程接收数据后切换主线程生成 Prefab 方案
Unity 所有涉及 GameObject 操作、Prefab 实例化的原生 API 仅允许在主线程执行,后台线程直接调用会触发运行时异常
步骤1:实现主线程任务调度器
创建 MainThreadDispatcher.cs 脚本,挂载到场景中永久存活的 GameObject(如全局管理对象)上:
using System; using System.Collections.Generic; using UnityEngine; public class MainThreadDispatcher : MonoBehaviour { public static MainThreadDispatcher Instance { get; private set; } private readonly Queue<Action> _taskQueue = new Queue<Action>(); private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; DontDestroyOnLoad(gameObject); } // 供后台线程调用,传入需要在主线程执行的委托 public void EnqueueTask(Action task) { if (task == null) return; lock (_taskQueue) { _taskQueue.Enqueue(task); } } private void Update() { lock (_taskQueue) { while (_taskQueue.Count > 0) { _taskQueue.Dequeue()?.Invoke(); } } } }
步骤2:修改数据接收逻辑
在后台线程拿到服务端数据后,将 Prefab 生成逻辑包装成委托传入调度器即可:
void retrieveData() { while (true) { string data = subSocket.ReceiveFrameString(); // 将生成逻辑丢到主线程执行 MainThreadDispatcher.Instance.EnqueueTask(() => { // 此处可正常调用 Unity 原生 API GameObject targetPrefab = Resources.Load<GameObject>("你的Prefab资源路径"); Instantiate(targetPrefab, 指定生成坐标, Quaternion.identity); // 可根据接收的data动态调整生成逻辑 }); } }
注意事项
- 需确保
MainThreadDispatcher提前挂载到场景激活的 GameObject 上,避免单例为空报错 - 新增线程退出控制逻辑,游戏停止运行时终止后台线程,避免内存泄漏
- 高频率数据接收场景可做任务批量合并,降低主线程执行压力
内容的提问来源于stack exchange,提问作者Paul Andy
相关产品推荐
相关产品推荐

