最近成为了底层拼图仔,对一些Unity中UGUI遇到的问题进行一下总结。 以下内容均在Unity2017.4中实现
许多UI中都可能需要实现可上下拖拽的列表功能,比如手机QQ中的聊天列表以及浏览器的上下拖拽显示内容列表。脑中有了大致的实现效果,便可以搭建起来了。
所以我们先初步要实现一个列表的效果就是:
假设列表中每个信息都是一个item,每接收到一个item,则会在原有列表中的item下方生成(竖直排列),并且我们可以通过拖拽(鼠标)来上下翻阅,类似于如下图所示
UGUI中提供了一个很方便的方法可以让我们快速搭建。在场景中右键找到"UI"->"Scroll View"即可,这个时候我们就会在场景中看到这样的结构
主要是三层结构: ScrollView -> Viewport -> Content
我们来具体看一下设置,点击场景中的Scroll View,看其属性面板
主要用到的组件就是Scroll Rect
再看一下其子物体Viewport下组件
这个Viewport帮我们限制了列表的具体能看见的范围大小,其中的Mask组件帮我们遮罩掉超出Viewport范围的Content,学过PS的应该知道这个和蒙版是差不多的意思
再看一下Viewport下子物体Content的组件
这边用到了一个竖直布局组件 我们生成的item都应该为Content的子物体,这个组件会对每个子物体进行竖直排列,里面比较有关的的一个设置就是Spacing,表示间距
看到这里是不是以为大功告成了呢…我们试着把新建的Item加入至Content中如下图所示
启动一下,会发现一个问题,也是一开始遇到的第一个坑:
一开始想解决思路的时候,最粗暴的方法就是每次增加一个item,对应的Content中Rect Transform的Height属性也相应增大一定比例,当然脚本写起来其实也非常简单的了。
之后去网上查阅了一些方法之后,发现一个比较简答的方法,那就是添加Content Size Fitter组件!
我们为Content添加上这个组件,并在Vertical Fit中选择Preferred Size,会自动根据子物体的范围为我们规划所需要的大小,如下图
当我们再次运行时,就不会有之前的问题了! 想翻到哪里就翻到哪里,不会拖了一会就弹回起点
我们经常在创建出Text后,会为Text设置一个较长的宽度,保证在输入Text文本时,文字能在宽度范围内显示出来
这个时候Content Size Fitter这个组件又出马了! 我们为带有Text组件的物体再添加Content Size Fitter
这个时候我们添加文本内容时,就无需担心是否超出宽度范围,当然如果你是跟着我一起做到这步,你会发现一个小问题:
当我们修改此文本内容的时候,其动态增加的宽度是从两边同时出发的,这肯定是跟我们的需求是违背的。
我们要的效果应该是文本添加时,只从一个方向(假定往右)进行宽度增加。解决这个方法也非常简单,只需要将我们这个物体的pivot坐标设置为0, 0即可
最近做到的项目需求有一个问题是, 聊天时的未读消息数(由一张背景图和一个text构成)要紧跟在玩家名字后面一点的距离。
由于玩家取名的长度不同,我们不能将未读消息数放置在固定位置(但是说实话如果像手机QQ里面那样的固定的未读消息位置会更舒服点…)大致要呈现的效果如下图
一开始想的思路是在给定玩家名字后,由于我们为其添加了Content Size Fitter,所以其扩增的width我们是能求出的,相应的未读消息数这个物体也对应偏移width的距离,思路理清了再去实现其实就不难了,这里稍微说一下代码中用到的属性
我们获取到Text的Rect Transform组件,如果要访问其PosX PosY PosZ 则只需要用
var nameRect = GetComponent();
var posX = nameRect.anchoredPostion.x;
var posY = nameRect.anchoredPostion.y;
var posZ = nameRect.anchoredPostion.z;
如果要访问Width和Height 则使用
var width = nameRect.sizeDelta.x;
var height = nameRect.sizeDelta.y;
当然这里的sizeDelta是保证四个锚点anchors都在一点上时可以代表宽高,否则表示为到锚点的距离。也可以使用
nameRect.rect.size来获取宽高,不受锚点影响
代码编程的思路应该是没问题的,但是有没有更简单的方法呢? 经过我查询了网上的资料,学到了这个技巧
首先将name的RectTransform的锚点设置成如下图 左中对齐
再将未读消息数这个物体的RectTransform的锚点设置成如下图 右中对齐
最后将未读消息数(icon)作为其子物体即可,结构如下图
这样子我们的Text长度不同时 icon会跟随我们text的宽度变化而变化
如何搭好一个UI也是一门技术活…