using System.Collections.Concurrent; using UnityEngine; public class MainThreadDispatcher : MonoBehaviour { private static MainThreadDispatcher _instance; private readonly ConcurrentQueue _executionQueue = new ConcurrentQueue(); public static MainThreadDispatcher Instance { get { if (_instance == null) { // Check if an instance already exists in the scene _instance = FindObjectOfType(); if (_instance == null) { // Create new GameObject if none exists var dispatcherObject = new GameObject("MainThreadDispatcher"); _instance = dispatcherObject.AddComponent(); DontDestroyOnLoad(dispatcherObject); } } return _instance; } } // Add action to the queue public void Enqueue(System.Action action) { if (action == null) { Debug.LogWarning("Trying to enqueue a null action"); return; } _executionQueue.Enqueue(action); } // Update is called once per frame void Update() { // Execute all actions in the queue while (_executionQueue.TryDequeue(out var action)) { try { action.Invoke(); } catch (System.Exception e) { Debug.LogError($"Exception in dispatched action: {e}"); } } } // Cleanup when destroyed void OnDestroy() { if (_instance == this) { _instance = null; } } }