如何将场景的所有MonoBehaviours添加到List中?
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 does not return inactive objects.
Also some objects can be instantiating dynamically
让每个 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 的游戏对象并将下面的脚本附加到它:
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()
函数要好。
我读过一篇文章 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 does not return inactive objects.
Also some objects can be instantiating dynamically
让每个 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 的游戏对象并将下面的脚本附加到它:
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()
函数要好。