Unity3D自己编写Scroll View

版权声明:本文为博主原创文章,未经博主允许不得转载。 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);
    }
}

猜你喜欢

转载自blog.csdn.net/wang_lvril/article/details/82592686
今日推荐