Skip to content

Instantly share code, notes, and snippets.

@GhatSmith
Created September 27, 2018 21:52
Show Gist options
  • Save GhatSmith/fafa1c6290278c5476fa65a23d599d6f to your computer and use it in GitHub Desktop.
Save GhatSmith/fafa1c6290278c5476fa65a23d599d6f to your computer and use it in GitHub Desktop.
UpdateDispatcher to have Update even when GameObjecct or script is disabled, or have update callback for non MonoBehaviour scripts
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
public interface IUpdateListener
{
void OnUpdate();
}
public class UpdateDispatcher : MonoBehaviour
{
private static UpdateDispatcher instance = null;
// Queue of commands to execute
private static List<System.Action> updateActions;
private static List<IUpdateListener> updateListeners = new List<IUpdateListener>();
// Cached iterators
private static IUpdateListener listener;
private static System.Action action;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void Init()
{
if (instance == null)
{
instance = new GameObject(typeof(UpdateDispatcher).Name).AddComponent<UpdateDispatcher>();
DontDestroyOnLoad(instance.gameObject);
}
}
#if UNITY_EDITOR
[InitializeOnLoadMethod()]
static void EditorInit()
{
EditorApplication.update -= EditorUpdate;
EditorApplication.update += EditorUpdate;
}
#endif
private void Update()
{
ExecuteActions();
ExecuteListeners();
}
private static void EditorUpdate()
{
ExecuteActions();
ExecuteListeners();
}
/// <summary> Constructor with initialization. /// </summary>
static UpdateDispatcher()
{
updateActions = new List<System.Action>();
updateListeners = new List<IUpdateListener>();
}
/// <summary> Add an update action. This function is thread-safe. </summary>
public static void AddAction(System.Action action)
{
lock (updateActions)
{
updateActions.Insert(0, action);
}
}
/// <summary> Execute actions </summary>
private static void ExecuteActions()
{
lock (updateActions)
{
for (int i = updateActions.Count - 1; i >= 0; i--)
{
updateActions[i].Invoke();
}
}
}
/// <summary> Execute commands until there are none left or a maximum time is used </summary>
private static void ExecuteListeners()
{
lock (updateListeners)
{
for (int i = updateListeners.Count - 1; i >= 0; i--)
{
updateListeners[i].OnUpdate();
}
}
}
public static void AddListener(IUpdateListener listener)
{
lock (updateListeners)
{
updateListeners.Insert(0, listener);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment