Unity点击Apply查看Prefab节点个数并检查是否有路径相同的子物体
发表于2018-07-17
在游戏开发内,UI和程序沟通问题在缺少集成工程师或者技术美术的情况下,往往是游戏开发过程中的一个大问题。
因为在游戏项目整个的流程开发中,要么是初级UI负责拼UI,要么是初级程序负责拼UI,很少有专门的集成工程师去做相关工作,而初级UI或者是初级策划拼凑出来的UI界面,emmm,往往又不是那回事,总归不能生成对应的Prefab之后做好功能再运行看看有没有什么问题吧(策划:那要你们程序干嘛....)
所以在本文中将主要介绍,如果在Unity中建立Prefab的点击Apply的情况下,在控制台输出对应的Prefab节点个数并检查是否有路径相同的子物体。
这样的话,如果在UI界面出来之前,不符合规定的内容,多余的沟通工作,可以先行避免。
世界和平...
贴上来在实际操作时所编写的代码:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; public class FindNodeCount { Transform trans; static int nodeCount; static List<string> nameLs = new List<string>(); static string sameError = ""; static int count ; static Dictionary<string,int> nameDic = new Dictionary<string, int>(); /// <summary> /// 通过递归的方法得到整体节点个数 /// </summary> /// <param name="t"></param> /// <returns></returns> private static int CheckNode(Transform t) { foreach (Transform item in t) { ++nodeCount; CheckNode(item); } return nodeCount; } /// <summary> /// 对于静态类型的节点数目初始化设置为1 /// </summary> private static void SetNodeCount() { nodeCount = 1; } /// <summary> /// 对于静态类型的名字字符串字典初始化设置为空 /// </summary> private static void SetNameStrs( Dictionary<string, int> nameDic ) { if (!nameDic.IsNull()) nameDic.Clear(); } /// <summary> /// 得到Prefab的全路径 /// </summary> /// <param name="childTrans"></param> /// <returns></returns> private static string GetPath(Transform childTrans) { string name = childTrans.name; Transform trans = childTrans; while (trans.parent != null) { trans = trans.parent; name = string.Format("{0}/{1}", trans.name, name); } return name; } /// <summary> /// No.1:通过递归的方法把Pre里面所有节点的全路径插入到字典的键中 /// 并依据字典中不能含有两个重复键的属性进行判断和检测 /// </summary> /// <param name="t"></param> private static void AddName( Transform t ) { if (t.childCount > 0) { foreach (Transform item in t) { //对于字典的属性不能存在两个相同的KEY //所以存在相同的KEY就是路径一样 if (nameDic.ContainsKey(GetPath(item))) { Debug.Log("The Same Node:" + GetPath(item)); } else nameDic.Add(GetPath(item),0); AddName(item); } } } /// <summary> /// /// </summary> /// <param name="nameLs"></param> private static void SetNameLs(List<string> nameLs) { { if (!nameLs.IsNull()) nameLs.Clear(); } } /// <summary> /// No.2:通过递归的方法把Pre里面所有节点的全路径插入到列表中 /// 并遍历通过Contains的方法查看是够含有重复元素 /// </summary> /// <param name="trans"></param> static void CheckSameName(Transform trans) { for (int i = 0; i < trans.childCount; i++) { if ( nameLs.Contains( GetPath(trans.GetChild(i)) ) ) { Debug.Log( GetPath(trans.GetChild(i)) +"\n"); } else { nameLs.Add(GetPath(trans.GetChild(i))); } CheckSameName(trans.GetChild(i)); } } //点击Apply出现的对应方法 [InitializeOnLoadMethod] /** Checking for updates on startup */ static void StartInitializeOnLoadMethod() { PrefabUtility.prefabInstanceUpdated = delegate(GameObject instance) { SetNodeCount(); Debug.Log("Prefab Node Count:" + CheckNode(instance.transform)); //第一种思路对应代码 SetNameStrs(nameDic); AddName(instance.transform); /* 第二种思路对应代码 SetNameLs(nameLs); CheckSameName(instance.transform); */ };}
在在代码里实现了比较多的小tips,比如:
检测子物体的全路径;
递归得到物体的节点个数;
总体来说,只是在实际开发中提供了一种思路,在注释里有很详尽的解释,不再赘述。
这样,最后就可以很方便的得到节点个数和相同路径子物体的路径信息了。
一旦节点总数超出了预警(比如500)或者是当一套界面具有很多节点,程序人员或者美术人员很难肉眼查看出来的时候有无重复节点信息的时候,运用此段代码可以很好地进行检测和查看。