被NGUI折磨中的攻略心得

发表于2019-07-15
评论0 4.6k浏览

  到新公司负责NGUI的工作,在目前几乎没有他人的帮助下,只得一边摸索一边完成工作。现将遇到的问题记录下来,一是加深自己的印象,二是也许能帮到其他学习者,毕竟目前网上NGUI相关系统的教程太少了。

(所使用的NGUI版本是3.7.0以上)

 

分享下获取过来的英文教程,此教程使用的NGUI版本虽然比较旧,但主要功能都有较好介绍,老外甚至用NGUI做了一个简单的小游戏~~

http://pan.baidu.com/s/1pKf88iB

 

h1t6EhOqisNTu3RJSZZC.jpg

Problem 1:U3D初始开启了默认的天空,曾找了半天找不到哪里可关闭和更换,其实打开Window-Lighting中即可设置。

 

 

problem2:在摆UI时,开始没有注意各个节点的坐标,导致设计视窗和运行视窗中看到的结果不一样,其实是节点Z轴没有统一。所以要么就用2d模式,节省调节坐标,要么就要把各节点坐标调好。在Hierarchy中,资源可看做以节点的方式组织,结构关系十分像程序中的父类和子类。当在一个名叫Wnd的panel父节点下放置其它如Sprite的子节点,那么子节点就继承了父节点的坐标系,子节点的坐标就变成了相对坐标。

y17rrp7Udyo7uYSv0F6h.png

problem3:用NGUI的atlas maker和Font maker制作bmpFont和图片混合的图集时,遇到过图上问题,报错且一直updating,是说图集中部分内容被挤出去了,生成失败。一个原因是时,没有勾remove empty选项,导致空白占用了过多空间(而且似乎一张文字图集达到2048*2048的尺寸时就容易报错)。还有一个原因尚不清楚,即使勾选了remove empty选项照样报错。这样我的做法是,先把图片生成一个图集,再选取生成好的bmpFont,右键打开图集管理,点击update到这个图集中,然后还要注意把Font的字符定位文件xx.txt再次导入到整个图集的预制中,完后之前Font的材质球则可删除。

 

BoYm2xCZcrEf7WQHNm4n.jpg

problem4:点击选取的节点,ctrl+6打开动画编辑面板,做好一段动画后顺利地播放,然后在其子节点再ctrl+6编辑动画,播放......结果发现把先前做的动画覆盖了。只要稍微注意就好,因为子节点默认是有父节点动画的,子节点要自己挂上一个animation或animator组件,才可做自己的动画。

 

tBnzYNj0L2Wi6if3nfvH.jpg


 problem5:在制作动画的时候,需要做一个移动+透明度渐变的过程。之前在节点属性上挂着NGUI Tween系列的Tween Alpha脚本,然后在动画面板上引用。播放结果是正确的,但是在实时游戏中,Tween Alpha只能作用一次。原因是Tween系列脚本不能通过动画反复播放,似乎是动画不会重置Tween?它单独挂在节点上是可以反复的。因此把Tween Alpha脚本替换为Animation Alpha就ok了。

 

oKwj5hIQfKppDbrqkjwI.png

problem6: 在使用table的时候,给table下的其它子节点增加了一个tween scale这种改变table元素位置的脚本,结果子对象发生了偏移,破坏了原有的对齐。原因是table下的所有子节点需要初始保持坐标一致,然后直接通过table的alignment或者spacing x/y等等设置来修改,不要手动一个个来调节,否则容易发生不可测的变动。(后来发现,table中子节点如果被隐藏,而又勾选了Hide Inactive选项,会导致对齐发生偏斜)。

 

ymaICbNyBOL3eNBbbDu9.png

problem7:NGUI的toggle组件。这个组件也和什么label,button等等一样,只需挂在一个gameobject上,调整参数就ok。最重要的修改,是toggle的Group、State of 'None',以及Starting State三项,其余的按默认设置是ok的。

*Group:表示当前UI中,会把group相等的toggle关联起来,使其互斥。

*State of 'None':表示点击toggle本身,也可在checkmark和background中进行切换。

*Starting State:表示该toggle是本界面中默认被选取的,通常仅有一个toggle会被勾上。

 

YwR7LlY5stEqlOLToWiR.png

problem8:通过Tween Scale和Play Tween来配合,使点击某个gameobject就可下滑出隐藏对象的尺寸变化动画。Trigger condition 原是On Click,Play direction设置为toggle,但需要使若干个目标进行互斥,这样设置是不行的。而把触发事件改成On Select便可使其互斥,但是会有bug,多点几次就会发现这些对象变得乱七八糟。 后来把play direction改为forward 就ok了。但整体效果还是不够好,所以点击按钮拉出下滑条的效果,要么用动画做,要么写脚本。

 

 problem9:NGUI的根节点,UIRoot将把子节点的Scale强制设置为1,这样无法将UI组件整体大小自由调节,后来发现只需改变子节点中的子节点即可。UIRoot是要控制屏幕自适应的,所以手动不能更改。

 

problem10:对新手来说,项目保存会一时纠结不清。在场景中创预制,是需要将预制做完后要手动拖入project中。并且U3D中包括预制,有三种保存方式,分别是save scene,save project,以及预制上的apply。save scene是保存当前场景状态;project则是整个工程,而预制的话必须点击inspector面板上的apply来保存更改。有时将预制拖入其它预制中,做了更改,点击apply会发现该预制没有被保存,只得重新拖入project中覆盖掉之前的。

 

u1TntRtji91x1WweMdT0.png

problem11:FBX模型的使用,导入FBX格式模型至project中,然后可以像prefab一样使用,但是这种方法用在UI上会比较耗性能,因为模型通常开销大,且质量越高越甚。Ctrl+6可以看到Animation下的模型动画设置,非常复杂,不过不需要自己手动调,因为这些都是从相关3D软件中读取出来的。

 

hfcJKs3QsTDFkpgwUMXJ.png

 problem12:Window-Aniamtor打开animator的设置界面,可以在试图中创建动画块,以及连接动画块来确定多个动画之间的转换逻辑关系。本动画系统比老动画系统更加高级,但实际上手亦不难,只需自己多动手足可。

 

S6OwGxkVL7kEiOIaJSp0.png

problem13:父节点挂着boxcollide导致的子节点收不到事件响应。因为每个panel都有自己的层级,不同的panel间是无法点击穿透的。如果一个panel是用做二级界面弹出框,它自带一个全屏的boxcollide,则可防止点击穿透到其下面panel的UI上。另外如果在一个scroll view组件中,如果在scroll view的panel上挂了drag scroll view组件来响应滑屏效果,那么其下面挂着的子节点上无法再挂drag scroll view组件,会有冲突(目前最好的做法,是在下面子节点上挂drag scroll view,然后调整布局,使其滑动顺畅)。

 

g24fW67gJuczjpPnupDN.png

problem14:Panel上Clipping的诡异问题,刚接触Scroll View组件弄出的问题,一般来说应该遇不到。如图左侧Sprite超出裁剪区域一半了,却没被裁剪,只有全部超出才被裁剪。这个问题纠结很久,后来才发现其实是shader的问题。NGUI自带了很多shader,其中有一系列shader(Transparent colored 1、2、3,Transparent colored(TextureClip)......)是负责透明像素的处理,而panel的裁剪则是运用了这些shader,图上问题正是个别shader丢失导致的。

 

oX2dhyLKdOBzSeRBEfpr.png

problem15:逗逼的AtlasMaker对话框,如果要大量通过点取删除单个精灵,那么一不小心点在Scene视图上则所有选取消失(其它的地方貌似ok,貌似是个bug),因此不要尝试一次性全点完后作删除。

 

qm4T8BdUgPvn2V7UbTss.png

problem16:多个tween系列的动作,无论是挂在一个gameobject上,还是多个,如果需要让这些动作连续,在Inspector编辑面板上貌似只能通过Start Delay方式来实现。

 

WF79CIzQO6CU8dVwQahv.png

problem17:button和sprite同时挂载一个gameobject上,会有bug,导致功能异常。一般Sprite放到Button下。

 

04hlDKQT4l3J8C1mlUbH.png
hcu7lqoFQvg0M3lNojrl.png

problem18:一般来说,ScrollView的参数不需要手动更改,除了Movement和Cancel Drag If Fits。它们一个是控制垂直还是水平滑动,一个是控制但ScrollView的panel显示区域中,子对象没有超出该区域时,不让其拖动,不勾选则反之。然而有时就放一个子对象进去,也能滑动,其原因要注意子对象身上的各种ui元素,是否超出了区域,可看到UI周围的黄线,就是代表UI中的widget实际所占的一个区域大小。

 

1kQ8H9db19fBlAwSDOfC.png

problem19:关于UI性能消耗问题,可以在做UI时,打开states查看相关的Batches(即为DrawCall,每帧UI需要被底层directX绘制多少次),以及更详细的打开Window/Frame Debugger来追踪。Drawcall消耗问题,之前听说单个widget的depth不同,将引发额外的DC,实际上并不是这样,而是引用了不同图集,然后再设置depth这种影响渲染优先级的操作,就将导致取相同图集中的Sprite也会额外多出一个DC,如图sundryAtalas用了两次DC。

 

Vx2wOK66cIN2R0vQxx1U.png

一个好习惯:在摆UI时,先保存一份公共的模板,然后通通Copy and paste过去,这样既轻松,又避免了手动调整带来的误差。
 

dLVeIKnQXoq4OBdy2BZH.png

另外在使用各种NGUI组件时,可以通过它提供的模板工具来做,只需选择预设好的模板,点击一下就创建出了对象。十分方便,而且也避免了手动去统一调整。本人之前不知道有prefab toolbar,一直用的legacy widget tool。而新的prefab toolbar更好,可存储自己做的一个模板,然后用的时候copy出来,推荐使用这个。

Dk6et0ljJ5MeAdHvwQvc.png

UIButton的系列组件,目前我用的最多的是Button、Button scale。其余的之前都被我无视了,其实有一些都很不错的,如Button Activate,可以控制一个GameObject的显/隐,Button drag 可以控制一个scroll view的点击滑动,Button Rotation可以使按钮增加旋转效果。

 

LyECQEbCZQutK0F2u5rJ.png

NGUI组件上系列回调接口,如图的On Click,可以自己编写一个函数,然后直接挂上去,NGUI组件会自动根据条件来执行。这其实是非常不错的一个功能,虽然多半是程序的事,但作为策划,或者UI设计人员,可以让程序写完一些功能,然后自己挂上去。

  • 允许他人重新传播作品,但他人重新传播时必须在所使用作品的正文开头的显著位置,注明用户的姓名、来源及其采用的知识共享协议,并与该作品在磨坊上的原发地址建立链接
  • 可对作品重新编排、修改、节选或者以作品为基础进行创作和发布
  • 在以作品基础上创作的演绎作品上适用相同类型的知识共享许可条款

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

标签: