【Editor】查看Prefab用在哪些场景

2015年09月23日 14:08 0 点赞 0 评论 更新于 2025-11-21 19:02

作者信息

作者:赵青青

原文链接

泰斗原文:http://www.taidous.com/forum.php?mod=viewthread&tid=33427

前言

在项目开发的中后期,工程中会出现大量的Prefab。当我们需要修改某个Prefab或者删除无用的Prefab时,往往不清楚该Prefab在哪些场景中被使用,甚至不确定它是否从未被使用过。为了解决这个问题,我开发了一个小工具,用于检查选中的Prefab的使用情况。

需要注意的是,这个小工具主要用于检查UI的Prefab。对于其他类型的Prefab,它们可能是在运行时动态加载的,在任何场景中都不会直接引用。因此,在从工程中删除一个Prefab之前,一定要确保它确实没有被使用。

相关约束

这里的约束条件指的是,工程中所有的UI场景需放置在同一路径下,例如Assets/UI/xxx,并且所有UI场景的顶层层次结构相同。

代码实现

1. 遍历路径下所有的UI场景

此功能的主要作用是遍历指定路径下的所有UI场景,并对每个场景执行回调操作。回调函数的第一个参数是场景的根节点,第二个参数是场景的路径名。

public static void LoopUIScene(Action<Transform, string> uiWindow)
{
// 当前工程的全部UI场景放在Assets/UI/TestScene下
foreach (var uiScene in Directory.GetFiles("Assets/UI/TestScene", "*.unity"))
{
EditorApplication.OpenScene(uiScene);
// TODO 补充判断异常,是否为空
var uiRoot = GameObject.Find("Window").transform;
uiWindow(uiRoot, uiScene);
}
}

2. 查找当前UI场景中是否引用了选中的Prefab

该功能会检查当前UI场景中的所有GameObject,判断它们是否为Prefab实例,并且是否与选中的Prefab是同一个实例。如果是,则输出相关日志。

// transform是在Hierarchy视图的,转成project的prefab
UnityEngine.Object parentObject = PrefabUtility.GetPrefabParent(child);

[MenuItem("Assets/选中的Prefab用在哪些场景?")]
private static void SearchPrefabReferences()
{
// 确保鼠标右键选择的是一个Prefab
if (Selection.gameObjects.Length != 1)
{
return;
}
// 遍历所有游戏场景
LoopUIScene((uiRoot, uiName) =>
{
// 获取场景中的所有游戏对象,包括隐藏的
var childs = uiRoot.GetComponentsInChildren<Transform>(true);
foreach (Transform child in childs)
{
// 判断GameObject的type是否是Prefab的引用
if (PrefabUtility.GetPrefabType(child) == PrefabType.PrefabInstance)
{
// transform是在Hierarchy视图的,转成project的prefab
UnityEngine.Object parentObject = PrefabUtility.GetPrefabParent(child);
string path = AssetDatabase.GetAssetPath(parentObject);
// 判断GameObject的Prefab是否和右键选择的Prefab是同一路径。
if (path == AssetDatabase.GetAssetPath(Selection.activeGameObject))
{
// 输出场景名,以及Prefab引用的路径
Debug.Log("场景名: " + uiName + "  引用路径: " + GetGameObjectPath(child.gameObject));
}
}
}
});
}

3. 获取GameObject的完整路径

此功能用于获取指定GameObject在场景中的完整路径。

public static string GetGameObjectPath(GameObject obj)
{
string path = "/" + obj.name;
// 一直往上找
while (obj.transform.parent != null)
{
obj = obj.transform.parent.gameObject;
path = "/" + obj.name + path;
}
return path;
}

使用步骤

  1. 创建三个UI场景,同时创建一个名为UpFont.prefab的Prefab。
  2. GameGame1两个场景中使用UpFont.prefab,在Game2.unity场景中创建一个名为UpFont的GameObject,但不引用UpFont.prefab
  3. 若想知道UpFont.prefab在哪些UI场景中被使用,选中UpFont.prefab,然后右键选择“选中的Prefab用在哪些场景?”。
  4. 查看控制台的输出结果,即可了解UpFont.prefab的使用情况。

作者信息

洞悉

洞悉

共发布了 3994 篇文章