不使用ScrollRect 和 HorizontalLayoutGroup做的横向循环列表

news2024/11/20 20:42:36

一、 版本一

1.前情提要

因为需要展示300多个相同的物体,但是如果全部放在场景内,运行起来会很卡,所以想到了用无限循环,然后动态填充不同的数据。
做的这个没有用HorizontalLayoutGroup 和 ScrollRect 。
1.没有使用HorizontalLayoutGroup,是因为运行后会在第一个放到后面后,自动给剩下的排序,然后排完发现第二个到了第一个的位置,然后,第二个自动符合排到最后的条件,然后第二个继续放到后面。。。
造成极短的时间内,所有东西都在不停向后排。
2.没有使用 ScrollRect是因为,它和IDragHandler接口都是滑动功能, 只需要一个就够了,而我使用IDragHandler更趁手。

2.效果展示

在这里插入图片描述

3.原理讲解

我使用的IDragHandler和IBeginDragHandler两个接口,在开始和每次drag后都保存上次的鼠标位置,然后拖拽的时候,移动他们的父级content。然后比较上次滑动的鼠标位置,左移,和最小值比较超过,就把第一个排到最后。同样,如果右移,和最大值比较超过,就把最后一个拍到第一个。TimeDanyuan是为了辨认的自定义类。使用时,可以自己使用其他的代替。
后续会优化,继续尝试其他方式,找到最优解。

4.功能代码

版本V1.0

private List<RectTransform> danyuans=new List<RectTransform>();

    public Transform content;
    private Vector3 last_mousePos;

    private float minXPos = 470.7586f;//左滑范围
    private float maxXPos = 1639.109f;//右滑范围

    private Vector3 oldPos;

    private float interval = 146;//间隔
    // Start is called before the first frame update
    void Start()
    {
        var danyuans01=GetComponentsInChildren<TimeDanyuan>();
        foreach (var danyuan in danyuans01)
        {
            var rect=danyuan.GetComponent<RectTransform>();
            danyuans.Add(rect);
        }
    }
    public void OnDrag(PointerEventData eventData)
    {
        Vector3 mousepos = Input.mousePosition - last_mousePos;

        content.position = oldPos+ new Vector3(mousepos.x, 0,0);
        if (mousepos.x> 0)//右滑
        {
            //右滑超出边界 

            var first = content.transform.GetChild(0).GetComponent<RectTransform>();
            var last = content.transform.GetChild(content.childCount - 1).GetComponent<RectTransform>();
            if (last.position.x > maxXPos)
            {
                last.anchoredPosition = new Vector2(first.anchoredPosition.x - interval, last.anchoredPosition.y);
                last.SetAsFirstSibling();
            }
        }
        else if(mousepos.x < 0) //左滑
        {
            //左滑超出边界
            var first = content.transform.GetChild(0).GetComponent<RectTransform>();
            var last = content.transform.GetChild(content.childCount - 1).GetComponent<RectTransform>();
            if (first.position.x < minXPos)
            {
                first.anchoredPosition = new Vector2(last.anchoredPosition.x+ interval, first.anchoredPosition.y);
                first.SetAsLastSibling();
            }
        }
        last_mousePos = Input.mousePosition;
        oldPos = content.position;
    }
    public void OnBeginDrag(PointerEventData eventData)
    {
        last_mousePos =Input.mousePosition;
        oldPos = content.position;
    }

二、 版本二,增加新的功能,可以根据左右滑动,里面的内容会不同。

1.效果截图

右滑 里面的数值会变大
在这里插入图片描述
左滑里面的数值会变小在这里插入图片描述

2.具体增加的内容

具体只增加了一个next_index 属性来标记序号,OnChange事件用来相应左右滑动时的事件,给里面的内容赋值。OnChange需要一个要赋值的值(这里是个int类型的值)和具体需要改的物体。

3…代码

private List<RectTransform> danyuans=new List<RectTransform>();

    public Transform content;
    private Vector3 last_mousePos;

    private float minXPos = 470.7586f;//左滑范围
    private float maxXPos = 1639.109f;//右滑范围

    private Vector3 oldPos;

    private float interval = 146;//间隔

    public Action<int, RectTransform> OnChange;
    private int next_index;
    // Start is called before the first frame update
    void Start()
    {
        foreach (Transform danyuan in content)
        {
            var rect=danyuan.GetComponent<RectTransform>();
            danyuans.Add(rect);
        }
        OnChange += ChangeIndex;
    }
    public void OnDrag(PointerEventData eventData)
    {
        Vector3 mousepos = Input.mousePosition - last_mousePos;

        content.position = oldPos+ new Vector3(mousepos.x, 0,0);
        if (mousepos.x> 0)//右滑
        {
            //右滑超出边界 

            var first = content.transform.GetChild(0).GetComponent<RectTransform>();
            var last = content.transform.GetChild(content.childCount - 1).GetComponent<RectTransform>();
            if (last.position.x > maxXPos)
            {
                last.anchoredPosition = new Vector2(first.anchoredPosition.x - interval, last.anchoredPosition.y);
                last.SetAsFirstSibling();

                int index=int.Parse(first.GetComponentInChildren<TextMeshProUGUI>().text);
                next_index = index - 1;
                OnChange(next_index,last);
            }
        }
        else if(mousepos.x < 0) //左滑
        {
            //左滑超出边界
            var first = content.transform.GetChild(0).GetComponent<RectTransform>();
            var last = content.transform.GetChild(content.childCount - 1).GetComponent<RectTransform>();
            if (first.position.x < minXPos)
            {
                first.anchoredPosition = new Vector2(last.anchoredPosition.x+ interval, first.anchoredPosition.y);
                first.SetAsLastSibling();

                int index = int.Parse(last.GetComponentInChildren<TextMeshProUGUI>().text);
                next_index = index + 1;
                OnChange(next_index,first);
            }
        }
        last_mousePos = Input.mousePosition;
        oldPos = content.position;
    }
    public void OnBeginDrag(PointerEventData eventData)
    {
        last_mousePos =Input.mousePosition;
        oldPos = content.position;
    }

    private void ChangeIndex(int index, RectTransform c_item)
    {
        var text= c_item.GetComponentInChildren<TextMeshProUGUI>();

        text.text = index.ToString();
    }

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

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

相关文章

Git原理及常用命令小结——实用版(ing......)、Git设置用户名邮箱

Git基本认识 Git把数据看作是对小型文件系统的一组快照&#xff0c;每次提交更新&#xff0c;或在Git中保存项目状态时&#xff0c;Git主要对当时的全部文件制作一个快照并保存这个快照的索引。同时&#xff0c;为了提高效率&#xff0c;如果文件没有被修改&#xff0c;Git不再…

JSON的序列化与反序列化以及VSCode执行Run Code 报错

JSON JSON: JavaScript Object Notation JS对象简谱 , 是一种轻量级的数据交换格式。 JSON格式 { "name":"金苹果", "info":"种苹果" } 一个对象&#xff1a;由一个大括号表示.括号中通过键值对来描述对象的属性 (可以理解为, 大…

操作系统总结(2)

目录 2.1 进程的概念、组成、特征 &#xff08;1&#xff09;知识总览 &#xff08;2&#xff09;进程的概念 &#xff08;3&#xff09;进程的组成—PCB &#xff08;4&#xff09;进程的组成---程序段和数据段 &#xff08;5&#xff09;程序是如何运行的呢&#xff1f…

Android和flutter交互,maven库的形式导入aar包

记录遇到的问题&#xff0c;在网上找了很多资料&#xff0c;都是太泛泛了&#xff0c;使用后&#xff0c;还不能生效&#xff0c;缺少详细的说明&#xff0c;或者关键代码缺失&#xff0c;我遇到的问题用红色的标注了 导入aar包有两种模式 1.比较繁琐的&#xff0c;手动将aar…

Java8-HashMap实现原理

目录 HashMap原理 hashmap的put流程&#xff1a; HashMap扩容机制&#xff1a; HashMap的寻址算法&#xff1a; HashMap原理 HashMap的底层数据结构是由&#xff0c;数组&#xff0c;链表和红黑树组成的。 当我们往HashMap中put元素的时候&#xff0c;利用key的hashCode重…

HC32F103BCB使用SPI获取AS5040编码器数据

1.AS5040介绍 2.硬件电路 硬件上使用SSI通信方式连接。 3.配置硬件SPI 查看手册&#xff0c;AS5040时序 可以看到在空闲阶段不发生数据传输的时候时钟(CLK)和数据(DO)都保持高电位(tCLKFE阶段)&#xff0c;在第一个脉冲的下降沿触发编码器载入发送数据&#xff0c;然后每一个…

【Unity Shader入门精要 第9章】更复杂的光照(四)

1. 透明度测试物体的阴影 对于物体有片元丢弃的情况&#xff0c;比如透明度测试或者后边会讲到的消融效果&#xff0c;使用默认的 ShadowCaster Pass 会产生问题&#xff0c;这是因为该Pass在生成阴影映射纹理时&#xff0c;没有考虑被丢弃的片元&#xff0c;而是使用完整的模…

FTP文件传输议

FTP是一种文件传输协议&#xff1a;用来上传和下载&#xff0c;实现远程共享文件&#xff0c;和统一管理文件 工作原理&#xff1a;用于互联网上的控制文件的双向传输是一个应用程序。工作在TCP/IP协议簇的&#xff0c;其传输协议是TCP协议提高文件传输的共享性和可靠性&#…

阅读笔记——《AFLNeTrans:状态间关系感知的网络协议模糊测试》

【参考文献】洪玄泉,贾鹏,刘嘉勇.AFLNeTrans&#xff1a;状态间关系感知的网络协议模糊测试[J].信息网络安全,2024,24(01):121-132.【注】本文仅为作者个人学习笔记&#xff0c;如有冒犯&#xff0c;请联系作者删除。 目录 摘要 1、引言 2、背景及动机 2.1、网络协议实现程…

正点原子LWIP学习笔记(二)MAC简介

MAC简介 一、MAC简介&#xff08;了解&#xff09;二级目录三级目录 二、ST的ETH框架&#xff08;了解&#xff09;三、SMI站管理接口&#xff08;熟悉&#xff09;四、介质接口MII、RMII&#xff08;熟悉&#xff09; 一、MAC简介&#xff08;了解&#xff09; STM32 的 MAC …

Ubuntu24.04设置静态IP地址

Ubuntu24.04设置静态IP地址 前言&#xff1a;vm17.5的动态IP问题 第一个是设置的静态IP我们可以看到是forever&#xff0c;第二个则是动态IP则是一天的时间。 如果我们不设置静态IP的话&#xff0c;那么可能在本地测试项目的时候&#xff0c;第二天发现一些服务不能用了&#…

13.js对象

定义 一种复杂数据类型&#xff0c;是无序的&#xff08;不保留键的插入顺序&#xff09;&#xff0c;以键值对&#xff08;{key:value})形式存放的数据集合 对象的创建 &#xff08;1&#xff09;字面量创建 var 对象名{ } &#xff08;2&#xff09;内部构造函数创建 v…

VirtualBox安装ubuntu22.04记录

一,VirtualBox 软件安装 虚拟机&#xff08;Virtual Machine&#xff09;指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。在实体计算机中能够完成的工作在虚拟机中都能够实现。 常见的虚拟机软件主要有两款 VMware 和 VirtualBox 。VMwar…

争议湖北消费金融2023年业绩,营收下滑or财务内控重大缺陷?

近日&#xff0c;湖北消费金融股份有限公司&#xff08;下称“湖北消费金融”&#xff09;披露了2023年度相关信息&#xff0c;包括股权结构、关联方、董事会、分支机构、资产负债情况等信息。 据介绍&#xff0c;湖北消费金融的注册资本为10.058亿元&#xff0c;法定代表人为…

linux---线程控制

线程和进程 以前我们要同时跑多个程序&#xff0c;可以通过fork()多个子进程&#xff0c;然后通过系统函数进行程序的替换&#xff0c;但是创建进程代价大&#xff0c;不仅要拷贝一份父进程的地址空间&#xff0c;页表&#xff0c;文件表述符表等。但是线程不需要因为是进程的…

使用JavaScript日历小部件和DHTMLX Gantt的应用场景(三)

DHTMLX Suite UI 组件库允许您更快地构建跨平台、跨浏览器 Web 和移动应用程序。它包括一组丰富的即用式 HTML5 组件&#xff0c;这些组件可以轻松组合到单个应用程序界面中。 DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表&#xff0c;可满足项目管理应用…

【调试笔记-20240520-Linux-在 WSL2 / Ubuntu 20.04 中编译 QEMU 可运行的 OVMF 固件】

调试笔记-系列文章目录 调试笔记-20240520-Linux-在 WSL2 / Ubuntu 20.04 中编译 QEMU 可运行的 OVMF 固件 文章目录 调试笔记-系列文章目录调试笔记-20240520-Linux-在 WSL2 / Ubuntu 20.04 中编译 QEMU 可运行的 OVMF 固件 前言一、调试环境操作系统&#xff1a;Windows 10 …

作业-day-240523

思维导图 知识点问答 1、IO多路复用的原理 1、创建一个检测文件描述符的容器 fd_set fds; 2、将需要检测的文件描述符放入容器中 FD_SET(文件描述符&#xff0c;&fds); 3、通过一个阻塞函数阻塞等待容器中是否有事件产生&#xff0c;如果有一个或多个事件产生&#xff0c…

C++设计模式|结构型 适配器模式

1.什么是适配器模式&#xff1f; 可以将⼀个类的接⼝转换成客户希望的另⼀个接⼝&#xff0c;主要⽬的是 充当两个不同接⼝之间的桥梁&#xff0c;使得原本接⼝不兼容的类能够⼀起⼯作。 2. 适配器模式的组成 &#xff08;1&#xff09;接口类&#xff0c;给客户端调用&…

软件设计师-上午题-计算题汇总

一、存储系统 - 存储容量计算&#xff08;字节编址、位编址、芯片个数&#xff09; 内存地址是16进制 内存地址编址的单位是Byte&#xff0c;1K1024B 1B 8 bit 1.计算存储单元个数 存储单元个数 末地址 - 首地址 1 eg. 按字节编址&#xff0c;地址从 A4000H 到 CBFFFH&…