2016-07-23 131 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不返回非活動對象。

相關問題