using System; using System.Collections.Generic; using UnityEngine; namespace Kill.Utils { /// /// 主线程执行器 - 确保回调在主线程执行 /// public class MainThread : MonoBehaviour { private static MainThread _instance; private static readonly Queue _actions = new Queue(); private static readonly object _lock = new object(); [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] private static void Initialize() { var go = new GameObject("MainThread"); _instance = go.AddComponent(); DontDestroyOnLoad(go); } private void Update() { lock (_lock) { while (_actions.Count > 0) { _actions.Dequeue()?.Invoke(); } } } /// /// 在主线程执行 /// public static void Enqueue(Action action) { if (action == null) return; // 编辑器环境下,如果调度器未初始化,直接执行 #if UNITY_EDITOR if (_instance == null) { action?.Invoke(); return; } #endif // 如果调度器已初始化,加入队列 if (_instance != null) { lock (_lock) { _actions.Enqueue(action); } } else { // 真机环境下调度器应该已初始化,如果未初始化则直接执行 action?.Invoke(); } } /// /// 立即在主线程执行(如果已经在主线程)或排队 /// public static void Run(Action action) { if (action == null) return; // 检查是否在主线程 if (Time.frameCount > 0) { // 已经在主线程,直接执行 action(); } else { // 不在主线程,排队 Enqueue(action); } } } }