1. 程式人生 > >【unity】GameObject.Find 的效能開銷分析

【unity】GameObject.Find 的效能開銷分析

有時需要找根節點下的一些節點。測試了一下各個方法,發現GameObject.Find, 確實慢。


有時需要找根節點下的一些節點。測試了一下各個方法。
在目前S_Inland場景下,裡面節點比較多, 測試 一個指令碼,每個查詢分別執行100000次
開銷結果如下:
GameObject.Find("CameraForScenes"):                 6318000
GameObject.Find("/CameraForScenes"):               12714000
UnityHelper.GetTopObject("CameraForScenes"):         172000
GameObject.Find("/LightForScenes/LightForScenes"): 24164000
GameObject.Find("LightForScenes/LightForScenes"):  24009000
UnityHelper.GetTopObject("LightForScenes") Then transform.Find("/LightForScenes"): 24742000
UnityHelper.GetTopObject("LightForScenes") Then transform.Find("LightForScenes"):    452000


可見 GameObject.Find 全部節點遍歷的,確實要少用,根節點的物件用 UnityHelper.GetTopObject。Update函式裡更加少用。


倒數第2個數據這麼大,




大概知道為啥 GameObject go = UnityHelper.GetTopObject("LightForScenes");
            go.transform.Find("/LightForScenes");
很慢了, 加了開頭的斜槓, transform.Find 好像相當於GameObject.Find, 找到了根節點下的一個節點。


我們自己實現的 UnityHelper.GetTopObject 還能找到根節點隱藏的子節點物件。


想關程式碼:

using UnityEngine;

public class TestGOFind : MonoBehaviour {
      void OnEnable()  {  DoTest();  }

    public void DoTest()
    {
        int count = 100000;

        int time = System.Environment.TickCount;
        for (int i = 0; i < count; ++i)
        {
            GameObject.Find("CameraForScenes");
        }
        Debug.Log("GameObject.Find("CameraForScenes"): " + (System.Environment.TickCount - time) * 1000);

        int time2 = System.Environment.TickCount;
        for (int i = 0; i < count; ++i)
        {
            GameObject.Find("/CameraForScenes");
        }
        Debug.Log("GameObject.Find("/CameraForScenes"): " + (System.Environment.TickCount - time) * 1000);

        int time3 = System.Environment.TickCount;
        for (int i = 0; i < count; ++i)
        {
            UnityHelper.GetTopObject("CameraForScenes");
        }
        Debug.Log("UnityHelper.GetTopObject("CameraForScenes"):" + (System.Environment.TickCount - time3) * 1000);

        int time4 = System.Environment.TickCount;
        for (int i = 0; i < count; ++i)
        {
            GameObject.Find("/LightForScenes/LightForScenes");
        }
        Debug.Log("GameObject.Find("/LightForScenes/LightForScenes"): " + (System.Environment.TickCount - time4) * 1000);

        int time5 = System.Environment.TickCount;
        for (int i = 0; i < count; ++i)
        {
            GameObject.Find("LightForScenes/LightForScenes");
        }
        Debug.Log("GameObject.Find("LightForScenes/LightForScenes"): " + (System.Environment.TickCount - time5) * 1000);
        int time6 = System.Environment.TickCount;
        for (int i = 0; i < count; ++i)
        {
            GameObject go = UnityHelper.GetTopObject("LightForScenes");
            go.transform.Find("/LightForScenes");
        }
        Debug.Log("UnityHelper.GetTopObject Then transform Find /LightForScenes: " + (System.Environment.TickCount - time6) * 1000);
        int time7 = System.Environment.TickCount;
        for (int i = 0; i < count; ++i)
        {
            GameObject go = UnityHelper.GetTopObject("LightForScenes");
            go.transform.Find("LightForScenes");
        }
        Debug.Log("UnityHelper.GetTopObject Then transform Find LightForScenes: " + (System.Environment.TickCount - time7) * 1000);
    }
  
}

//GetTopObject程式碼:

    public static GameObject GetTopObject(string name)
    {
        UnityEngine.SceneManagement.Scene scene = SceneManager.GetActiveScene();
        GameObject[] rootObj = scene.GetRootGameObjects();
        foreach (GameObject obj in rootObj)
        {
            if (obj.name == name)
            {
                return obj;
            }
        }

        return null;
    }