Unity3D UGUI
User Interface 用户界面
GUI:优点使用简单,有专一性。缺点:代码繁琐,屏幕自适应差。
常用来当调试工具,还有editor编辑器的开发
UGUI:亲儿子,优点:使用灵活。层级清晰。屏幕自适应。缺点:宽度,高度自适应只有一种。Canvas不容易理解,RectTransform不直观。
NGUI:第三方插件,优点:使用方便(大多功能已集成),自带ITween插件。缺点:层级深度调整困难,不打包图集2d图片无法使用。
UGUI和NGUI目前使用较多,但新项目大多使用UGUI。NGUI在老项目中使用。
UGUI属性:
共有属性
UGUI的渲染顺序是通过排列顺序决定的,谁在hierarchy后面,谁就在屏幕的前面
代码实现:
Pivot UI的轴心点 ,决定位置和旋转的中心点,0,0 是UI控件的左下角,右上角为1,1。该值为比例。
(unity左上角pivot改成center后,UI就不显示pivot,而只显示比例中心,此时UI会按照比例中心旋转,用代码来旋转是旋转的pivot,而不是比例中心。)
没有transform,而是其子类RectTransform。
获取RectTransform的方式,可以通过getComponent获取,或者transform as RectTransform强制转换获得。
Width,height UI的宽和高,数值不能为负数
Posx posy 值是以锚点为中心的自身坐标系,如果锚点被拆分开后,posx,y会被left,top,right,bottom替代,四个值都是到拆分锚点组合的图形的四边的距离,0000会占满锚点组合的图形。此时坐标原点是锚点组成的图形的中心点。
子物体的锚点最大范围就是父物体的大小
Anchors锚点:min,max都为0,0在左下角,1,1,在左上角,min是锚点左下角的锚点,max是右上角的锚点
Ui控件的transform.positiom就是世界坐标的点, localposition的原点也不是锚点,而是父物体的中心点。
Ui控件的transform.positiom和localposition都是transform组件
获取锚点的中心点使用RectTransform对象.anchoredPosition
anchoredPosition是物体到锚点四条边的距离
Canvas
画布负责管理当前属于canvas的所有UI控件,UI只有在canvas下才能可见。
Canvas就是游戏屏幕大小,不能单独调整。
画布可以有多个。
如果canvas选成camera模式(让摄像机渲染ui),camera正交投影高度为图片screen.height/2/piexperunit(100) 。
UI Scaler mode :
Const 自由比例下不会改变ui元素的大小。
Canvas的缩放系数:缩放系数是在原有基础上的像素大小缩放的,小数是扩大,正数才是缩小的,内部进行的缩放方式是除法的操作。但此时无论缩放,ui控件的大小width和height属性始终是真实宽高,不受缩放影响。
所以,任何对UI控件大小的处理,一定要乘以缩放系数。
Scale with screen size:
根据屏幕的一边(高度,或者宽度,不能同时)做自适应缩放元素ui,一般以高度自适应,宽度自己写适应
设定缩放的分辨率比例。手机常用比例:960*640
Canvas的渲染方式:
1、 camera方式:
判断出界:
鼠标拖动:此时世界坐标系和canvas的坐标原点重合,所以ui的世界坐标就是在屏幕上的位置,所以只要将鼠标位置转化成世界坐标给ui的transform.position就可以实现拖动。
2、 overlay方式:
判断出界:transform.x<-(rec.rect.width/2+screen.width/2);
鼠标拖动:此时世界坐标和屏幕坐标的原点重合,世界坐标和屏幕坐标是一样的,所以只要将鼠标的屏幕坐标直接给transform.position即可实现鼠标拖动。
3、 真实的鼠标拖动:
上述办法只能一旦拖动,图片的中心就会变成鼠标位置,为了实现真实的拖动,其实只要计算出拖动位置和中心点的距离,然后实时判断该距离的增量,让中心点也就是transform.position加上增量既可以实现。
代码仅适用于overlay的方式,camera方式需要先将鼠标点击和实时位置转成世界坐标
public class tuodong : MonoBehaviour,IDragHandler,IPointerDownHandler
public Image
Vector2
Vector2
Vector3
public void OnDrag(PointerEventData
dian1 = eventData.position;
Vector3 vv = new Vector3(dian1.x -transform.position.x- v3.x, dian1.y - transform.position.y- v3.y, transform.position.z);算出固定距离发生的增量
transform.position += vv;
}
public void OnPointerDown(PointerEventData
dian = eventData.position;
v3 = new Vector3(dian.x - transform.position.x, dian.y - transform.position.y, transform.position.z);//先用点击位置判断一下点击位置和位置的距离。
}
其实鼠标拖动有一个对应的api,RectTransformUtility(rect的工具).ScreenPointToWorldPointInRectangle(移动元素的rectransform(其实这里要的是一个矩形框,ui的rect都是矩形框),鼠标位置,eventdata下的pressEventCamera,out 返回v3的worldpos);该类可以将屏幕坐标转化成世界坐标并且实时和矩形框内做对比。
该api返回bool,如果当前鼠标位置在移动的元素以内,就返回true,否则为false,常用来判断有没有点击到对应的UI元素。
而且该api可以适应任何摄像机渲染方式,和ui的位置方式,真实拖动时只要计算差量就行了,上述代码内容完全没用。
RectTransformUtility(rect的工具).ScreenPointToLocalPointInRectangle(父物体的rectransform(其实这里要的是一个矩形框,ui的rect都是矩形框),鼠标位置,eventdata下的pressEventCamera,out 返回v2的localpos); 该api把当前坐标转换为父物体的相对坐标位置。相对位置是以父物体(center模式下)矩形的中心为参考,而非轴心点,和archer和轴心点没有关系。
public void OnDrag(PointerEventData
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rec, Input.mousePosition, eventData.enterEventCamera, out
transform.position = worldpos - offset;
}
}
public void OnPointerDown(PointerEventData
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rec, Input.mousePosition, eventData.enterEventCamera, out
offset = worldpos - transform.position;
}
}
Canvas Group
Alpha设置透明度,子物体也会生效
Interactable
Blocks RayCasta阻挡射线
Image
Color:需要叠加到img的颜色
Material:添加材质
Raycast Target:不勾选,UI不能和用户交互(拖拽点击功能都没有了)并且还有穿透的效果(不接受射线检测)该射线不是常规射线,是ui的射线。
Image type:图片模式
Simple正常图片模式
filled是填充
Fill amount 填充方式,0-1,0的时候就没有了。不同的填充方式可以模拟进度条
Sliced.切片模式,设置拉伸区域(在图片sprite edit中修改设置四条切绿色线,以前用过),可用于按钮的中间拉伸而四边不拉伸
Tiled:平铺,图片拉伸尺寸超过原图时,采用重复平铺的模式。
button
interactable : 按钮是否可用,勾上会变灰
Fade Duration :颜色过度时间
Navigation : 按钮导航,可以由键盘控制按钮
Animation动画按钮:
通过动画片段来实现,点击可实现自动
Btn.onClick.Addlistener(方法名);
Toggle
Ison: 打开关闭的选项,对应Graphic开关与否,组合下只有一个toggle能是ison
Toggle Transition:过渡效果,Fade淡出效果,none没有效果
Graphic : 勾选的标志,默认是对勾图形
Group: toggle组,制作单选的效果,将多个放在一个组中。组合下只有一个toggle能是ison
Dropdown
下拉菜单
Label 默认显示的选项内容
Scroll rect:滚动条
事件有一个int 参数,参数是选项的索引
对象.OnValueChanged(函数名);
函数名(int a)
通过索引取选项内容:对象.options[int参数];取到的是一个对象,对象内包含一个图片,一个内容,获取内容应该用对象.options[int参数].text。
Slider
监听事件:
对象.OnValueChanged(函数名);
函数名(float a)
注意,函数参数必须要,不写会报错
当作进度条时,Fill拿出来,不需要手柄,可以将两边的留空给覆盖到
Scrollbar
Handle 滑块,此滑块必须要,和slider不一样
Size 滑块的大小
Numbrer of step:滑块从0-1滑动的步数。一般和value配合使用
UImask
Mask
遮罩组件。
在父物体身上添加img组件和遮罩组件,子物体的图形会按照父物体的图形形状遮罩显示,img必须是带透明通道的图片
Rect mask 2d
以中心点为基准点遮罩,并且是方形的。
Scroll Rect组件
事件接口
引用命名空间,using untiyEngine.EventSystems;
IBeginDragHandler,开始拖动,鼠标不松手,即是不拖动了,事件也不会判断结束
Public void OnBeginDrag(Point);
IEndDragHandler,结束拖动
拖动
IdragHandler,拖动中
自动排版
Layout下的组件
HorizontalLayoutGroup:自动横向布局
Padding:四边的距离,left,right,top,bottom
Spacing:每个元素之间的间隔
Child Alignment 对齐方式
Control child size:勾选这个,配合Layout Element起作用
Child Force Expland : 是否有间隔。
Layout Element :配合LayoutGroup使用,勾选lgnore image不自动调整该元素。
元素过多时的动态扩容:Content size fitter,动态扩容时必须将内容面板的轴心点放在上面。
背包界面
Ui设置:
1、 背包系统需要layoutgroup组件,为了避免物体的UI也被自动布局,所以应该将物体ui上加上layout element组件,使该组件不自动布局。
2、 拖动物体ui时,物体ui应该显示在所有物体之上,由于ugui的渲染机制,只有将物体放在同级最下面才能显示在所有上面,所以实现IbenginDrag接口,每次拖动开始时,将物体ui的父类设置为格子的父类(原物体ui在每个格子内,是格子的子类),并且通过transform. SetAslastSiblingIndex()设置为最后一个。
3、 Eventdata中pointEnter可以获取物体ui移动到了哪个格子。
4、 物体UI身上加上Canvas Group ,拖动物体UI时,勾选掉Blocks RayCasta,就会阻挡射线点击到物品UI(否则pointEnter就会是物体ui自己),但松开拖动物体时,再将Blocks RayCasta勾回来,就可以再点击拖动了。
背包系统
思路:先写Model数据
背包物品的基类:ItemBase{id,name,Count,description,price}
基类按照物品的分类有多个子类:
Equipment:ItemBase装备类:
枚举.类型:{人物属性:攻击力,防御,敏捷等,人物状态:红,蓝}
Asitem: ItemBase 消耗品类
使用数组存储所有背包数据。
背包管理类:bagManager
使用数组存储的背包数据
交换两个格子的物品
删除物品
查找物品
添加物品
ItemUI:背包物品
数量,图,继承itembase,写入
GridUI 背包格子
Index,itemUI(当前格子的物品)
BagWindow 背包窗口,管理整个背包的显示层
Grids 存所有格子
Additem
Removeitem
Fxchangeitem
Useitem
Moveto