unity双层滑动实现

news2024/11/26 16:47:55

实现功能:
当滑动列表中内容处于顶端的时候,向上滑动优先滑动整个滑动列表,当滑动列表移动到设置位置,即设定的最高处时,继续移动列表内内容。向下移动亦然,当内容处于滑动列表顶端时,移动整个滑动列表。

eventtriggerlistener脚本可在这篇查看unity防止ui点击事件被子物体拦截

using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;

public class ScrollViewMove : MonoBehaviour
{
    public ScrollRect m_scorllView;
    public RectTransform m_rectView;

    private void Start()
    {
        //添加滑动事件
        Graphic horizontalGraphic = m_scorllView.GetComponent<Graphic>();
        if (horizontalGraphic != null && horizontalGraphic.raycastTarget)
        {
            EventTriggerListener.Get(m_scorllView.gameObject).onBeginDrag = OnScrollBeginDrag;
            EventTriggerListener.Get(m_scorllView.gameObject).onDrag = OnScrollDrag;
            EventTriggerListener.Get(m_scorllView.gameObject).onEndDrag = OnScrollEndDrag;
        }

        //设置最高高度,和出现滑动时的阈值
        m_minHeight = m_scorllView.GetComponent<RectTransform>().localPosition.y;
        m_LimitY = (m_maxHeight - m_minHeight) * MOVE_DISTANCE_SCALE;
    }

    #region 滑动条事件

    //起始滑动位置
    private float m_startScrollHeight = 0f;
    //结束滑动位置
    private float m_endScrollHeight = 0f;
    //限制切换动画的最小判断
    private float m_LimitY;
    private readonly float MOVE_DISTANCE_SCALE = 0.2f;

    //起始鼠标位置
    private float m_startMouseHeight = 0f;
    //中途鼠标位置
    private float m_partMouseHeight = 0f;

    //最大高度
    private float m_maxHeight = 0f;
    //最小高度
    private float m_minHeight = 0f;

    //是否为展开状态
    private bool m_isOpen = false;

    /// <summary>
    /// 滑动列表开始拖拽事件
    /// </summary>
    /// <param name="obj"></param>
    private void OnScrollBeginDrag(GameObject obj)
    {
        m_startScrollHeight = m_scorllView.GetComponent<RectTransform>().localPosition.y;
        m_startMouseHeight = Input.mousePosition.y;
    }

    /// <summary>
    /// 滑动列表拖拽事件
    /// 先判断走拖拽事件还是滑动列表滑动事件
    /// </summary>
    /// <param name="obj"></param>
    private void OnScrollDrag(GameObject obj)
    {
        m_partMouseHeight = Input.mousePosition.y;
        float m_offsetHeight = m_partMouseHeight - m_startMouseHeight;
        m_startMouseHeight = m_partMouseHeight;

        float scrollPosY = m_scorllView.GetComponent<RectTransform>().localPosition.y;
        if (scrollPosY >= m_maxHeight)
        {
            if (m_offsetHeight >= 0)
            {
                m_scorllView.vertical = true;
                return;
            }
            else
            {
                if (m_scorllView.verticalNormalizedPosition < 1)
                {
                    m_scorllView.vertical = true;
                    return;
                }
            }
        }
        else if (scrollPosY <= m_minHeight)
        {
            if (m_offsetHeight <= 0)
            {
                m_scorllView.vertical = true;
                return;
            }
            else
            {
                if (m_scorllView.verticalNormalizedPosition > 1)
                {
                    m_scorllView.vertical = true;
                    return;
                }
            }
        }
        m_scorllView.verticalNormalizedPosition = 1;
        m_scorllView.vertical = false;

        OnPosDrag(m_offsetHeight);
    }

    /// <summary>
    /// 设置滑动位置
    /// </summary>
    /// <param name="offset"></param>
    private void OnPosDrag(float offset)
    {
        //设置滑动列表位置
        Vector3 scrollPos = m_scorllView.GetComponent<RectTransform>().localPosition;
        float endPosY = scrollPos.y + offset;
        if (endPosY > m_maxHeight)
        {
            offset = m_maxHeight - scrollPos.y;
        }
        else if (endPosY < m_minHeight)
        {
            offset = m_minHeight - scrollPos.y;
        }
        scrollPos = new Vector3(scrollPos.x, scrollPos.y + offset, scrollPos.z);

        m_scorllView.GetComponent<RectTransform>().localPosition = scrollPos;

        //设置滑动列表遮罩大小
        Vector2 viewPos = m_rectView.offsetMin;
        viewPos = new Vector2(viewPos.x, viewPos.y - offset);
        m_rectView.offsetMin = viewPos;
    }

    /// <summary>
    /// 滑动列表结束拖拽事件
    /// </summary>
    /// <param name="obj"></param>
    private void OnScrollEndDrag(GameObject obj)
    {
        m_endScrollHeight = m_scorllView.GetComponent<RectTransform>().localPosition.y;
        float offset = m_endScrollHeight - m_startScrollHeight;

        if (Mathf.Abs(offset) >= m_LimitY)
        {
            m_isOpen = (offset > 0);
        }

        ScrollDragAni(m_isOpen);
    }

    //动画播放时间
    private readonly float TWEEN_POS_TIME = 0.2f;

    /// <summary>
    /// 滑动条动画
    /// </summary>
    /// <param name="isOpen"></param>
    private void ScrollDragAni(bool isOpen)
    {
        Vector3 scrollPos = m_scorllView.GetComponent<RectTransform>().localPosition;
        if (isOpen)
        {
            DOTween.To(() => scrollPos.y,
                    (v) =>
                    {
                        Vector3 tmpVec = m_scorllView.GetComponent<RectTransform>().localPosition;
                        float offset = v - tmpVec.y;
                        OnPosDrag(offset);
                    }, m_maxHeight, TWEEN_POS_TIME).OnComplete(() => { m_isOpen = true; });
        }
        else
        {
            DOTween.To(() => scrollPos.y,
                    (v) =>
                    {
                        Vector3 tmpVec = m_scorllView.GetComponent<RectTransform>().localPosition;
                        float offset = v - tmpVec.y;
                        OnPosDrag(offset);
                    },  m_minHeight, TWEEN_POS_TIME).OnComplete(() => { m_isOpen = false; });
        }
    }

    #endregion
}

设置,在滑动列表中,将ViewPort设置成顶端锚点
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1553901.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Hive的天气情况大数据分析系统(通过hive进行大数据分析将分析的数据通过sqoop导入到mysql,通过Django基于mysql的数据做可视化)

基于Hive的天气情况大数据分析系统&#xff08;通过hive进行大数据分析将分析的数据通过sqoop导入到mysql&#xff0c;通过Django基于mysql的数据做可视化&#xff09; Hive介绍&#xff1a; Hive是建立在Hadoop之上的数据仓库基础架构&#xff0c;它提供了类似于SQL的语言&…

【Django学习笔记(一)】HTML语言简介和基于Flask Web框架快速搭建网站

HTML语言简介和基于Flask Web框架快速搭建网站 前言正文1、本专栏学习的主要目的2、Flask Web框架2.1 安装 Flask web 框架2.2 创建网站的基本方法2.3 templates 模板 3、HTML 语言简介3.1 编码3.2 title3.3 标题3.4 div 和 span3.5 超链接3.6 图片3.6.1 直接显示别人的图片地址…

MongoDB内存过高问题分析解决

告警 公司有个3.2.7版本的mongo复制集&#xff0c;最近几天频繁告警内存过高。 服务器配置16C64G内存。mongo备节点内存使用到55G&#xff0c;触发告警。 以下内容基于3.2.7版本&#xff0c;3.2.7版本已经太老&#xff0c;很多后来的命令和配置&#xff0c;3.2.7都没有。 …

信息安全之网络安全防护

先来看看计算机网络通信面临的威胁&#xff1a; 截获——从网络上窃听他人的通信内容中断——有意中断他人在网络上的通信篡改——故意篡改网络上传送的报文伪造——伪造信息在网络上传送 截获信息的攻击称为被动攻击&#xff0c;而更改信息和拒绝用户使用资源的攻击称为主动…

OpenGL 实现“人像背景虚化“效果

手机上的人像模式,也被人们称作“背景虚化”或 ”双摄虚化“ 模式,也称为 Bokeh 模式,能够在保持画面中指定的人或物体清晰的同时,将其他的背景模糊掉。突出画面的主体部分,主观上美感更强烈。 人像模式的一般实现原理是,利用双摄系统获取景深信息,并通过深度传感器和图…

超市收银系统-亿发智能收银,引领线上线下一体化新零售管理

社交新零售的传播核心在于移动互联网。从信任关系的角度来看&#xff0c;移动互联网为用户之间搭建了沟通的桥梁&#xff0c;促进了人们之间更频繁的交流&#xff0c;从而建立了信任关系。从场景的角度来看&#xff0c;移动互联网使得用户之间的沟通更加多样化&#xff0c;包括…

Tomcat项目创建 以及 在IDEA当中集成Tomcat

一: 有关Tomcat的WEB项目创建 TOMCAT项目的创建有两种方式, 第一种是利用骨架进行创建, 第二种是利用填补进行相应的创建, 不适用骨架进行创建 ,在这里主要聊第二种 (使用IDEA版本为2023) 1. 创建MAVEN项目, 非骨架形式 2.在相应的pom文件当中设置打包方式 为 war包的打包形…

Aino AI,一个空间数据查询和分析的应用

简介 chatgpt的出现掀起了一大波行业革命&#xff0c;或许也包括我们地信行业。分享一下Aino AI&#xff0c;一个基于AI的GIS应用。 Aino公司在今年推出了 Aino AI 助手&#xff0c;它可以通过自然语言的方式自动化处理空间数据&#xff0c;通过和OpenStreetMap的结合实现无缝…

太阳能发电园区3D可视化:揭秘绿色能源新纪元

在科技飞速发展的今天&#xff0c;绿色能源已成为推动社会进步的重要力量。太阳能发电作为绿色能源的重要代表&#xff0c;正在全球范围内掀起一股清洁能源的革命浪潮。 太阳能发电园区作为集中展示太阳能发电技术和应用的场所&#xff0c;其规模之大、设备之复杂&#xff0c;常…

#Linux系统编程(消息队列)

&#xff08;一&#xff09;发行版&#xff1a;Ubuntu16.04.7 &#xff08;二&#xff09;记录&#xff1a; &#xff08;1&#xff09;什么是消息队列 消息队列是一种先进先出的队列型数据结构&#xff0c;实际上是系统内核中的一个内部链表。消息被顺序插入队列中&#xff…

QT QInputDialog弹出消息框用法

使用QInputDialog类的静态方法来弹出对话框获取用户输入&#xff0c;缺点是不能自定义按钮的文字&#xff0c;默认为OK和Cancel&#xff1a; int main(int argc, char *argv[]) {QApplication a(argc, argv);bool isOK;QString text QInputDialog::getText(NULL, "Input …

故障排查指南:通过连接电脑查找iOS应用崩溃日志的有效技巧

在iOS应用开发过程中&#xff0c;调试日志和奔溃日志是开发者必不可少的工具。当iOS手机崩溃时&#xff0c;我们可以连接电脑并使用Xcode Console等工具来查看日志。然而&#xff0c;这种方式可能不够方便&#xff0c;并且处理奔溃日志也相当繁琐。克魔助手的出现为开发者带来了…

推荐!00 后都在用的6个超实用微信小程序,又能少装N个app啦

在这个手机内存永远不够用的年代&#xff0c;每一次下载新app都像是在和手机进行一场心理博弈——不下载就out&#xff0c;下载了又怕手机喘不过气来。好在&#xff0c;微信小程序如同一股清流&#xff0c;轻巧地滑入我们的生活&#xff0c;解救了那些对“存储空间不足”弹窗深…

【数据结构 | 图论】如何用链式前向星存图(保姆级教程,详细图解+完整代码)

一、概述 链式前向星是一种用于存储图的数据结构&#xff0c;特别适合于存储稀疏图&#xff0c;它可以有效地存储图的边和节点信息&#xff0c;以及边的权重。 它的主要思想是将每个节点的所有出边存储在一起&#xff0c;通过数组的方式连接&#xff08;类似静态数组实现链表…

基于51单片机的汽车安全带检测控制器Proteus仿真

地址&#xff1a;https://pan.baidu.com/s/1To_ZEiJHBrZnm9ejYHFoPg 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52简介&#xff1a; AT89C52是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectronics&#xff09;公…

Numpy 初体验

文章目录 第1关&#xff1a;Numpy 创建数组第2关&#xff1a;Numpy 数组的基本运算第3关&#xff1a;Numpy 数组的切片与索引第4关&#xff1a;Numpy 数组的堆叠第5关&#xff1a;Numpy 的拆分 第1关&#xff1a;Numpy 创建数组 编程要求 本关的任务是&#xff0c;补全右侧编辑…

查询优化-提升子查询-UNION类型

瀚高数据库 目录 文档用途 详细信息 文档用途 剖析UNION类型子查询提升的条件和过程 详细信息 注&#xff1a;图片较大&#xff0c;可在浏览器新标签页打开。 SQL: SELECT * FROM score sc, LATERAL(SELECT * FROM student WHERE sno 1 UNION ALL SELECT * FROM student…

Mybatis中QueryWrapper的复杂查询SQL

最近在使用QueryWrapper编写查询语句时发现复杂的SQL不会写。在网上找了半天&#xff0c;终于得到了点启示。在此做个记录以备忘。 我要实现的SQL是这样的&#xff1a; -- 实现这个复杂查询 -- 查询设备表 select * from oa_device where ((dev_code BSD1003 and dev_status…

系统开发实训小组作业week5 —— 用例描述与分析

目录 4.3 UC003电影浏览与查询 4.3.1 用例描述 4.3.2 活动图 4.3.3 界面元素 4.3.4 功能 4.4 UC004在线订票 4.4.1 用例描述 4.4.2 活动图 4.4.3 界面元素 4.4.4 功能 4.3 UC003电影浏览与查询 4.3.1 用例描述 用例号 UC003-01 用例名称 电影浏览与查询 用例描述…

2.9 Python缩进规则(包含快捷键)

Python缩进规则&#xff08;包含快捷键&#xff09; 和其它程序设计语言&#xff08;如 Java、C 语言&#xff09;采用大括号“{}”分隔代码块不同&#xff0c;Python采用代码缩进和冒号&#xff08; : &#xff09;来区分代码块之间的层次。 在 Python 中&#xff0c;对于类…