创建一个空物体,将以下物体挂载到上面,然后将视口和内容模块分别拖拽到对应字段上,再设置自己想要的滚动速度和边缘阈值即可
using UnityEngine;
public class AutoScroll : MonoBehaviour
{
public RectTransform viewport; // 视口,显示内容的窗口
public RectTransform content; // 内容,需要滚动的对象
public float scrollSpeed = 100f; // 滚动速度
public float edgeThreshold = 10f; // 边缘阈值,鼠标距离边缘小于该值时触发自动滚动
private float contentHeight; // 内容的高度
private float viewportHeight; // 视口的高度
private void Start()
{
// 获取内容的高度和视口的高度
contentHeight = content.rect.height;
viewportHeight = viewport.rect.height;
}
private void Update()
{
// 获取鼠标的位置
Vector2 mousePosition = Input.mousePosition;
// 获取视口的四个角的世界坐标
//通过调用 RectTransform 的 GetWorldCorners 方法来获取视口在世界坐标中的四个角的位置
//其中 corners[0] 是左下角的位置,corners[1] 是右下角的位置
//corners[2] 是右上角的位置,corners[3] 是左上角的位置
//RectTransform 组件使用的坐标系统是以视口的左下角为原点的局部坐标系,可以使用这些位置信息来获取视口的底部和顶部的世界坐标
Vector3[] corners = new Vector3[4];
viewport.GetWorldCorners(corners);
float viewportBottom = corners[0].y; // 视口底部的世界Y坐标
float viewportTop = corners[1].y; // 视口顶部的世界Y坐标
// 只有当鼠标在视口内时才进行自动滚动
if (mousePosition.y >= viewportBottom && mousePosition.y <= viewportTop)
{
// 计算鼠标与视口边缘的距离
float distanceToTop = Mathf.Abs(mousePosition.y - viewportTop);
float distanceToBottom = Mathf.Abs(mousePosition.y - viewportBottom);
// 如果鼠标接近视口的上边缘,则向下滚动
if (distanceToTop <= edgeThreshold)
{
content.anchoredPosition -= Vector2.up * scrollSpeed * Time.deltaTime;
}
// 如果鼠标接近视口的下边缘,则向上滚动
else if (distanceToBottom <= edgeThreshold)
{
content.anchoredPosition += Vector2.up * scrollSpeed * Time.deltaTime;
}
}
// 限制滚动范围,确保内容不会滚出视口范围
//计算最小的 Y 坐标(minY),通过将内容的总高度减去视口的高度得到
//Mathf.Max 函数来确保 minY 不会小于 0,即内容的高度小于视口的高度时,minY 保持为 0
//创建一个新的 Vector2 对象来更新滚动内容的位置,content.anchoredPosition.x 保持不变
//Mathf.Clamp 函数来限制 anchoredPosition.y 的取值范围,使其保持在 0 到 minY 之间
float minY = Mathf.Max(contentHeight - viewportHeight, 0f);
content.anchoredPosition = new Vector2(content.anchoredPosition.x, Mathf.Clamp(content.anchoredPosition.y, 0f, minY));
}
}