问题
The very useful feauture "Find usages" exists in Visual Studio and Resharper, but I can't find the same in Unity3D Editor. I see only "Select dependencies" in Unity3d, but I need the opposite one. Does it exist?
回答1:
Unfortunately, Unity Editor allows you to find usages of an asset in Scene only.
- Moreover, what you get is selected list of assets using it, so after changing the mouse focus you'll lose your selection
There's a solution on Asset Store that does:
- Find all usages of an asset, both in Project and in Scene view
- Demonstrate results in a separate window, showing particular fields that are using target asset
- Allows you to replace particular asset usages with drag&drop
GIF demonstrating features and interface:
- http://imgur.com/a/i72XL
Asset Store link:
- https://www.assetstore.unity3d.com/en/#!/content/59997
回答2:
From the Editor, go to the Project Tab, select the given Asset, right click on it and click Find Reference In Scene. It will show you every GameObject the the given Asset is attached to in the Hierarchy View if the given Asset is a script. If it is an image, audio file or a prefab, it will show you which GameObject is using that Asset in the Hierarchy View.
回答3:
There is this script from the Unity Answers that does a pretty good job at it. (Can also be easily slightly tweaked to improve its functionalities)
Source: 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
来源:https://stackoverflow.com/questions/40172220/unity3d-editor-how-can-i-find-all-usages-of-a-given-asset