在開發中往往會遇到一個問題:不知道整個場景中究竟有哪些物體掛載了某一個腳本。如果挨個查找太麻煩了,下面有一種方法可以快速找到解決這個問題。
在unity的Window里有一項Editor tests runner 選擇這個會出現一個窗口:如下圖:
然后點擊創建腳本會有腳本自動創建在project里的Editor下。之后我們要寫兩個腳本(如下圖)
這兩個腳本代碼,一個是用來盛放要被找的那些物體另個是盛放你要來查找被物體掛載的腳本:
盛放物體的代碼:
using UnityEngine; using UnityEditor; public class FindMissingScriptsRecursively : EditorWindow { static int go_count = 0, components_count = 0, missing_count = 0; [MenuItem("Window/FindMissingScriptsRecursively")] public static void ShowWindow() { EditorWindow.GetWindow(typeof(FindMissingScriptsRecursively)); } public void OnGUI() { if (GUILayout.Button("Find Missing Scripts in selected GameObjects")) { FindInSelected(); } } private static void FindInSelected() { GameObject[] go = Selection.gameObjects; go_count = 0; components_count = 0; missing_count = 0; foreach (GameObject g in go) { FindInGO(g); } Debug.Log(string.Format("Searched {0} GameObjects, {1} components, found {2} missing", go_count, components_count, missing_count)); } private static void FindInGO(GameObject g) { go_count++; Component[] components = g.GetComponents<Component>(); for (int i = 0; i < components.Length; i++) { components_count++; if (components[i] == null) { missing_count++; string s = g.name; Transform t = g.transform; while (t.parent != null) { s = t.parent.name + "/" + s; t = t.parent; } Debug.Log(s + " has an empty script attached in position: " + i, g); } } // Now recurse through each child GO (if there are any): foreach (Transform childT in g.transform) { //Debug.Log("Searching " + childT.name + " " ); FindInGO(childT.gameObject); } } }
盛放腳本的代碼:
using UnityEngine; using System.Collections; using System.Collections.Generic; using UnityEditor; ///////////////////////////////////////////////////////////////////////////// //查找節點及所有子節點中,是否有指定的腳本組件 ///////////////////////////////////////////////////////////////////////////// public class MonoFinder : EditorWindow { Transform root = null; MonoScript scriptObj = null; int loopCount = 0; List<Transform> results = new List<Transform>(); [MenuItem("Level4/Finder/MonoFinder")] static void Init() { EditorWindow.GetWindow(typeof(MonoFinder)); } void OnGUI() { GUILayout.Label("節點:"); root = (Transform)EditorGUILayout.ObjectField(root, typeof(Transform), true); GUILayout.Label("腳本類型:"); scriptObj = (MonoScript)EditorGUILayout.ObjectField(scriptObj, typeof(MonoScript), true); if (GUILayout.Button("Find")) { results.Clear(); loopCount = 0; Debug.Log("開始查找."); FindScript(root); } if (results.Count > 0) { foreach (Transform t in results) { EditorGUILayout.ObjectField(t, typeof(Transform), false); } } else { GUILayout.Label("無數據"); } } void FindScript(Transform root) { if (root != null && scriptObj != null) { loopCount++; Debug.Log(".." + loopCount + ":" + root.gameObject.name); if (root.GetComponent(scriptObj.GetClass()) != null) { results.Add(root); } foreach (Transform t in root) { FindScript(t); } } } }
有了這兩個腳本,會發現unity的菜單里會多出一個level4(如圖)的選項,然后點擊它,會出現一個彈窗。上面那個節點(如圖)就是盛放物體的,下面那個腳本類型(如圖)就是放腳本的。
例如下面的案例中,我要查找一個名字叫AsyncImageDownloader的腳本在panoramic這個物體里有多少被掛載了。直接把對應的東西拖進去,然后點擊find就會發現在userhead_portrait這個子物體里有這個腳本。
這種方法可以找到所有父物體下的子物體中所有的掛載。它會遍歷整個父物體中個的子物體;
從下圖中可以看出在panoramic這個父物體中有575個子物體,它們都被查找了一遍。可見剛才查到只有userhead_portrait上掛載了剛才要找的腳本。