unity双层滑动实现

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

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.mfbz.cn/a/497984.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

低功耗、低成本 NAS/公共文件夹 的可能性

使用现状&#xff1a;多台工作电脑&#xff0c;家里人手一台&#xff0c;还在两个住处 有好几台工作电脑&#xff0c;不同电脑不同OS有不同的用途&#xff0c;最大的问题就是各个电脑上文件的同步问题&#xff0c;这里当然就需要局域网里的公共文件夹&#xff0c;在NAS的问题上…

R语言使用dietaryindex包计算NHANES数据多种营养指数(2)

健康饮食指数 (HEI) 是评估一组食物是否符合美国人膳食指南 (DGA) 的指标。Dietindex包提供用户友好的简化方法&#xff0c;将饮食摄入数据标准化为基于指数的饮食模式&#xff0c;从而能够评估流行病学和临床研究中对这些模式的遵守情况&#xff0c;从而促进精准营养。 该软件…

Unity3d使用Jenkins自动化打包(Windows)(一)

文章目录 前言一、安装JDK二、安装Jenkins三、Jenkins插件安装和使用基础操作 实战一基础操作 实战二 四、离线安装总结 前言 本篇旨在介绍基础的安装和操作流程&#xff0c;只需完成一次即可。后面的篇章将深入探讨如何利用Jenkins为Unity项目进行打包。 一、安装JDK 1、进入…

【嵌入式机器学习开发实战】(十二)—— 政安晨:通过ARM-Linux掌握基本技能【C语言程序的安装运行】

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: 嵌入式机器学习开发实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 在ARM-Linux系统中&#xff0c;C语言程序的安装和运行可…

快速上手Spring Cloud 六:容器化与微服务化

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

啥也不会的大学生看过来,这8步就能系统入门stm32单片机???

大家好&#xff0c;今天给大家介绍啥也不会的大学生看过来&#xff0c;这8步就能系统入门stm32单片机&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 对于没有任何基础的大学生来…

数据库原理与应用(SQL Server)笔记 关系数据库

目录 一、关系数据库的基本概念&#xff08;一&#xff09;关系数据库的定义&#xff08;二&#xff09;基本表、视图&#xff08;三&#xff09;元组、属性、域&#xff08;四&#xff09;候选码、主码、外码 二、关系模型三、关系的完整性&#xff08;一&#xff09;实体完整…

快速上手Spring Cloud五:Spring Cloud与持续集成/持续部署(CI/CD)

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

神策数据参与制定首份 SDK 网络安全国家标准

国家市场监督管理总局、国家标准化管理委员会发布中华人民共和国国家标准公告&#xff08;2023 年第 13 号&#xff09;&#xff0c;全国信息安全标准化技术委员会归口的 3 项国家标准正式发布。其中&#xff0c;首份 SDK 国家标准《信息安全技术 移动互联网应用程序&#xff0…

根据实例逐行分析NIO到底在做什么

Selector&#xff08;选择器&#xff09;是 Channel 的多路复用器&#xff0c;它可以同时监控多个 Channel 的 IO 状况&#xff0c;允许单个线程来操作多个 Channel。Channel在从Buffer中获取数据。 选择器、通道、缓冲池是NIO的核心组件。 一、新建选择器 此时选择器内只包含…

HackTheBox-Machines--Legacy

文章目录 1 端口扫描2 测试思路3 445端口漏洞测试4 flag Legacy 测试过程 1 端口扫描 nmap -sC -sV 10.129.227.1812 测试思路 目标开启了135、139、445端口&#xff0c;445 SMB服务存在很多可利用漏洞&#xff0c;所以测试点先从445端口开始。而且在Nmap扫描结果中&#xff0c…

操作系统练习-操作系统的发展与分类

批量处理系统 ----------------------------------------------------------------------------------------------------------------------------- 1. 下列关于批处理系统的叙述中&#xff0c;正确的是( )。 I.批处理系统允许多个用户与计算…

百度智能云千帆,产业创新新引擎

本文整理自 3 月 21 日百度副总裁谢广军的主题演讲《百度智能云千帆&#xff0c;产业创新新引擎》。 各位领导、来宾、媒体朋友们&#xff0c;大家上午好。很高兴今天在石景山首钢园&#xff0c;和大家一起沟通和探讨大模型的发展趋势&#xff0c;以及百度最近一段时间的思考和…

camtasia怎么添加背景图 camtasia怎么添加背景音乐

在进行视频编辑时&#xff0c;添加合适的背景图和背景音乐是很重要的。美观的背景图可以增强视频的视觉体验&#xff0c;让画面更加生动和谐&#xff0c;而添加背景音乐&#xff0c;则能够调节气氛&#xff0c;让观众更好地沉浸到视频中。接下来我将为大家介绍&#xff1a;camt…

专题:一个自制代码生成器(嵌入式脚本语言)之应用实例

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 专题&#xff1a;一个自制代码…

网络原理-传输层-UDP报文结构

本文介绍UDP报文 有很多友友搞不清楚UDP报文的详细结构还有TCP的详细结构,所以专门分开来讲 以免弄混. 首先我们先看一下整个UDP结构,让大家有一个全方面的认识 下面我们来详细解释UDP报 16位源端口号(本机):就是2字节大小,16个二进制位. 16位目的端口号(目的机):也是2字节…

element-ui autocomplete 组件源码分享

紧接着 input 组件的源码&#xff0c;分享带输入建议的 autocomplete 组件&#xff0c;在 element-ui 官方文档上&#xff0c;没有这个组件的 api 目录&#xff0c;它的 api 是和 input 组件的 api 在一起的&#xff0c;看完源码之后发现&#xff0c;源码当中 autocomplete 组件…

MTK8781安卓核心板_MT8781(Helio G99)核心板性能参数

MT8781安卓核心板搭载了八核CPU&#xff0c;其中包括两个主频高达2.2GHz的高性能Arm Cortex-A76处理器。这一处理器采用了台积电6纳米级芯片生产工艺&#xff0c;以及先进的3D图形功能的高性能Arm Mali G57级GPU。通过超快LPDDR4X内存和UFS 2.2存储供电&#xff0c;不仅提高了游…

新版Idea2023.3.5与lombok冲突、@Data失效

新版idea和lombok冲突&#xff0c;加上Data&#xff0c;其他地方get set也不报错&#xff0c;但是一运行就找不到get set方法。 但是直接使用Getter和Setter可以访问、应该是Data失效了。 解决方法&#xff1a; 看推上介绍是 lombok 与 idea 采集 get 、set 方法的时候所用的技…

成都市酷客焕学新媒体科技有限公司:实现品牌的更大价值!

成都市酷客焕学新媒体科技有限公司专注于短视频营销&#xff0c;深知短视频在社交媒体中的巨大影响力。该公司巧妙地将品牌信息融入富有创意和趣味性的内容中&#xff0c;使观众在轻松愉悦的氛围中接受并传播这些信息。凭借独特的创意和精准的营销策略&#xff0c;成都市酷客焕…
最新文章