在不少游戏中都会有自动滚动的效果
我们这里用UGUI的Scroll View来实现一下
我建议大家在开始做之前 首先先了解一下这个的基本用法
我之前也没写过关于这个的使用方法
然后先给大家一个效果图片(里边的水印大家凑活看一下)
可以看到 当我们鼠标不移上去的时候 他是自己滚动的 当我们自己鼠标移动上去并且拖拽的时候
他可以被我们拖动 而且 通过代码自动检测区域 然后吸附过去
实现过程
首先我们现在unity中搭建所要的Scrool View
content上的组件
之后就是代码了 其中计算比较麻烦 仔细看看其实也不是特别复杂
public class PageScrollview : MonoBehaviour,IEndDragHandler,IBeginDragHandler
{
#region 声明对象
public enum ScrolType
{
//滑动类型(分为两种 横纵两种)
HorizontalType,
VerticalType
}
ScrollRect rect;
private int pagecount;//选项个数
private RectTransform content;
private float[] pages;//位置
[Header("滚动参数")]
public float movetime = 0.3f;//移动的时间
public float timer = 0;//计时器
public float startmovepos;//开始移动的位置
public int currentindex = 0;//当前所处页数
private bool ismoving = false;
private bool isDraging = false;//是否在拖动中
[Header("自动滚动参数")]
public bool isAutoScrol=true ;//是否自动滚动
public float AutoTime = 2f;//自动滚动时间间隔
public float autotimer = 0;//自动计时器
[Header("滑动类型")]
public ScrolType scroltype = ScrolType.HorizontalType;
#endregion
private void Start()
{
Init();//初始化
}
private void Update()
{
listenermove();
listenerAutoScroll();
}
private void Init()
{
rect = GetComponent<ScrollRect>();
if (rect == null)
{
Debug.LogError("不存在组件ScrollRect");
}
content = GameObject.Find("Content").GetComponent<RectTransform>();
pagecount = content.childCount;//子节点数量
pages = new float[pagecount];//初始化
if (pages.Length == 1)
{
Debug.LogError("只有一页 不用滚动");
}
for (int i = 0; i < pages.Length; i++)
{
switch (scroltype)
{
case ScrolType.HorizontalType:
pages[i] = i * (1.0f / (float)(pagecount - 1));//给位置的数组赋值
break;
case ScrolType.VerticalType:
pages[i] = 1 - i * (1.0f / (float)(pagecount - 1));//给位置的数组赋值
break;
}
}
}
private void listenermove()//监听滑动
{
if (ismoving)
{
timer += Time.deltaTime * movetime;
//灵魂就在这里
switch (scroltype)
{
case ScrolType.HorizontalType:
rect.horizontalNormalizedPosition = Mathf.Lerp(startmovepos, pages[currentindex], timer);
break;
case ScrolType.VerticalType:
rect.verticalNormalizedPosition = Mathf.Lerp(startmovepos, pages[currentindex], timer);
break;
}
if (timer >= 1)
{
ismoving = false;
}
}
}
private void listenerAutoScroll()//自动滑动
{
if (isDraging)
{
return;
}
if (isAutoScrol)
{
autotimer += Time.deltaTime;
if (autotimer > AutoTime)
{
autotimer = 0;
currentindex++;
currentindex %= pagecount;//取余形成循环
scrolltopage(currentindex);
}
}
}
private void scrolltopage(int page)
{
ismoving = true;
this.currentindex = page;
timer = 0;
switch (scroltype)
{
case ScrolType.HorizontalType:
startmovepos = rect.horizontalNormalizedPosition;
break;
case ScrolType.VerticalType:
startmovepos = rect.verticalNormalizedPosition;
break;
}
}
//取消拖动的接口
public void OnEndDrag(PointerEventData eventData)
{
int min = 0;
//计算当最近的一页是哪个
for(int i = 0; i < pages.Length; i++)
{
switch (scroltype)
{
case ScrolType.HorizontalType:
if (Mathf.Abs(pages[i] - rect.horizontalNormalizedPosition) < Mathf.Abs(pages[min] - rect.horizontalNormalizedPosition))
{
min = i;
}
break;
case ScrolType.VerticalType:
if (Mathf.Abs(pages[i] - rect.verticalNormalizedPosition) < Mathf.Abs(pages[min] - rect.verticalNormalizedPosition))
{
min = i;
}
break;
}
}
scrolltopage(min);
isDraging = false;
autotimer = 0;
}
//开始拖动的接口
public void OnBeginDrag(PointerEventData eventData)
{
isDraging = true;
}
}
里边使用了一个枚举 使用来方便数轴上的修改的
希望这篇博文对你有所帮助
如果有问题或者是合作 主页有我的联系方式(知无不答)
之后我还会持续更新这个方面的内容