Last active
March 29, 2021 02:28
-
-
Save simonwittber/7f1364cd3a82c4281ee3370ef5366a5f to your computer and use it in GitHub Desktop.
MonoBehaviour classes which allow for Batch Updating.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
While we wait for ECS support for all unity features, this is a viable solution to solving the "1000 update calls" problem.