【问题标题】:Unity3D Editor: How can I find all usages of a given asset?Unity3D Editor:如何找到给定资产的所有用途?
【发布时间】:2021-07-08 21:03:00
【问题描述】:

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

【问题讨论】:

    标签: unity3d assets unity3d-editor


    【解决方案1】:

    在编辑器中,转到项目选项卡,选择给定的资源,右键单击它,然后单击在场景中查找引用。如果给定资产是脚本,它将在 层次结构视图 中显示给定资产附加到的每个游戏对象。如果它是图像、音频文件或预制件,它将在 Hierarchy View 中显示哪个 GameObject 正在使用该资产。

    【讨论】:

    • 程序员您好,非常感谢您及时详细的回复,即使有图形!它非常有用,但是(从我的角度来看)对于不是那么大的项目,只有一个或几个场景。不管怎样,总比没有好。))
    • 对于更大的项目,我的意思是当你有超过 3 个用法时,我在场景中使用 Find Usages 时得到的选择不是很有用。此外,它不允许像 Select Dependencies 那样进行项目搜索,所以很抱歉,它并不能完全解决我的问题。
    • 没关系。编码愉快!
    • 当您右键单击对象选项“在场景中查找参考”不存在。只有“在场景中查找引用”
    • 它对我来说已经坏了一段时间了:/ issuetracker.unity3d.com/issues/…
    【解决方案2】:

    不幸的是,Unity Editor 只允许您在场景中查找资产的使用情况。

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

    Asset Store 上有一个解决方案:

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

    GIF 演示功能和界面:

    资产商店链接:

    【讨论】:

    • 我想这只是我在寻找。谢谢!
    • 是否有计划支持 Unity 2018.3+ 和 Unity 2019?
    【解决方案3】:

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

    它由一个脚本组成,因此很容易将其复制粘贴到您的项目中。

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

    所以它有两个使用选项:

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

    【讨论】:

      【解决方案4】:

      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
      

      【讨论】:

      • 感谢您提供源链接!它有一些有趣的 cmets。
      猜你喜欢
      • 2018-12-05
      • 2012-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多