作者:赵青青
泰斗原文:http://www.taidous.com/forum.php?mod=viewthread&tid=33427
前言
在项目开发阶段的中后期,工程中有越来越多的Prefab,当我们要修改一个prefab或删除无用的prefab时,或许我们不是那么清楚该prefab在那些场景中使用着或从未使用过,所以我就写了这么一个小工具,对选中的prefab进行检查。
当然我把这个小工具用于检查UI的prefab,对于其它类型的prefab它可能在任何场景都未使用,是在运行时动态加载的。所以当你要把一个prefab从工程中删除时一定要清楚该prefab是否真的没用
相关约束
这里所指的约束,大概就是比如:工程所有的UI场景都放在同一路径下,比如Asset\UI\xxx,所有UI场景的顶部分层次结构都相同,如下图所示:
代码
代码主要有两个功能:
1、遍历路径下所有的UI场景,该callback,第1个参数是场景的根节点,第2个参数是路径名
[AppleScript] 纯文本查看 复制代码
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是同一个实例么? 如果是,输出日志
笔记:
[AppleScript] 纯文本查看 复制代码
//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的完整路径
[AppleScript] 纯文本查看 复制代码
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,
2、Game和Game1两个场景都使用UpFont.prefab,Game2.unity则创建一个Gameobject的名字也为UpFont,但并没有引用UpFont.prefab
3、此时我们想知道UpFont.prefab究竟在哪些UI场景中使用了呢?选中UpFont.prefab 执行: 右键/选中的prefab用于哪些场景?
4、查看控制台的输出