Unity3D编辑器:如何查找某个资源的所有使用情况?

10

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

5个回答

17

从编辑器中,前往项目选项卡,选择给定资产,右键单击它,然后单击在场景中查找引用。如果给定的资产是一个脚本,它将在层次结构视图中显示与之关联的每个游戏对象。如果它是一个图片、音频文件或预制体,则它将显示使用该资产的游戏对象在层次结构视图中。

输入图像描述


程序员你好,非常感谢你的及时和详细的回复,甚至还附上了图形!这非常有用,但(从我的角度来看)对于不是很大的项目,只有一个或几个场景,它就足够了。无论如何,这比没有要好得多。)) - user2018103
通过“更大的项目”,我是指当使用场景中的“查找用法”时得到的选择对于具有超过3个用法的情况不是很有用。此外,它不允许像“选择依赖项”那样进行项目搜索,所以抱歉,它并没有完全解决我的问题。 - user2018103
没问题。愉快编码! - Programmer
当你右键单击一个对象时,不存在“在场景中查找引用”的选项。只有“在场景中查找引用”。 - Alan Mattano
这个问题对我来说已经有一段时间了 :/ https://issuetracker.unity3d.com/issues/find-references-in-scene-shows-objects-that-are-not-referencing-the-asset - DShook

15
这里有一个免费且开源的工具 Dependencies-Hunter,它可以找到给定资源的所有依赖项/使用情况。它还可以执行完整的项目分析,以找到其中所有未使用的资产。
这个工具只包含一个脚本,所以将其复制粘贴到您的项目中非常容易。
在内部,它使用AssetDatabase.GetDependencies来构建所有用于分析的资产的映射表。
因此,它有两种使用选项:
1. 它在资源右键菜单中添加了一个“查找项目引用”选项,以显示特定资源的所有依赖关系。 生成的窗口看起来像这样 2. 还有一种通过单独的编辑器窗口查找项目中所有未使用资产的选项。您可以通过指定要忽略的RegExp模式来过滤要分析的资产。

只需在“Packages/”中的“manifest.json”文件中添加"unity-dependencies-hunter": "https://github.com/AlexeyPerov/Unity-Dependencies-Hunter.git#upm",在我的情况下,Unity会在保存后自动加载该软件包。 - ChrisoLosoph

5

很遗憾,Unity编辑器只允许您在场景中查找资产的用法。

  • 此外,您得到的是使用它的选定资产列表,因此在改变鼠标焦点后,您将失去所选内容

Asset Store 中有一个解决方案:

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

演示功能和界面的 GIF:

Asset Store 链接:


我认为这正是我在寻找的。谢谢! - user2018103
是否有支持Unity 2018.3+和Unity 2019的计划? - piojo
更新的链接(因为我无法编辑答案):https://assetstore.unity.com/packages/tools/utilities/asset-usage-finder-59997 - Graeme Rock

3
这里有一个来自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

1
感谢您包含源链接!它有一些有趣的评论。 - ShawnFeatherly

2
上述解决方案实际上是错误的。Unity确实支持在项目视图中查找资源的引用,但没有相应的按钮。您需要手动在项目视图搜索栏中输入查询:“ref:Assets//”加上文件扩展名。这与您在场景视图中查找引用时放入的查询完全相同。Unity需要一些时间来“思考”,但最终会输出有关您的资源/脚本的引用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接