游戏中关于滚动视图来说是非常常见的功能,NGUI的例子中已经很好的展示给我们了,第一种是用UIScrollView组件实现的。第二中是用UIDragCamera实现的,就是通过移动相机来实现物品列表的相对滑动,第一种比较简单,本文不再赘述,在此记录下第二种的做法说明以便日后查阅
这种方式的实现需要两个相机,一个用于显示普通UI层Camera1,另一相机Camera2用来移动显示待显示列表;
这里我们用到的两个相机都是正交相机,你可以根据项目需求自己修改
每次我们新建工程时,引擎都会自动创建一个MainCamera主相机,这里我们把它当做Camera1用来渲染除滑动显示列表以外的所有UI对象,工程目录如下:
另外在创建一个UICamera(即Camera2)相机用于显示滑动列表如下图
这里我们为上图Camera2添加UIViewport脚本和UIDraggableCamera脚本
UIViewport脚本可以通过指定两个位置用来限制相机渲染到指定相机的特定部分
SourceCamera这里我们设为Camera1
UIDraggableCamera脚本一般和UIDragCamera脚本一起使用,允许你在指定的区域拖动第二个相机
rootForBounds:将用于限制拖拽范围边界的根对象
Scale :应用到拖拽增量的缩放值。设置X或Y为0来拒绝在那个方向的拖拽。
scrollWheelFactor:滚轮在滑动时的动力影响值
dragEffect:拖拽时要应用效果
smoothDragStart:当开始拖动时是否平滑,否则会有一个精确的跳跃
momentumAmount:滑动因子
UIViewport中的TopLeft对象和BottomRIght对象取自Camera1中的对象,两个对象属性信息如下:
接下来我们为Panel对象下的Item对象添加UIDragCamera脚本,表示拖拽该对象可以移动相机,拷贝该Item对象到一定数量
这里设置的DraggableCamera为当前Camera2相机
然后为Panel对象添加表格脚本
用于排列上述item对象
设置调整列表对象的位置,将其放在适当的位置上,本文放在了bg1对象上
为了拖拽方便,这里也为bg1对象添加了UIDragCamera脚本。至此UI界面已全部搭建完毕
最后因为我们是两个相机,因此最好各自负责渲染自己的层对象,借此也整理下Camera属性,方便理解
Clear Flags:
每个相机在渲染时会存储颜色和深度信息。屏幕的未绘制部分是空的,默认情况下会显示天空盒。当你使用多个相机时,每一个都将自己的颜色和深度信息存储在缓冲区中,还将积累大量的每个相机的渲染数据。当场景中的任何特定相机进行渲染时,你可以设定清除标记以清除缓冲区信息的不同集合。可以通过下面四个选项之一来完成:
SkyBox天空盒
这是默认设置。在屏幕上空的部分将显示当前相机的天空盒。如果当前相机没有设置天空盒,它会默认使用渲染设置(在Edit->Render Settings里)中选择的天空盒。然后它将退回使用背景颜色。另外天空盒组件可以添加到相机上
Solid Color 纯色
屏幕上的任何空的部分将显示当前相机的背景颜色。
Depth Only 仅深度
如果你想绘制一个玩家的枪而不让它在环境内部得到裁剪,你要设置一个深度为0的相机来绘制环境,还要另一个深度为1的相机单独绘制武器。该武器相机的清除标记应设置为仅深度。这将保持环境的图形显示在屏幕上,但会丢弃所有关于每个对象在三维空间中的位置的信息。当枪被绘制出来,不透明的部分将完全覆盖任何已绘制的事物,而不管枪到墙之间如何接近。(这部分看起来很费劲)
该模式不清除任何颜色或深度缓存。其结果是,每帧绘制在下一帧之上,造成涂片效果。这不是用于游戏的典型方式,最好是与自定义着色器一起使用。
Culling Mask 剔除遮罩:
剔除遮罩使用层有选择地渲染一组对象。通常好的做法,是把用户界面放到不同的层,然后用一个独立相机单独渲染UI层。
为了使UI显示在其他相机视角的顶部,你还需要设置清除标记为Depth only,并确保UI相机的深度比其他相机高
为了讲Camera2的界面显示在Camera1上,这里我对两个相机的UI层进行了不同命名,方便管理,一个相机对应一组对象
Camera2的层设置类似,这里不再贴图,另外Camera2的Depth属性值要不低于Camera1,否则会被Camera1遮挡
效果图如下:
至此,我们明白了摄像机的Depth、Clear Falgs和Culling Mask的强大作用。
同样的,如果是制作游戏,你可以创建一个界面摄像机,单独渲染界面,而别的摄像机将渲染场景。你只需要添加UI图层,将所有的界面物体的Layer设置为UI,UI摄像机的Culling Mask也只勾选UI层。
注意:由于拖拽部分是先用新相机拍下,然后附加在主相机上的,所以view内的内容不能随着主UI旋转!!!同时也不能放到屏幕外面!!!