1. 程式人生 > >[轉]unity如何查詢某個指令碼掛在了哪些物體上

[轉]unity如何查詢某個指令碼掛在了哪些物體上

在開發中往往會遇到一個問題:不知道整個場景中究竟有哪些物體掛載了某一個指令碼。如果挨個查詢太麻煩了,下面有一種方法可以快速找到解決這個問題

在unity的Window裡有一項Editor tests runner 選擇這個會出現一個視窗:如下圖:

然後點選建立指令碼會有指令碼自動建立在project裡的Editor下。之後我們要寫兩個指令碼(如下圖)

 

這兩個指令碼程式碼,一個是用來盛放要被找的那些物體另個是盛放你要來查詢被物體掛載的指令碼:

盛放物體的程式碼:

 

 
  1. using UnityEngine;

  2. using UnityEditor;

  3. public class FindMissingScriptsRecursively : EditorWindow

  4. {

  5. static int go_count = 0, components_count = 0, missing_count = 0;

  6.  
  7. [MenuItem("Window/FindMissingScriptsRecursively")]

  8. public static void ShowWindow()

  9. {

  10. EditorWindow.GetWindow(typeof(FindMissingScriptsRecursively));

  11. }

  12.  
  13. public void OnGUI()

  14. {

  15. if (GUILayout.Button("Find Missing Scripts in selected GameObjects"))

  16. {

  17. FindInSelected();

  18. }

  19. }

  20. private static void FindInSelected()

  21. {

  22. GameObject[] go = Selection.gameObjects;

  23. go_count = 0;

  24. components_count = 0;

  25. missing_count = 0;

  26. foreach (GameObject g in go)

  27. {

  28. FindInGO(g);

  29. }

  30. Debug.Log(string.Format("Searched {0} GameObjects, {1} components, found {2} missing", go_count, components_count, missing_count));

  31. }

  32.  
  33. private static void FindInGO(GameObject g)

  34. {

  35. go_count++;

  36. Component[] components = g.GetComponents<Component>();

  37. for (int i = 0; i < components.Length; i++)

  38. {

  39. components_count++;

  40. if (components[i] == null)

  41. {

  42. missing_count++;

  43. string s = g.name;

  44. Transform t = g.transform;

  45. while (t.parent != null)

  46. {

  47. s = t.parent.name + "/" + s;

  48. t = t.parent;

  49. }

  50. Debug.Log(s + " has an empty script attached in position: " + i, g);

  51. }

  52. }

  53. // Now recurse through each child GO (if there are any):

  54. foreach (Transform childT in g.transform)

  55. {

  56. //Debug.Log("Searching " + childT.name + " " );

  57. FindInGO(childT.gameObject);

  58. }

  59. }

  60. }


盛放指令碼的程式碼:

 

 
  1. using UnityEngine;

  2. using System.Collections;

  3. using System.Collections.Generic;

  4. using UnityEditor;

  5.  
  6. /////////////////////////////////////////////////////////////////////////////

  7. //查詢節點及所有子節點中,是否有指定的指令碼元件

  8. /////////////////////////////////////////////////////////////////////////////

  9. public class MonoFinder : EditorWindow

  10. {

  11. Transform root = null;

  12. MonoScript scriptObj = null;

  13. int loopCount = 0;

  14.  
  15. List<Transform> results = new List<Transform>();

  16.  
  17. [MenuItem("Level4/Finder/MonoFinder")]

  18. static void Init()

  19. {

  20. EditorWindow.GetWindow(typeof(MonoFinder));

  21. }

  22.  
  23. void OnGUI()

  24. {

  25. GUILayout.Label("節點:");

  26. root = (Transform)EditorGUILayout.ObjectField(root, typeof(Transform), true);

  27. GUILayout.Label("指令碼型別:");

  28. scriptObj = (MonoScript)EditorGUILayout.ObjectField(scriptObj, typeof(MonoScript), true);

  29. if (GUILayout.Button("Find"))

  30. {

  31. results.Clear();

  32. loopCount = 0;

  33. Debug.Log("開始查詢.");

  34. FindScript(root);

  35. }

  36. if (results.Count > 0)

  37. {

  38. foreach (Transform t in results)

  39. {

  40. EditorGUILayout.ObjectField(t, typeof(Transform), false);

  41. }

  42. }

  43. else

  44. {

  45. GUILayout.Label("無資料");

  46. }

  47. }

  48.  
  49. void FindScript(Transform root)

  50. {

  51. if (root != null && scriptObj != null)

  52. {

  53. loopCount++;

  54. Debug.Log(".." + loopCount + ":" + root.gameObject.name);

  55. if (root.GetComponent(scriptObj.GetClass()) != null)

  56. {

  57. results.Add(root);

  58. }

  59. foreach (Transform t in root)

  60. {

  61. FindScript(t);

  62. }

  63. }

  64. }

  65. }

有了這兩個指令碼,會發現unity的選單裡會多出一個level4(如圖)的選項,然後點選它,會出現一個彈窗。上面那個節點(如圖)就是盛放物體的,下面那個指令碼型別(如圖)就是放指令碼的。

例如下面的案例中,我要查詢一個名字叫AsyncImageDownloader的指令碼在panoramic這個物體裡有多少被掛載了。直接把對應的東西拖進去,然後點選find就會發現在userhead_portrait這個子物體裡有這個指令碼。


 

這種方法可以找到所有父物體下的子物體中所有的掛載。它會遍歷整個父物體中個的子物體

從下圖中可以看出在panoramic這個父物體中有575個子物體,它們都被查找了一遍。可見剛才查到只有userhead_portrait上掛載了剛才要找的指令碼。