zoukankan      html  css  js  c++  java
  • Editor扩展之查看Prefab用在那儿

    Prefab查找需求

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

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

    UI结构

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

    image image

    编写工具

    小工具功能

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

    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,

    image

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

    imageimageimage

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

    image

    4、查看控制台的输出

    image

  • 相关阅读:
    spring boot 打包 jar 实现第三方零配置引用
    spring boot 整合log4j2
    linux cat 模糊查询日志命令
    docker深入浅出
    docker容器为啥一定要前台运行
    李诚云原生技术分享
    k8s中对应的stateful有状态服务的讲解
    k8s networkpolicy网络策略详解
    k8s中IngressIp和egressIp的区别
    技术丨小团队微服务落地实践
  • 原文地址:https://www.cnblogs.com/zhaoqingqing/p/4727510.html
Copyright © 2011-2022 走看看