2016-07-23 55 views
1

我读过一篇文章10000 UPDATE() CALLS。 作者使用UpdateManager。它有Update方法,在所有其他对象的MonoBehaviours中调用Update方法。它的工作速度比分别从每个MonoBehaviour调用Update方法快。如何添加场景的所有MonoBehaviours到列表中?

该经理的样子:

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上使用递归方法吗?因为每个对象可能包含其他对象的脚本,它们可能含有其它对象等..无限嵌套

也有一些物体可以被动态实例...如何在他们的单加入的经理吗?什么是正确的方式?

+0

您可以创建一个被管理的monobehaviours的静态列表,并在每个monobehaviour的'Start()'函数中添加它到该列表中,然后从管理器中的列表中读取。 –

+0

@YotamSalmon Neee。我不认为这是个好主意。如果我有50..100个Monobehaviours会怎么样?手动添加代码到每个脚本?如果我改变了主意,该怎么办?手动删除?改变我的想法吗?))它不是生产性的.......'java 8'具有可以包含默认方法的接口(带有实现)...如果C#有类似的东西,那将是很好的....那会更合适,我认为 –

回答

1

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

让每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 Test : MonoBehaviour 
{ 
    UpdateSubscriber updateSUBSCR; 

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

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

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

然后你可以叫它

请注意,数组比012快,但是这比每个脚本中具有Update()函数要好。

+0

因此,没有更好的方法可以做到这一点,而不是将这些代码手动添加到每个Monobehaviour中? :'(我的意思是,如果我有50..100个Monobehaviours,并且我改变了主意,那么从哪里手动删除代码(从'Start','OnDestroy'和'UpdateSubscriber updateSUBSCR;')? 没有更多的东西通用的方法来将这个逻辑添加到对象中?例如:使用一些全局脚本来监视是否在场景中实例化了一些东西,并将它的单声道添加到列表中 或类似于Java的8个接口,默认逻辑... 。或者这是唯一的方式?很难但是正确:) –

+0

@AlexeyShimansky我真的不明白你在说什么。你是**不**手动做任何事情。每个GameObject都会在实例化时自动添加它,并在销毁时自行删除。你所要做的就是将'ManagedUpdateBehavior'附加到每个GameObject或你的预制件上。创建一个名为UpdateSUBSCR的GameObject并将'UpdateSUBSCR'脚本附加到它。 – Programmer

+0

现在,为了实际调用'Update'函数,您必须将代码放在上面的'Test'脚本中,并添加到您的主游戏代码中。然后你可以通过调用'updateSUBSCR.callUpdateFuncs();' – Programmer

1

你可以找到和使用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不返回非活动对象。

相关问题