Unity3D编辑器:如何查找给定资产的所有用法?

时间:2016-10-21 08:49:50

标签: unity3d assets unity3d-editor

非常有用的功能“查找用法”存在于Visual Studio和Resharper中,但我在Unity3D编辑器中找不到相同的功能。我在Unity3d中只看到“选择依赖”,但我需要相反的一个。它存在吗?

4 个答案:

答案 0 :(得分:2)

在编辑器中,转到项目标签,选择给定的资产,右键单击它,然后点击在场景中查找参考。如果给定的资产是脚本,它将向您显示给定资产在层次结构视图中附加到的每个GameObject。如果是图像,音频文件或预制件,它将在层次结构视图中显示哪个GameObject正在使用该资产。

enter image description here

答案 1 :(得分:2)

免费开源工具 Dependencies-Hunter 可以完成这项工作:查找给定资产的所有依赖项/使用情况。它还可以执行完整的项目分析以找到所有未使用的资产。

它由单个脚本组成,因此只需将其复制粘贴到您的项目中即可。

在内部,它使用 AssetDatabase.GetDependencies 构建用于分析的所有资产的地图。

所以它有两个选项可以使用:

  • 它在资产上下文菜单中添加了一个选项“在项目中查找引用”,显示该特定资产具有哪些依赖项。 The resulting window looks like this
  • 还有一个选项可以通过单独的编辑器窗口查找项目中所有未使用的资产。您可以通过指定要忽略的内容的 RegExp 模式来过滤资产以进行分析。

答案 2 :(得分:0)

不幸的是,Unity Editor允许您在“场景”中查找资产的用法。

  • 此外,您获得的是使用它的资产列表,因此更改鼠标焦点后您将失去选择

资产商店有一个解决方案:

  • 在“项目”和“场景”视图中查找资产的所有用法
  • 在单独的窗口中显示结果,显示使用目标资产的特定字段
  • 允许您使用拖放功能替换特定资产使用情况

GIF演示功能和界面:

资产商店链接:

答案 3 :(得分:0)

Unity Answers中有一个脚本,可以很好地完成它。 (也可以轻松地略微调整以改善其功能)

来源: http://answers.unity.com/answers/1509032/view.html

using System.Collections.Generic;
 using UnityEngine;
 using System.Linq;
 #if UNITY_EDITOR
 using UnityEditor;
 public class BacktraceReference : EditorWindow
 {
     /// <summary> The result </summary>
     public static List<Component> ReferencingSelection = new List<Component>();
     /// <summary> allComponents in the scene that will be searched to see if they contain the reference </summary>
     private static Component[] allComponents;
     /// <summary> Selection of gameobjects the user made </summary>
     private static GameObject[] selections;
     /// <summary>
     /// Adds context menu to hierarchy window https://answers.unity.com/questions/22947/adding-to-the-context-menu-of-the-hierarchy-tab.html
     /// </summary>
     [UnityEditor.MenuItem("GameObject/Find Objects Referencing This", false, 48)]
     public static void InitHierarchy()
     {
         selections = UnityEditor.Selection.gameObjects;
         BacktraceSelection(selections);
         GetWindow(typeof(BacktraceReference));
     }
     /// <summary>
     /// Display referenced by components in window
     /// </summary>
     public void OnGUI()
     {
         if (selections == null || selections.Length < 1)
         {
             GUILayout.Label("Select source object/s from scene Hierarchy panel.");
             return;
         }
         // display reference that is being checked
         GUILayout.Label(string.Join(", ", selections.Where(go => go != null).Select(go => go.name).ToArray()));
         // handle no references
         if (ReferencingSelection == null || ReferencingSelection.Count == 0)
         {
             GUILayout.Label("is not referenced by any gameobjects in the scene");
             return;
         }
         // display list of references using their component name as the label
         foreach (var item in ReferencingSelection)
         {
             EditorGUILayout.ObjectField(item.GetType().ToString(), item, typeof(GameObject), allowSceneObjects: true);
         }
     }
     // This script finds all objects in scene
     private static Component[] GetAllActiveInScene()
     {
         // Use new version of Resources.FindObjectsOfTypeAll(typeof(Component)) as per https://forum.unity.com/threads/editorscript-how-to-get-all-gameobjects-in-scene.224524/
         var rootObjects = UnityEngine.SceneManagement.SceneManager
             .GetActiveScene()
             .GetRootGameObjects();
         List<Component> result = new List<Component>();
         foreach (var rootObject in rootObjects)
         {
             result.AddRange(rootObject.GetComponentsInChildren<Component>());
         }
         return result.ToArray();
     }
     private static void BacktraceSelection(GameObject[] selections)
     {
         if (selections == null || selections.Length < 1)
             return;
         allComponents = GetAllActiveInScene();
         if (allComponents == null) return;
         ReferencingSelection.Clear();
         foreach (GameObject selection in selections)
         {
             foreach (Component cOfSelection in selection.GetComponents(typeof(Component)))
             {
                 FindObjectsReferencing(cOfSelection);
             }
         }
     }
     private static void FindObjectsReferencing<T>(T cOfSelection) where T : Component
     {
         foreach (Component sceneComponent in allComponents)
         {
             componentReferences(sceneComponent, cOfSelection);
         }
     }
     /// <summary>
     /// Determines if the component makes any references to the second "references" component in any of its inspector fields
     /// </summary>
     private static void componentReferences(Component component, Component references)
     {
         // find all fields exposed in the editor as per https://answers.unity.com/questions/1333022/how-to-get-every-public-variables-from-a-script-in.html
         SerializedObject serObj = new SerializedObject(component);
         SerializedProperty prop = serObj.GetIterator();
         while (prop.NextVisible(true))
         {
             bool isObjectField = prop.propertyType == SerializedPropertyType.ObjectReference && prop.objectReferenceValue != null;
             if (isObjectField && prop.objectReferenceValue == references)
             {
                 ReferencingSelection.Add(component);
             }
         }
     }
 }
 #endif