版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wang_lvril/article/details/82592686
介绍:
在做UI的时候,会遇到滑动的组件,固定一个方框中显示内容。
UGUI和NGUI中都有scroll view组件,可以很放便使用。但有时候不是想要的功能。
了解底层实现,才能做出自己想要的功能,下面就写一个简单的scroll view
组成:
- 显示区域
- 内容区域
- 内容
- 滑块
步骤:
Canvas下创建一个空物体,添加脚本<MyScrollView>。调整好大小,即显示区域的大小。
另外可以添加《Image》《Mask》组件,设置背景,和遮罩。
Scroll View下创建一个空物体Content,调整好大小,即要显示内容的总大小。一般比ScrollView大。
Content下可以放置要显示的内容。
脚本:MyScrollView
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);
}
}