Skip to content

Instantly share code, notes, and snippets.

@simonwittber
Last active March 29, 2021 02:28
Show Gist options
  • Save simonwittber/7f1364cd3a82c4281ee3370ef5366a5f to your computer and use it in GitHub Desktop.
Save simonwittber/7f1364cd3a82c4281ee3370ef5366a5f to your computer and use it in GitHub Desktop.
MonoBehaviour classes which allow for Batch Updating.
using System.Collections.Generic;
using UnityEngine;
public abstract class MonoBehaviourSystem<T> : MonoBehaviour where T : MonoBehaviourComponent<T>
{
protected abstract void UpdateBatch(Queue<T> components);
void Update()
{
UpdateBatch(ComponentBatch<T>.components);
}
void Awake()
{
if (ComponentBatch<T>.system != null)
DestroyImmediate(this);
else
ComponentBatch<T>.system = this;
}
}
static internal class ComponentBatch<T> where T : MonoBehaviourComponent<T>
{
internal static Queue<T> components = new Queue<T>();
internal static MonoBehaviourSystem<T> system = null;
internal static void Enqueue(T component)
{
components.Enqueue(component);
if (system != null && !system.enabled)
system.enabled = true;
}
internal static T Dequeue()
{
var c = components.Dequeue();
if (components.Count == 0 && system != null && !system.enabled)
system.enabled = false;
return c;
}
}
public abstract class MonoBehaviourComponent<T> : MonoBehaviour where T : MonoBehaviourComponent<T>
{
protected virtual void OnEnable()
{
ComponentBatch<T>.Enqueue((T)this);
}
}
using System.Collections.Generic;
using UnityEngine;
public class YourClassSystem : MonoBehaviourSystem<YourClass>
{
protected override void UpdateBatch(Queue<YourClass> components)
{
//Only process items that are in the queue _right now_.
//This lets other processes add items to the queue without
//effecting the batch state.
for (int i = 0, count = components.Count; i < count; i++)
{
var c = components.Dequeue();
// if object is active, requeue so it will be processed again.
// inactive objects are discarded, but added to the batch again
// when reactivated.
if (c.gameObject.activeSelf)
{
components.Enqueue(c);
//Do work on the component here.
}
}
}
}
@simonwittber
Copy link
Author

While we wait for ECS support for all unity features, this is a viable solution to solving the "1000 update calls" problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment