1.保存方式:
所有的面板,弹出窗口等都保存为prefab,并且按模块来划.比如:
竞技场下模块下有3个窗口,就划分为3个prefab,都放在同一个文件夹下面。
2.Panel组件:
所有的面板或窗口的都是用UIPanel组件,比如背包窗口就是一个Panel,任务窗口也是一个Panel,有些大的窗口还划分为2-3个Panel.为什么窗口都是用Panel而不是使用Sprite或Widget组件呢?我在我上次写的一篇文章中(http://www.cnblogs.com/rocky300/articles/4667213.html)提到过,NGUI为了减少DrawCall数量,Panel中会把相同Materail的widget的drawcall合并,所以从理论上讲一个项目中使用的UIPanel越少就越能减少DrawCall的数量,既然如此,那为什么这个项目中还要使用那么多的Panel组件?这个问题一开始我也很迷惑,后来网上查了一下资料我弄明白了,有时候项目中的不是一味的最求减少DrawCall就行的,Panel中集成的Widget越多,那么当其中一个很小的控件发生变化的时候,很可能要引起其他使用相同DrawCall的控件重新检索自己的顶点,UV,颜色,位置,大小等信息,简单说就是一个控件变化,导致多个控件重新遍历它们的信息。这部分代码是非常消耗CPU的,通过中划分Panel的方式能减少CPU的消耗,为了在CPU和GPU之间找平衡,多增加几个DrawCall影响也不是很大。
3.窗口管理:
使用一个单例类UImanger来统一管理所有的窗口,比如加载窗口,显示,隐藏等等.
下面是显示窗口的部分经过简化的代码:
//判断窗口是否缓存在字典里面
if (!lookUp (wndName))
{
//加载窗口的Prefab
GameObject wndPrefab = Resources.Load (wndName) as GameObject;
//实例化窗口对象
wndObj = GameObject.Instantiate (wndPrefab) as GameObject;
wndObj.transform.localScale = Vector3.one;
wndObj.transform.parent = root.transform;
//保存在字典里面
save (wndName, wndObj);
}
else
{
//从字典取出
wndObj = getUI(wndName);
wndObj.SetActive(true);
}
4.图集:
图集的划分:
一.按模块来划分:主界面,背包,任务,技能,副本,奖励,对话等等,每个模块来独有的UI都划分为一个图集,一个窗口通常是512*512,大的用1024*1024,不过这也不是固定的,也有512*256,256*256之类的,这个根据具体情况来定。还有一些特定的情况下用到的UI分到个单独的小图集,比如战斗中提示之类的字,这些只在战斗时出现,虽然也属于战斗模块但并不是很战斗界面一起的,如果和战斗相关的模块中合在一起那么战斗只是显示一个提示文字,可能就要加载一个很大的图集这样就没必要了,而且战斗中一般不打开其他窗口的,所以这样分还挺合理的。
二.按照功能划分:公共按钮图集 公共背景图集(穿插文字,数字,提示) 技能图标图集 装备图集 物品图集等等。
这种划分方式我知道算不是是最优,但我觉得还是比较合理的。比如,如果不划分出公共按钮这个图集,假设按钮1,按钮2,按钮3分别放在3个不同的图集里面,那么A界面要同时使用3个按钮的时候,就要加载3个按钮所在图集,如果它们都集成在同一个图集里,那么就只需要加载一个了。还有公共背景图集,背景图通常稍大,所以非常适穿插一些小图。
通过分析代码,发现实际项目中使用NGUI还是有很多通用规则的,当然还有很多细节还没去研究,好了,就总结到这里吧。
原文地址:http://www.cnblogs.com/rocky300/articles/4670152.html