繁体   English   中英

如何将所有场景的MonoBehaviours添加到列表中?

[英]How to add all MonoBehaviours of Scene into the List?

我已经读了文章10000 UPDATE()CALLS 作者使用UpdateManager。 它具有Update方法,该方法在所有其他MonoBehaviours对象中调用Update方法。 它比分别从每个MonoBehaviour调用Update方法要快。

该经理看起来像:

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();
    }
}

现在,每个对象都包含带有代码的组件:

public class ManagedUpdateBehavior : MonoBehaviour {
    // some variables

    public void UpdateMe() {
        // some logic
    }
}

没关系,如果5-6-7-8-对象将具有该组件。

但是,如果我有100个对象怎么办? 1000? 10000?

如何从场景的所有对象中查找并添加所有ManagedUpdateBehaviors 我应该在On Start上使用一些递归方法吗? 因为每个对象可能包含脚本中的其他对象,它们可能包含其他对象等...无限嵌套

还有一些对象可以动态实例化...如何将其单声道添加到管理器? 正确的方法是什么?

您可以使用Object.FindObjectsOfType方法查找并添加所有ManagedUpdateBehaviours。

您可以使用静态方法添加动态实例化对象,该方法可以从创建的游戏对象中调用以将其添加到列表中。

我的建议是创建一个SceneUpdateManager,如下所示:

using UnityEngine;
using System.Collections.Generic;
using System.Linq;

public class SceneUpdateManager : MonoBehaviour {

    private static List<ManagedUpdateBehavior> list;

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

    public static void AddBehavior(ManagedUpdateBehavior behaviour)
    {
        list.Add (behaviour);
    }

    private void Update () {
        var count = list.Count;

        for (var i = 0; i < count; i++)
        {
            list [i].UpdateMe();
        }
    }
}

Object.FindObjectsOfType不返回非活动对象。

还有一些对象可以动态实例化

通过将ManagedUpdateBehavior实例的实例添加到ManagedUpdateBehavior实例,使每个ManagedUpdateBehavior订阅ManagedUpdateBehavior列表。 他们还应该从取消ManagedUpdateBehavior当从清除自身破坏ManagedUpdateBehavior实例。

您新的ManagedUpdateBehavior脚本:

public class ManagedUpdateBehavior : MonoBehaviour
{
    UpdateSubscriber updateSUBSCR;

    //Add it self to the List
    void Start()
    {
        updateSUBSCR = GameObject.Find("UpdateSUBSCR").GetComponent<UpdateSubscriber>();
        updateSUBSCR.addManagedUpdateBehavior(this);
    }

    //Remove it self from the List
    void OnDestroy()
    {
        updateSUBSCR.removeManagedUpdateBehavior(this);
    }

    public void UpdateMe()
    {
        // some logic
        Debug.Log("Update from: " + gameObject.name);
    }
}

创建一个名为UpdateSUBSCR的GameObject并将以下脚本附加到该对象:

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 List<ManagedUpdateBehavior> getManagedUpdateBehaviorinstance
    {
        get
        {
            return managedUpdateBehavior;
        }
    }*/

    public void updateAll()
    {
        for (int i = 0; i < managedUpdateBehavior.Count; i++)
        {
            managedUpdateBehavior[i].UpdateMe();
        }
    }
}

然后,您可以使用以下命令调用它:

public class Test : MonoBehaviour
{
    UpdateSubscriber updateSUBSCR;

    void Start()
    {
        updateSUBSCR = GameObject.Find("UpdateSUBSCR").GetComponent<UpdateSubscriber>();
    }

    void Update()
    {
        updateSUBSCR.callUpdateFuncs();
    }
}

请注意,数组比List快,但是比在每个脚本中使用Update()函数要好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM