zoukankan      html  css  js  c++  java
  • [Unity3D]UI方案及制作细节(NGUI/EZGUI/原生UI系统)

    转载请留下本文原始链接,谢谢。本文会不定期更新维护,最近更新于2013.09.17。
     
    http://blog.sina.com.cn/s/blog_5b6cb9500101bplv.html
     
     
     
     
    一、方案选择
     
    U3D项目的UI方案总的来说就三个,NGUI、EZGUI、用U3D原生UI。
     
    U3D官方说的新UI系统迟迟不出来,在新UI系统出来之前,任何项目使用U3D原生UI做技术方案的就是找死。那一套可以说未经过任何优化的UI系统简直要让人抓狂,且不说其运行效率,各种STYLE各种SKIN各种位置大小调整属性字体分辨率自适应可以直接让你吐血,UI全程需要程序调节,生产效率极度底下。运行效率也是渣渣……所以本文不讲原生GUI的东西了。
     
    在U3D官方UI支持不给力的前提下,NGUI和EZGUI等各种UI插件开始流行。目前主流也是这两个了,说周围用得最多的话算NGUI无误。
     
    NGUI和EZGUI的大概对比如下(图片来自下面推荐的外文):
     
    [Unity3D]UI方案及制作细节(NGUI/EZGUI/原生UI系统)

    [Unity3D]UI方案及制作细节(NGUI/EZGUI/原生UI系统)
     
    NGUI与EZGUI的详细对比:
     
    http://blog.heyworks.com/choosing-gui-framework-for-your-unity3d-project-ezgui-vs-ngui-part-i/
    http://blog.heyworks.com/choosing-gui-framework-for-your-unity3d-project-ezgui-vs-ngui-part-ii/
     
    可以看出,NGUI几乎完胜EZGUI。本人也建议大家采用NGUI作为目前的第一UI解决方案。别纠结太多啥的。
     
     
    二、UI图片资源管理及优化操作细节
     
    a.图片格式统一采用PNG。
     
    b.切块的大小要跟素材相吻合,不要留太多白空,会占用大小,而且调用会有位置和大小形状不准确的情况。
    虽然说NGUI合并成ATLAS能自动识别透明而自动切,有些大图需要整张直接用的话,需要很好的保证。
     
    c.所有图片命名请规范,自己对项目中的UI模块进行分类。不要所有图都放在一个文件夹,不同部分的图片要求放在不同文件夹,不然找起来也麻烦。
     
    d.区域选择性制图。大张的UI图片是非常占资源的,所以能优化则优化。若背景中间重复度高,只切边角部分,在NGUI中设定让其中心不断重复,实现优化效果。这样非常小的图片也能达到精度很高的效果。设计UI的时候也要考虑这方面事情。
     
    e.若在乎游戏容量的大小,设计前请多吩咐UI的重用度,在尽可能的情况下提高UI的重用度。
     
    f.UI特效的注意规范。3.X版本和4.0版本的特效系统有所改进,所以以4.0的为准。因为特效一般不设计transform的旋转和缩放,所以这个最好将其归为原始值。(这个很难说清,就是U3D粒子4.0对3.5兼容不好。)
     
    g.小的图片资源尽量打在ATLAS图集里面,U3D对用同一MATERIAL对进行批处理,提高渲染效率。当然要自己分好模块。发布前查看ATALS图集是否充分利用好空间,若黑空出来一大片,需要好好考虑下分配了。U KNOW,一张图集若因为几个小东西而翻了一倍的话,那就是多了一倍的空间。例如一张1024*512的图集就有2M,当图集因为一个小图而达到1024*1024大小的时候,这张图就是4M了。整个游戏就增加了2M……听闻图集极限是2048 *2048,超过了会有问题(各种看不到),在配置较低的安卓机子下,图集超过1024 * 1024就是各种黑片片了,所以建议图集大小控制在刚好1024 * 1024。
     
    h.大的图片最好不要放在打包的ATALS图集里面了,多大算大……400*400分辨率以上,当然要分情况考虑,这个值只是我大概打出来的。因为容易出现上述现象。大的图片往往都是UI的背景图片。单独作为一个simple texture的widget来处理比较好。
     
    i.有时你会发现调整深度无效,图片的层次乱了。这要看下你是怎么定义图集的了,深度只在同一图集内有效。若在两个不同图集的,则需要调整Z轴来修改层次。当然也会出现一种尴尬现象,例如你需要定义图集A的一个sprite在图集B的两个sprite之间的情况。此刻调整Z轴也没有办法了,你需要分开图集B的那两个SPRITE。
     
    j.项目时间越长你会发现冗余的图片资源越多,所以需要注意不要的资源就删掉了吧,或者统一放在一个地方,以后方便删,不然以后挺烦人的。也可以自动将无用(没被用到)资源删掉,参考下面的脚本(需要翻墙)。修改一下则能用。
     
    http://zaxisgames.blogspot.com/2012/02/automatically-locate-all-unused-assets.html
     
     
     
     
    三、UI加载、显示隐藏关闭
     
    很多人喜欢直接将UI放到场景里面,不用的UI直接隐藏起来。若项目只有两三个Scenes估计是没什么问题的。不过当你的Scenes达到四五个之后,每当你需要换个UI图片,或者调整下UI你就会觉得格外烦闷了。因为每次你都要点开该Scene,然后找到相应的UI来替换,然后再回到逻辑最初的Scene测试……若效果不好,再重复调……
     
    这样的话可以直接将UI拖出来成为一个Prefab,这样你便可以每次修改拉相应的Prefab出来修改了。不过在多人协作之下容易出错,假设你的UI中引用了(public拖过来的)Scene中的一些物体,某人不当操作上传SVN/ASSETSERVER后很可能会导致空引用,然后开始DEBUG……
     
    倘若你的UI是采用显示隐藏的方法的话,肯定有很多你想调的UI被DisActive了……这时你就要一个个打开隐藏的GameObject……机械的劳动操作简直让人崩溃。
     
    若有多重UI摄像机可能出现的话,一定要处理好层次的关系,规定好哪个摄像机的深度,防止多重UI之后会出现显示层次错乱的问题。
     
    当然不同的项目遇到的情况肯定也不一样,得根据相应的来。
     
    本人建议是一个Scene中可以放置一个UI,并且这个UI被预制成Prefab。然后多做UI模块化。一个部分就是一个模块,尽可能让整体UI的耦合度最小化(关联性尽量少)。采用Resources.Load的方法将定义好的UI模块Load进来显示,若不要的时候直接删掉新加载进来的UI就好。
     
    这里可能会有一个问题就是当两个摄像机同时在的时候,点击会触发到下面那层的UI(原先是盖住的那层)。此刻便需要修改一些脚本使之当启用一个摄像机时,要禁用哪些摄像机脚本。Camera下的UICamera脚本被禁用则不会响应该UI的事件。当然你也可以为每个在最上层的UI加个半透背景,在上面加一层collider,使之碰撞检测不能透过这一层。
     
    UI的模块化好处就是重用UI非常方便,修改方便。
     
    考虑效率的话,可以尝试全局只存在一个摄像机,每次加载场景的时候不删除这个摄像机,需要什么模块LOAD什么模块。
     
    (有人可能会觉得Resource.Load这样的方法第一次加载一个prefab的时候会有lag(延迟),但个人测试UI的这种加载lag没啥关系,东西不大,Load UI的LAG可以接受。)
     
    提示NGUI有几个快捷键:
    Alt + Shift + a 隐藏当前选择的游戏物体
     
     
    四、中文字体(动态字体)方案
     
    网络上很多,我也不多写了,推荐两篇不错的。动态字体对于安卓的支持很有限,经常会有出现不显示字现象。是由于该机型的某些接口有时不灵光导致的,这个解决版本现在貌似还没有,只能换回图集的方式了。
     
    NGUI动态字体教程:
    http://game.ceeger.com/forum/read.php?tid=8965
     
    Dynamic Font for NGUI 2.5.0c,动态字体脚本支持NGUI最新版本:
    http://game.ceeger.com/forum/read.php?tid=9828
     
    NGUI自定义图集和自定义字体
     
     
    五、自适应方案
     

    谈谈UI分辨率适配

      :
     
     
    NGUI有根据高度自适应拉伸UI的自适应调节,若需求不太高直接用这个就好了。
     
    若需求比较高,需要针对不同的分辨率、比例做不同UI调节不同位置的话,则需要自己写一个配置文件了。
     
    大概原理就是做几种比例,同比例用NGUI的缩放。
     
    做好一种比例,写个简单的插件去记录每一个UI的坐标位置和层次关系并序列化到TXT里面。(若你要换图的话,需要记录的信息就更大了。)
     
    然后调好另一种比例再点用下这个插件。
     
    然后根据不同的分辨率比例读取不同的配置文件,再还原坐标和选择相应图片则可。
     
    这样会有一些资源上的浪费(多了其他分辨率所不需要用到的资源),要求更高的话,还是不同分辨率导出不同的吧……
     
     
     
    六、多语言方案
     
    1.做不同语言的UI,为每种UI导出一个版本。
     
    2.做切换语言,方法同上。记录所需要替换的坐标和位置和层次关系等,记录对应要换的语言UI。直接改sprite中的spriteName来实现UI变换。其实要记录的东西并不多,因为手游UI往往按键不多。
     
     
    七、自动化UI的流水生产方案
     
    其实这个才是程序员最该搞的,但短期内做这个回报价值是非常低的,因为你要去研究很多东西。大家这段不看也没问题,大部分项目都不需要用到。
     
    当你发现UI的位置大小竟然要程序员来调,不会觉得很奇怪么?UI修改了一个按钮颜色,需要程序员来调。程序员一般都忙,忙完手头上的东西,然后搁置半天时间再调。调完了再通知UI。期间的沟通成本是很大的。有人说可以单独请一个专门做UI资源对接的人,确实是可以,但每个项目都要一个专门负责这个的人感觉有点浪费。让UI去学U3D这个引擎的NGUI部分?即便UI会调,你不怕他不小心动到其他资源么?还要让他学习U3D版本控制的概念。
     
    那么我们来考虑一下,是否UI设计人员在不懂U3D不用U3D引擎的前提下,是否也能自己改游戏的UI?
     
    因为这个模块有点大,不打算细讲。
     
    大概操作方法:
     
    1.UI设计好的图片导出一个个切片。
     
    2.将切片全部放到开发工具,让其自动打成一个图集,并且为每个精灵起好名字。(目前已经有类似插件,生成出来的图集能无缝对接NGUI,名字我忘了,记得的时候再修改,有知道的话提醒下。)
     
    3.UI在一个工具上用刚生成的图集的元素摆出相应分辨率的UI,然后点击输出信息。将整个布局信息输出。
     
    4.程序将图集加入U3D后,根据刚UI生成的信息。用已经写好的脚本还原和更新UI新修改的东西。
     
    这样可以将UI和程序的职责分开,UI专心UI,程序专心程序,沟通直接迅速,操作方便。
     
    开发这一套东西代价是非常大的,很多细节都需要考虑到。例如函数调用的配置方式,动态加载模块的资源处理等等。不过对于流水生产是很有帮助的。
     
    目前已经有类似插件出现了,名字叫FastGUI,是NGUI的扩展插件。实现了上面不少功能。
     
    (完)
     
     
    FINALLY,
     
    若文中有不当请指教,相互交流学习。
     
    联系:xuzhiping7#qq.com

     

  • 相关阅读:
    Selenium简单测试页面加载速度的性能(Page loading performance)
    Selenium Page object Pattern usage
    Selenium如何支持测试Windows application
    UI Automation的两个成熟的框架(QTP 和Selenium)
    分享自己针对Automation做的两个成熟的框架(QTP 和Selenium)
    敏捷开发中的测试金字塔(转)
    Selenium 的基础框架类
    selenium2 run in Jenkins GUI testing not visible or browser not open but run in background浏览器后台运行不可见
    eclipse与SVN 结合(删除SVN中已经上传的问题)
    配置Jenkins的slave节点的详细步骤适合windows等其他平台
  • 原文地址:https://www.cnblogs.com/123ing/p/3789081.html
Copyright © 2011-2022 走看看