一:Scroll View下重要组件属性及API的详解
Scroll View是一个组合UI,创建后有以下内容
——Viewport:显示的区域,一般配合Mask一起使用
——Scrollbar Horizontal:水平滑动条
——Scrollbar Vertical:竖直滑动条
Scroll View上最重要的就是Scroll Rect组件:
——Content:所有要显示的内容(可滑动的区域)
——Horizontal:是否可以水平滑动
——Vertical:是否可以竖直滑动
——Movement Type:滑动的类型(不受限制随意滑动,到边界出现弹性,到边界没有弹性)
——Elasticity:弹性数值
——Inertia:是否用惯性
——Deceleration Rate:惯性的加速度
——Viewport:可视区域,一般配合Mask一起使用
获取content的宽和高:
//获取content的宽和高(content矩形的width和height)
print("size " + content.rect.size);
print("width " + content.rect.width);
print("height " + content.rect.height);
print("width " + content.rect.size.x);
print("height " + content.rect.size.y);
//以下方法本质上并不是获取content的宽和高,而是获取content矩形的四个角的位置
print("width " + content.rect.xMax);
print("width " + content.rect.xmin);
print("height " + content.rect.ymax);
print("height " + content.rect.ymin);
//设置content的大小——content.sizeDelta
print("相对位置 "+content.sizeDelta);
//——content.sizeDelta是一个相对大小,直接设置位置即可,不需要累加上之前content的数值
//——content.rect.size是结构体类型,不能改数值
二:搭配ScrollView的组件
——Grid Layout Group
Padding:Content下所有物体对于Content整体的上下左右偏移量
Cell Size:Content下所有物体的大小(持有Grid Layout Group组件下所有Image的RectTransfrom大小设置都被锁上,只能通过此属性设置Image大小)
Spacing:Content下所有物体的行与列的间隔
Start Corner:填充的起始点
Start Axis:填充的轴向
Child Alignment:所有子物体的对齐方式
Constraint:限制Content内容的行数和列数
——Vertical Layout Group和Horizontal Layout Group
Padding:Content下所有物体对于Content整体的上下左右偏移量
Spacing:Content下所有物体的行或列的间隔
Child Alignment:所有子物体的对齐方式
Control Child Size:是否控制子物体的大小(勾选后将不能控制其大小)
Use Child Scale:是否使用子物体的缩放
Child Force Expand:子物体自动伸展(Width和Height一般都不勾选)
——Content Size Fitter(此组件还可以制作提示文本框随着文字的数量增多而变大)
Horizontal Fit:水平的自动调节(通常选择Preferred Size)
Vertical Fit:竖直的自动调节(通常选择Preferred Size)
三:如何计算ScrollView的Content大小
content.sizeDelta = (n-1)*(Spacing X+CellSize X)
四:自己编写代码实现Scroll View
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyScrollView : MonoBehaviour {
[Header("======弹性设置=======")]
public bool canOver = false; //是否可以超出内容边界
public float overNum = 0.3f; //超出多少
public float overTime = 0.1f; //弹回时间
[Header("======滑动系数=======")]
public float sliderXStrength = 0.001f; //横向滑动系数
public float sliderYStrength = 0.001f; //纵向滑动系数
[Header("======滑动方向=======")]
public bool horizontal = true; //横向滑动
public bool vertical = true; //纵向滑动
private Transform content; //内容
private float minContentPosX; //内容横向开始位置
private float maxContentPosX; //内容横向结束位置
private float minContentPosY; //内容纵向开始位置
private float maxContentPosY; //内容纵向结束位置
private float mouseBeginPosX; //鼠标横向开始位置
private float mouseEndPosX; //鼠标横向结束位置
private float mouseBeginPosY; //鼠标纵向开始位置
private float mouseEndPosY; //鼠标纵向结束位置
private float valueX = 1.0f;
private float valueY = 1.0f;
private bool isDrag; //判断鼠标是否在滑
private float bounceFri; //SmoothDamp系数
private void Awake()
{
content = transform.Find("Content");
if (horizontal) {
minContentPosX = 540.0f; //内容滑到最左边的位置
maxContentPosX = -540.0f; //内容滑倒最右边的位置
}
if (vertical) {
minContentPosY = 213.0f; //内容滑到最下边的位置
maxContentPosY = -209.0f; //内容滑到最上边的位置
}
}
void Update () {
//鼠标按下,开始滑动,获取鼠标位置
if(Input.GetMouseButtonDown(0))
{
isDrag = true;
if (horizontal) {
mouseBeginPosX = Input.mousePosition.x;
mouseEndPosX = Input.mousePosition.x;
}
if (vertical)
{
mouseBeginPosY = Input.mousePosition.y;
mouseEndPosY = Input.mousePosition.y;
}
else {
return;
}
}
//鼠标抬起,滑动结束
if(Input.GetMouseButtonUp(0))
{
isDrag = false;
}
//滑动过程
if(isDrag)
{
if(Input.GetMouseButton(0))
{
//不断获取鼠标位置的差值,判断方向
mouseBeginPosX = mouseEndPosX;
mouseBeginPosY = mouseEndPosY;
if (horizontal) {
mouseEndPosX = Input.mousePosition.x;
float offsetX = mouseEndPosX - mouseBeginPosX;
valueX += offsetX * sliderXStrength;
if (canOver)
{
valueX = Mathf.Max(0 - overNum, valueX);
valueX = Mathf.Min(valueX, 1 + overNum);
}
else
{
valueX = Mathf.Max(0f, valueX);
valueX = Mathf.Min(valueX, 1f);
}
}
if (vertical) {
mouseEndPosY = Input.mousePosition.y;
float offsetY = mouseEndPosY - mouseBeginPosY;
valueY += offsetY * sliderYStrength;
if (canOver)
{
valueY = Mathf.Max(0 - overNum, valueY);
valueY = Mathf.Min(valueY, 1 + overNum);
}
else
{
valueY = Mathf.Max(0f, valueY);
valueY = Mathf.Min(valueY, 1f);
}
}
}
}
//弹回来的强度
if (horizontal) {
if (valueX > 1f && isDrag == false)
{
valueX = Mathf.SmoothDamp(valueX, 1f, ref bounceFri, overTime);
}
if (valueX < 0f && isDrag == false)
{
valueX = Mathf.SmoothDamp(valueX, 0f, ref bounceFri, overTime);
}
}
if (vertical) {
if (valueY > 1f && isDrag == false)
{
valueY = Mathf.SmoothDamp(valueY, 1f, ref bounceFri, overTime);
}
if (valueY < 0f && isDrag == false)
{
valueY = Mathf.SmoothDamp(valueY, 0f, ref bounceFri, overTime);
}
}
//把value值转换为pos值,赋值给内容的pos
float posX = valueX * (maxContentPosX - minContentPosX) + minContentPosX;
float posY = valueY * (maxContentPosY - minContentPosY) + minContentPosY;
content.localPosition = new Vector3(posX, posY, content.localPosition.z);
}
}