I recently read an article 10,000 UPDATE CALLS () . The author uses his UpdateManager . This manager has its own Update method, which calls all Update methods in all other MonoBehaviours components of all objects. It works faster than calling Update in each MonoBehaviour separately .. His manager looks like this:

 private ManagedUpdateBehavior[] list; private void Start() { list = GetComponents<ManagedUpdateBehavior>(); } private void Update() { var count = list.Length; for (var i = 0; i < count; i++) { // UpdateMe list[i].UpdateMe(); } } 

And each object should now contain a script with the code:

 public class ManagedUpdateBehavior : MonoBehaviour { // some variables public void UpdateMe() { // some logic } } 

If the objects using this component are not many, then it is easy to find them. And if there are 100? 1000? 10,000?

How to find all the objects on the scene and add them to all ManagedUpdateBehaviors . Should I use any recursive workaround at startup? After all, each object may contain another object with a script, which, in turn, is another object. Unlimited nesting. Also, objects are dynamically instantiated and removed from the scene, then you need to somehow add them dynamically to the list too. How to do it?

    1 answer 1

    To find all objects of type ManagedUpdateBehavior simply use the Object.FindObjectsOfType method. eg:

     private static List<ManagedUpdateBehavior> list; private void Start () { list = Object.FindObjectsOfType<ManagedUpdateBehavior>().ToList(); } 

    But truth he will not find inactive objects. And given that

    Also objects are dynamically instantiated and removed from the scene.

    there is no need to look for something each time and add components to it. It is enough to modify ManagedUpdateBehavior so that when it appears, it would list itself as a subscriber, let's call it UpdateSubscriber , and if you remove an object from the scene, it would remove itself from the list.

    So, the modified ManagedUpdateBehavior , which you need to add to all objects, whose characteristics we will update (that is, call UpdateMe ) from the general manager will be like this:

     public class ManagedUpdateBehavior : MonoBehaviour { UpdateSubscriber updateSUBSCR; // Добавляем себя в список void Start() { updateSUBSCR = GameObject.Find("UpdateSUBSCR").GetComponent<UpdateSubscriber>(); updateSUBSCR.addManagedUpdateBehavior(this); } // Удаляем себя из списка void OnDestroy() { updateSUBSCR.removeManagedUpdateBehavior(this); } public void UpdateMe() { // some logic Debug.Log("Update from: " + gameObject.name); } } 

    Next on the stage we create an object (our subscriber), with the name UpdateSUBSCR and attach a script to it:

     public class UpdateSubscriber : MonoBehaviour { private List<ManagedUpdateBehavior> managedUpdateBehavior = new List<ManagedUpdateBehavior>(); public void addManagedUpdateBehavior(ManagedUpdateBehavior managedUB) { managedUpdateBehavior.Add(managedUB); } public void removeManagedUpdateBehavior(ManagedUpdateBehavior managedUB) { for (int i = 0; i < managedUpdateBehavior.Count; i++) { if (managedUpdateBehavior[i] == managedUB) { managedUpdateBehavior.RemoveAt(i); break; } } } public void updateAll() { for (int i = 0; i < managedUpdateBehavior.Count; i++) { managedUpdateBehavior[i].UpdateMe(); } } /* public List<ManagedUpdateBehavior> getManagedUpdateBehaviorinstance { get { return managedUpdateBehavior; } }*/ } 

    And also add the script below, which will separately call Update from the manager himself, which in turn will call all UpdateMe methods UpdateMe the objects in the list

     public class Test : MonoBehaviour { UpdateSubscriber updateSUBSCR; void Start() { updateSUBSCR = GameObject.Find("UpdateSUBSCR").GetComponent<UpdateSubscriber>(); } void Update() { updateSUBSCR.updateAll(); } } 

    The answer is translated and slightly updated with https://stackoverflow.com/a/38541620/6104996