【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; }