且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Editor扩展之查看Prefab用在那儿

更新时间:2022-08-13 22:38:34




Prefab查找需求

在项目开发阶段的中后期,工程中有越来越多的Prefab,当我们要修改一个prefab或删除无用的prefab时,或许我们不是那么清楚该prefab在那些场景中使用着或从未使用过,所以我就写了这么一个小工具,对选中的prefab进行检查。

当然我把这个小工具用于检查UI的prefab,对于其它类型的prefab它可能在任何场景都未使用,是在运行时动态加载的。所以当你要把一个prefab从工程中删除时一定要清楚该prefab是否真的没用

UI结构

这里所指的约束,大概就是比如:工程所有的UI场景都放在同一路径下,比如Asset\UI\xxx,所有UI场景的顶部分层次结构都相同,如下图所示:

Editor扩展之查看Prefab用在那儿 Editor扩展之查看Prefab用在那儿

编写工具

小工具功能

该插件代码主要有两个功能:

1、遍历路径下所有的UI场景,该callback,第1个参数是场景的根节点,第2个参数是路径名

   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场景所有的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的完整路径

 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,

Editor扩展之查看Prefab用在那儿

2、Game和Game1两个场景都使用UpFont.prefab,Game2.unity则创建一个Gameobject的名字也为UpFont,但并没有引用UpFont.prefab

Editor扩展之查看Prefab用在那儿Editor扩展之查看Prefab用在那儿Editor扩展之查看Prefab用在那儿

3、此时我们想知道UpFont.prefab究竟在哪些UI场景中使用了呢?选中UpFont.prefab 执行: 右键/选中的prefab用于哪些场景?

Editor扩展之查看Prefab用在那儿

4、查看控制台的输出

Editor扩展之查看Prefab用在那儿


本文转自赵青青博客园博客,原文链接:http://www.cnblogs.com/zhaoqingqing/p/4727510.html,如需转载请自行联系原作者