unity UGUI无限循环滚动居中

最近在做一个ui循环滚动的功能,网上找了半天脚本感觉都和我实际需求不太符合,自己花费一些时间完成了这个功能记录一下。下面开始正题
,我是采用unity自带组件Scroll View来完成,首先设置Scroll View如下图
我是横屏你可以根据情况选择你的
面板层级结构如下
层级面板结构
然后创建一个预制体,预制体需要锚点到左侧中心点,设置为起始点,设置完成后把这个图片随便放个层级不要在本层级,不要影响后面生成。
红色就是UI
然后开始编写代码,我就直接贴了,不懂可以看一下注释,因为我是水平所以判断用的都是x轴,如果你是垂直你改成y稍微修改一下代码就可以了,差别应该不大。

using DG.Tweening;
using System.Collections;
using System.Collections.Generic;using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;public class LoopScroll : MonoBehaviour,IBeginDragHandler  
{public List<Sprite> photographList;[Header("中心点")]public Transform Centre;private Vector3 startPos, endPos;[Header("预制体")]public GameObject item;[Header("预制体父级")]public Transform Content;[HideInInspector]public List<Transform> itemList;bool isDrag = false, isAdsorption;float MaxDis, MinDis;[Header("间隔距离")]public float SpacingDistance = 100;[Header("缩放倍数")]public float Scale =1;Transform tempCentre;   public Text tempCentreName;private void Awake(){instantiationItem();}void Start(){            isDrag = true;//设置第一个坐标与最后一个坐标位置startPos = itemList[0].position;endPos = itemList[itemList.Count - 1].position;startPos.x -= itemList[0].GetComponent<RectTransform>().rect.width /2;endPos.x += itemList[0].GetComponent<RectTransform>().rect.width / 2;//求出最远距离for (int i = 0; i < itemList.Count; i++){var dis = Vector3.Distance(itemList[i].position, Centre.position);if (dis > MaxDis){MaxDis = dis;MinDis = dis;}}}void instantiationItem()//生成预制体设置初始坐标{for (int i = 0; i < photographList.Count; i++){var t = Instantiate(item, Content);t.GetComponent<Image>().sprite = photographList[i];t.name = photographList[i].name;var pos = new Vector3((t.GetComponent<RectTransform>().rect.width + SpacingDistance) * (i), 0, 0);pos.x += t.GetComponent<RectTransform>().rect.width;t.GetComponent<RectTransform>().anchoredPosition = pos;itemList.Add(t.transform);}}void Islimit() //设置坐标切换与列表内元素与面板层级切换 保证层级与列表内数据同步{if (isDrag){for (int i = 0; i < itemList.Count; i++){if (itemList[i].position.x < startPos.x){itemList[i].position = itemList[itemList.Count - 1].position + new Vector3(SpacingDistance + itemList[0].GetComponent<RectTransform>().rect.width, 0, 0);var temp = itemList[i];itemList.Remove(itemList[i]);itemList.Add(temp);temp.SetSiblingIndex(itemList.Count - 1);}if (itemList[i].position.x > endPos.x){itemList[i].position = itemList[0].position - new Vector3(SpacingDistance + itemList[0].GetComponent<RectTransform>().rect.width, 0, 0);var temp = itemList[i];itemList.Remove(itemList[i]);itemList.Insert(0, temp);temp.SetSiblingIndex(0);}}}}void ScaleDistance()//根据百分比设置缩放动画{for (int i = 0; i < itemList.Count; i++){double dis = Vector3.Distance(itemList[i].position, Centre.position) / MaxDis;if (!double.IsInfinity(dis)){if (dis > 0){if (dis<0.05f){itemList[i].localScale = Vector3.one * ((1f - (float)dis) * Scale) ;}else{itemList[i].localScale = Vector3.one * ((1f - (float)dis) * Scale) * 0.8f;}}}} }Tween tw;void Adsorption() //停止滑动进行吸附{for (int i = 0; i < itemList.Count; i++)//找出距离中心点最近的{float dis = Vector3.Distance(itemList[i].position, Centre.position);if (dis < MinDis){tempCentre = itemList[i];tempCentreName.text = itemList[i].name;}MinDis = dis;}if (GetComponent<ScrollRect>().velocity.x==0 && isAdsorption == false)//判断当前滑动结束{//计算当前距离中心差多远后 进行吸附if (tempCentre){var dis = Centre.position - tempCentre.position;tw = Content.DOMoveX(Content.position.x + dis.x, 0.5f);tempCentre = null;isAdsorption = true;}else{isAdsorption = false;}}else if (GetComponent<ScrollRect>().velocity.x!=0)//如果在吸附过程中点击拖拽强制结束吸附动画{isAdsorption = false;tw.Kill();}}// Update is called once per frame  void Update(){Islimit();ScaleDistance();Adsorption();}public void OnBeginDrag(PointerEventData eventData){tw.Kill();}
}

下面这个是脚本设置,主要关注的就是公开的变量我都有注释,结合上面的面板图很轻易就能看出来,第一个就是循环图片,间隔距离是两个图片之间的距离,缩放倍数是中间最大是多少倍,根据你工程设置,默认设置1就可以了,最后面的text是显示居中ui的名字,名字的设置是根据图片名称来的。
在这里插入图片描述
运行后这三个内容层级都会同步,可以进行一些你想要的操作
在这里插入图片描述

最后说下使用了Dotween插件,吸附居中功能我是感觉有点延迟,但是还没找到更好的方法,如果大家有更好的方法欢迎大佬留言,完成上面的设置就可以畅快玩耍了~~

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

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

相关文章

C语言每日一题(29)合并两个有序链表

力扣网 21合并两个有序链表 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 思路分析 最基本的一种思路就是&#xff0c;遍历两个链表&#xff0c;将对应结点的值进行比较&#xff0c;题目要求是要升序排…

二部图问题

目录 一、介绍 二、染色算法的实现 三、无权二部图中的最大匹配 四、有权二部图中的最大匹配 五、稳定婚配问题 一、介绍 二部图是一种特殊的图&#xff0c;其中所有的节点可以被分成两个不相交的集合&#xff0c;使得图中的每条边连接的两个节点分属于不同的集合。换句话…

什么是GIL锁,有什么作用?python的垃圾回收机制是什么样的?解释为什么计算密集型用多进程,io密集型用多线程。

1 什么是gil锁&#xff0c;有什么作用&#xff1f; 2 python的垃圾回收机制是什么样的&#xff1f; 3 解释为什么计算密集型用多进程&#xff0c;io密集型用多线程。 1 什么是gil锁&#xff0c;有什么作用&#xff1f; 1 GIL&#xff1a;Global Interpreter Lock又称全局解释器…

基于安卓android微信小程序的食谱大全系统

项目介绍 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和mysql数据库来完成对系统的设计。整个开发过程首先对食谱大全进行需求分析&#xff0c;得出食谱大全主要功能。接着对食谱大全进行总体设计和详细设计。总体设…

源码升级gcc

wget https://ftp.gnu.org/gnu/gcc/gcc-8.1.0/gcc-8.1.0.tar.gztar -xzf gcc-8.1.0.tar.gzcd gcc-8.1.0/打开/contrib/download_prerequisites&#xff0c;查看依赖的库 wget http://mirror.linux-ia64.org/gnu/gcc/infrastructure/mpfr-3.1.4.tar.bz2 & wget http://mir…

实现高值医疗耗材智能化管理的RFID医疗柜解决方案

一、行业背景 医疗物资管理面临着一系列问题&#xff0c;如高值耗材种类激增导致准入标准弱化、信息追踪困难、管理责任不明确等&#xff0c;医院内部设备、财务和临床科室相互独立&#xff0c;兼容性不佳&#xff0c;高值耗材储备不足&#xff0c;缺乏合理的预警机制&#xf…

Java 21:最新特性、性能改进和语言发展

文章目录 模式匹配和模式变量新的记录类型生产者接口本地类型推断的扩展新的垃圾收集器动态CDS档案G1垃圾收集器的增强Java语言的持续发展性能改进和JEPJava 21的部署和使用Java 21的生态系统结语 &#x1f389;欢迎来到Java学习路线专栏~Java 21&#xff1a;最新特性、性能改进…

Postman接口Mock Servier服务器

近期在复习Postman的基础知识&#xff0c;在小破站上跟着百里老师系统复习了一遍&#xff0c;也做了一些笔记&#xff0c;希望可以给大家一点点启发。 应用场景&#xff1a;后端的接口还没有开发完成&#xff0c;前端的业务需要调用后端的接口&#xff0c;可以使用mock模拟。 一…

Android高级实践分享

以下是我学习过程中&#xff0c;觉得比较好的Android进阶高级实践&#xff0c;分享给大家&#xff0c;可能有些东西差异化比较大了&#xff0c;但是我也想经过这些实践&#xff0c;踩踩坑。等我搞完&#xff0c;给大家出一下实践教程 Android进阶之旅&#xff1a; https://ww…

终于有人把VMware虚拟机三种网络模式讲清楚了!

前段时间VMware更新了&#xff0c;你用上最新版了吗&#xff1f; 有几个网工在操作中遇到过各种各样的问题。 比如说由于公司服务器重启导致出现下面的问题&#xff1a;在Xshell里连接虚拟机映射时连接失败&#xff1b;能够连接上虚拟机的映射地址&#xff0c;但git pull时报…

电子电机行业万界星空科技MES解决方案

现在电子电机行业规模越来越大&#xff0c;也伴随着生产和管理成本走向变高的现象。针对这个问题&#xff0c;mes系统就成为各电子电机制造业的最优选择。 电子机电行业MES涵盖了从原材料采购到最终产品交付的整个过程&#xff0c;包括生产计划、物料管理、生产过程监控、质量…

CleanMyMac X“断网激活”真的可以吗?

CleanMyMac X帮助Mac系统进行垃圾清理&#xff0c;清除多余的缓存、应用程序等&#xff0c;在提高工作效率上起了很大的作用。但是随着对软件的需求不断增加&#xff0c;很多人开始研究通过捷径破解正版软件&#xff0c;但是是否能成功呢&#xff1f;今天小编就为大家揭开“断网…

【常见SQL报错及解决办法】个人记录,自用

ORA-00942: 表或视图不存在 现象&#xff1a;明明已经新建了视图&#xff0c;并提交了&#xff0c;直接查询的时候还是报了这个错 解决&#xff1a;视图名那加双引号&#xff0c;与建立的时候保持一致 --SELECT * FROM VIEW_NAME 报错&#xff0c;需要加双引号 SELECT * FR…

7-爬虫-中间件和下载中间件(加代理,加请求头,加cookie)、scrapy集成selenium、源码去重规则(布隆过滤器)、分布式爬虫

0 持久化(pipelines.py)使用步骤 1 爬虫中间件和下载中间件 1.1 爬虫中间件(一般不用) 1.2 下载中间件&#xff08;代理&#xff0c;加请求头&#xff0c;加cookie&#xff09; 1.2.1 加请求头(加到请求对象中) 1.2.2 加cookie 1.2.3 加代理 2 scrapy集成selenium 3 源码去重…

C++ 动态规划 DP教程 (一)思考过程(*/ω\*)

动态规划是一种思维方法&#xff0c;大家首先要做的就是接受这种思维方法&#xff0c;认同他&#xff0c;然后再去运用它解决新问题。 动态规划是用递推的思路去解决问题。 首先确定问题做一件什么事情&#xff1f; 对这件事情分步完成&#xff0c;分成很多步。 如果我们把整件…

【SpringBoot】序列化和反序列化介绍

一、认识序列化和反序列化 Serialization&#xff08;序列化&#xff09;是一种将对象以一连串的字节描述的过程&#xff1b;deserialization&#xff08;反序列化&#xff09;是一种将这些字节重建成一个对象的过程。将程序中的对象&#xff0c;放入文件中保存就是序列化&…

回顾 — SFA:简化快速 AlexNet(模糊分类)

模糊图像的样本 一、说明 在本文回顾了基于深度学习的模糊图像分类&#xff08;SFA&#xff09;。在本文中&#xff1a;Simplified-Fast-AlexNet (SFA)旨在对图像是否因散焦模糊、高斯模糊、雾霾模糊或运动模糊而模糊进行分类。 二、大纲 图像模糊建模简要概述简化快速 AlexNet…

vscode 快速打印console.log

第一步 输入这些 {// Print Selected Variabl 为自定义快捷键中需要使用的name&#xff0c;可以自行修改"Print Selected Variable": {"body": ["\nconsole.log("," %c $CLIPBOARD: ,"," background-color: #3756d4; padding:…

action3录制出来的LRF文件的正确打开方式

你会发现使用大疆的产品录制出来的视频会有两种格式&#xff1a;LRF和MP4 这个LRF文件是低分辨率、低码率的预览文件&#xff0c;非常适合预览。 这个文件可以直接通过修改文件后缀转化为.mp4格式