最近的工作跟 UI 打交道比较多, 各种坑.

  今天从 Prefab 的序列化功能来说说 System.Diagnostics.Conditional 的妙用.

  我们做 UI 面对各种按钮, 组件的获取方式大致也就两种, 一种直接序列化到 Prefab 中, 另一种是在代码中去获取 :

序列化

tagObj = transform.Find("Child/Cube").gameObject; // 代码获取

  各有各的好处 :

    序列化很直接, 代码都不用写了, 并且随便你拖动 UI 到哪个节点, 都能正确引用. 不过问题也很明显, 过了几天连自己都找不着北了, 有过长期维护经验的人应该了解.

    代码获取的方式从维护性来说, 直接就能让看的人知道那个组件在哪个节点上, 理解起来更简单. 可是如果节点路径发生变更, 就要出问题了, 这在频繁改动的 UI 设计上来说很要命. 特别是如果使用封装好的函数进行安全获取, 就更难发现问题了, 比如:

    // 封装好的函数, 连错都不报
public static GameObject GetGameObject(Transform from, string find)
{
var trans = from.Find(find);
if(trans)
{
return trans.gameObject;
}
return null;
}

  如果从效率的角度来看, 应该是序列化 Prefab 的效率要高于使用代码查找的效率的, 因为序列化对象是一个唯一ID, 而代码查找时 Transform 的子对象是在列表中的, 所以 Find 函数查找效率是跟 List 一样的 :

  这里用 tagObj 引用了自己, 看到序列化对象的 ID 就是指向上面的 m_GameObject 的, 应该就是个内部 GUID 了. 从效率上看略胜一筹, 因为我在之前的项目碰到过有几千个 Child 的节点, 然后通过数据库得到的几千个数据对节点下面的对象进行查找, 那效率简直酸爽, 有这种需求的一定要先厉遍 Transform 把所有节点都放到 Dictionary 里引用啊, 血的教训...

  第二点, 存储大小 :

    如果序列化到 Prefab 里面, 它使用了 ID 作为引用, 增加的存储大小基本是个定值, 并且打包之后还能进行压缩等, 实际占用空间非常小, 而且作为资源它可以热更.

    代码如果写在 C# 中, Find("XXX/ooo") 里面的字符会被放到静态域中, 这就很要命了, 因为到项目后期不仅由于过多的代码, 更多的字符串导致程序包过大, 我们真的碰到过超过 IOS 50多M限制的单个 DLL 问题...当然如果写在 Lua 中的话就跟资源一样了, 你能编译成二进制, 你能压缩, 万能的 Lua. 不过按照一般情况, "XXX/ooo" 字符一般都会比 ID 更长特别是 UI 层级很深的情况, 有中文的时候就更糟了.

  假设我们有了 Lua, 你问问开发人员他们愿意写一大堆 Find 代码, 还是简单拖一拖了事? 因为 Lua 在使用上跟 C# 没有什么不同, 如果使用了序列化谁都懒得再去写代码了... 这真的是少有的 Unity 官方功能比民间方法更牛的特例.

  这样看来序列化真是又简单又高效, 还省空间, 主要问题还是在后期维护上, 比如我们的变量叫 tagObj, 制作的人可能引用的对象名称是 Cube, 名称上完全没有关联性, 在一些不可预知的情况下如果引用丢失了, 连制作者都不知道原来引用的是哪个对象的情况多的是. 我们能把两种模式结合起来的话就好了, 比如在组件上面加个注释 :

  恩, 不错, 还有更好的 :

  System.Diagnostics.Conditional 可以根据编译条件决定是否编译,  它在非编辑器下就跟注释一样是不会加进去的, 而在编辑器下你是可以通过 GetCustomAttributes 获取的, 那么它的用处就大了 :

  1. 在编辑器下检查序列化对象是不是丢了, 丢了的话找 Attribute 然后通过 loadPath 去自动获取.

  2. 在编辑器下检查序列化对象跟 loadPath 的对象是不是一致, 检查数据正确性.

  这些看似简单的功能, 在发布版本之前可能救不少人的命呢, 避免了每次抓人去祭天. 通过这个应用方法添加了一些信息, 并能提供上述功能支持.

测试一下 :

-------- 编辑器 --------

-------- 发布后 --------

System.Diagnostics.Conditional 的妙用 -- 把文档放在代码中的更多相关文章

  1. System.Diagnostics.Conditional

    [System.Diagnostics.Conditional] 指示编译器当特定的宏定义了时,才生成此方法的相应代码.只能应用于AttributeClass.Method. 参考:http://ms ...

  2. 小讲堂:Mobox文档管理软件中的文件外链是什么?

    今天我们来讨论Mobox文档管理软件中的文件外链是什么?熟悉MOBOX的朋友们应该知道,如果有文件需要分享给其他同事,直接可以进行文件共享.对方会在AM的即时通讯客户端有消息提醒,点击消息提醒可以看到 ...

  3. 小讲堂:在线编辑在Mobox文档管理软件中的意义

    今天我们来讨论一下,mobox文档管理软件中的在线编辑的这个功能,相信这个功能是用户在日常的文档维护中非常需要的. 文档管理软件的诸多功能中,在线编辑是一块很重要的功能点,因为在线编辑可以说是提高工作 ...

  4. 利用Gulp实现JSDoc 3的文档编写过程中的实时解析和效果预览

    ### 利用Gulp实现JSDoc 3的文档编写过程中的实时解析和效果预览 http://segmentfault.com/a/1190000002583569

  5. 随时发布:REST API文档的代码仓库中的持续集成与协作

    本文主要内容:API文档提供了预测客户成功的关键路径:在代码附近的文档上进行协作可以更好地检查代码和文档文件,提高自动化效率,并专门针对文档进行质量测试:提供通用文档框架,标准,自动化和工具,以提高团 ...

  6. C#读取Word文档内容代码

    首先要添加引用com组件:然后引用: using Word = Microsoft.Office.Interop.Word; 获取内容: /// /// 读取 word文档 返回内容 /// //// ...

  7. 将word文档A表格中的内容拷贝到word文档B表格中

    Function IsFileExists(ByVal strFileName As String) As Boolean ) <> Empty Then IsFileExists = T ...

  8. 在Eclipse中如何关联spring-framework的文档和源代码

    1.到官方网站去下载spring-framework的jar包 spring-framework jar包的下载地址是:http://repo.spring.io/release/org/spring ...

  9. 开发人员的福音:微软、谷歌、Mozilla将他们所有的web API文档放在同一个地方

    Tips 原文作者:Liam Tung  原文地址:Developers rejoice: Microsoft, Google, Mozilla are putting all their web A ...

随机推荐

  1. js 根据data-i 降序排列

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. oracle 多表查询,请教个问题

    首先,是有一个合同表,对应数据库表 lg_bill_of_lading_detail  简称 bold    有一个用户表 EMT_USER 简称 e 合同审批 后,合同表里  会有一个审核人AUDI ...

  3. php.ini修改php上传文件大小限制的方法

    打开php.ini,首先找到file_uploads = on ;是否允许通过HTTP上传文件的开关.默认为ON即是开upload_tmp_dir ;文件上传至服务器上存储临时文件的地方,如果没指定就 ...

  4. 在C中测试函数运行时间

    #include <stdio.h> #include <time.h> #include <math.h> clock_t start, stop; //cloc ...

  5. elasticsearch数据组织结构

    elasticsearch数据组织结构 1.      mapping 1.1.    简介 mapping:意为映射关系,特别是指组织结构.在此语境中可理解为数据结构,包括表结构,表约束,数据类型等 ...

  6. 【转载】IntelliJ IDEA配置JUnit进行单元测试

    前提条件 安装JDK,并配置好环境变量 工程已解决JUnit依赖关系(pom.xml) IDEA中JUnit配置 IDEA自带一个JUnit插件,打开Settings窗口搜索junit,如图:   图 ...

  7. iOS 开发中常用的排序(冒泡、选择、快速、插入、希尔、归并、基数)算法

    1.冒泡排序: 冒泡算法是一种基础的排序算法,这种算法会重复的比较数组中相邻的两个元素.如果一个元素比另一个元素大(小),那么就交换这两个元素的位置.重复这一比较直至最后一个元素.这一比较会重复n-1 ...

  8. (0)Lora及LoraWAN

    Lora和LoraWAN的区别 LoRa经常被误用来描述整个LPWAN通信系统,其实Lora是Semtech拥有的专有调制格式. SX1272和SX1276 LoRa芯片使用称为chirp扩频(CSS ...

  9. Nginx笔试题!

    1.Nginx实现HTTP及TCP负载均衡的模块?HTTP就是工作在七层协议TCP工作在四层协议 Nginx七层负载:七层通过虚拟的URL或主机名接收请求在server里面配置location反向代理 ...

  10. JAVA语言实现简单登录界面

    程序设计思想: 使用Math.random()方法循环生成6个97~122之间的随机整数(对应ASCII码值‘a’~‘z’),将其转化为char型变量,连接成为一个6位字符串作为验证码输出,提示用户输 ...