首先贴效果:
1.动态设置gridLayout的大小
核心组件为rectTransform,核心属性一个为rectTransform.anchoredPosition,用来设置和锚点的距离,否则只设置宽高会导致grid只以锚点(一般为居中)为中心扩展。第二个核心属性为rectTransform.sizeDelta,用于设置控件的宽度和高度。实现起来很简单,只要获得放进去的图片的宽高然后乘以总数就能得到滑动框的总宽高。
boardBtns.GetComponent<RectTransform>().anchoredPosition = new Vector2(posX*(num-1),0);
boardBtns.GetComponent<RectTransform>().sizeDelta = new Vector2(width*num, boardBtns.GetComponent<RectTransform>().rect.height);
boardBtns为含有gridLayout组件的控件,即所有公告的父物体。
2.定时滑动公告板的实现
实现这个核心组件为scrollrect,核心属性scrollrect.horizontalNormalizedPosition
这个值返回一个0-1的浮点数,实验一下就知道这个能用来控制滑动框划到哪里,值越小越接近起点。
以及需要继承Unity事件的拖动接口,分别为IBeginDragHandler和IEndDragHandler(IDragHandler用于拖动时监测事件,不过感觉它没什么用就没有实现)
同时需要设置一个核心变量,表示现在滑动到第几页,我取名为currIndex,滑动到currIndex页(从0开始)时上述scrollrect.horizontalNormalizedPosition的值为currIndex * ((float)1 / (num - 1)))
public void OnBeginDrag(PointerEventData eventData)//记录起始位置
{
lastX = sr.horizontalNormalizedPosition;
}
public void OnEndDrag(PointerEventData eventData)//滑动结束,根据判断的方向设置index的加减然后根据index的值朝某个方向滑动
{
if (Mathf.Abs(lastX- sr.horizontalNormalizedPosition)>=0.01f)
{
if (lastX < sr.horizontalNormalizedPosition)//向左划
{
if (currIndex<num-1)
{
currIndex++;
StopAllCoroutines();//一定要停止协程!!否则会导致协程重复执行,滑动框会乱划
StartCoroutine(MoveTo(currIndex * ((float)1 / (num - 1))));
}
}
else if (lastX > sr.horizontalNormalizedPosition)//向右划
{
if (currIndex >0)
{
currIndex--;
StopAllCoroutines();
StartCoroutine(MoveTo(currIndex * ((float)1 / (num - 1))));
}
}
}
}
接下来实现利用协程平滑移动公告板的功能,主要使用Mathf.Lerp插值函数。
IEnumerator MoveTo(float targetX)
{
while (true)
{
if (Mathf.Abs(sr.horizontalNormalizedPosition - targetX) >= 0.01f)//未到时滑动
{
sr.horizontalNormalizedPosition = Mathf.Lerp(
sr.horizontalNormalizedPosition, targetX,
Time.deltaTime * (Mathf