【unity小技巧】实现无限滚动视图和类似CSGO的开箱抽奖功能及Content Size Fitter组件的使用介绍
文章目录
- 一篇一句
- 前言
- 素材
- 一、无限滚动视图
- 1. 绘制视图
- 2. Content Size Fitter是布局控件
- (1)在文本框中使用
- (2)控制Scroll View(Scroll Rect组件)控件下Content的大小
- 3. 控制视图无限滚动
- 4. 向右拉无限滚动
- 5. 修复滚动视图一卡一卡的问题
- 二、滚动选中视图
- 1. 和前面差不多 添加滚动视图
- 2. 挂载代码并配置参数
- 源码
- 完结
一篇一句
我们总喜欢拿顺其自然,敷衍人生道路上的荆棘坎坷,却很少承认,真正的顺其自然,其实是竭尽所能之后的不强求,而非两手一摊的不作为。 ——瑞卡斯
前言
先来看看最终实现效果
无限滚动视图

滚动选中视图

素材
链接:https://pan.baidu.com/s/159PuQjxYA0jdSLQ6y65mYw?pwd=qy5q
提取码:qy5q
一、无限滚动视图
1. 绘制视图
新增滚动视图,并禁止垂直滚动

添加布局组件和内容大小控制容器(设置为水平首选)
为什么使用Content Size Fitter是布局控件下面会介绍

添加遮罩组件Rect Mask 2D

添加字体

最终效果

2. Content Size Fitter是布局控件
这里我觉得有必要解释一下Content Size Fitter是布局控件的作用
(1)在文本框中使用
在文本框中添加这个Content Size Fitter组件,并设置为Preferred Size之后
文本框就会跟随文字的大小自由变化了,也是一个小技巧,但是就不可以再自定义控制文本框的大小了

(2)控制Scroll View(Scroll Rect组件)控件下Content的大小
- 在使用Scroll View组件的时候,一般会设置Content的大小来调节现实的内容
- 如果Content下的东西太多,就会拖不到最后面的模块了,所以这个时候给Content添加一个Content Size Fitter组件,将Vertical Fit的值设置为Preferred Size,那我们就不需要关心Content的Heigh高度了,这个时候就不怕子物体的多少了,都会正常显示出来。
演示一下
未使用Content Size Fitter组件的情况:

使用Content Size Fitter组件的情况:

可以看到未添加Content Size Fitter组件时,因为Content的大小我并没有手动调节到一个合适的大小,导致下面的拖不到
即使鼠标拖过去了,松开的时候也会返回到原来的位置
所以这个时候添加Content Size Fitter组件后,我们就可以达到一个理想的效果了
不用在考虑Content的大小调节了!
3. 控制视图无限滚动
using UnityEngine;
using UnityEngine.UI;public class InfiniteScroll : MonoBehaviour
{public ScrollRect scrollRect; // 滚动视图组件,用于控制滚动行为public RectTransform viewPortTransform; // 可视区域的RectTransform组件,用于获取可视区域的大小public RectTransform contentPanelTransform; // 内容面板的RectTransform组件,用于放置项的容器public HorizontalLayoutGroup HLG; // 水平布局组件,用于计算项之间的间距和对齐方式public RectTransform[] ItemList; // 项的列表,包含了所有可能的项void Start(){// 按照空白间距(spacing)和项的宽度(width),计算可视区域所需的项数int ItemsToAdd = Mathf.CeilToInt(viewPortTransform.rect.width / (ItemList[0].rect.width + HLG.spacing));Debug.Log(ItemsToAdd);// 根据上面计算出来的项数,创建轮播的初始项for (int i = 0; i < ItemsToAdd; i++){// 创建首批项并放置在内容面板的末尾RectTransform RT = Instantiate(ItemList[i % ItemList.Length], contentPanelTransform);//将新创建的项放置在内容面板的末尾,确保它们按顺序排列RT.SetAsLastSibling();}// 创建轮播的补位项,确保用户向左或向右滚动时都有相应的项可供显示for (int i = 0; i < ItemsToAdd; i++){// 计算下一批项在ItemList中的索引int num = ItemList.Length - i - 1;while (num < 0){// 对索引进行循环处理,确保不超过ItemList的长度num += ItemList.Length;}// 创建更多的项并放置在内容面板的开头RectTransform RT = Instantiate(ItemList[num], contentPanelTransform);//将新创建的项放置在内容面板的开头,确保它们按顺序排列RT.SetAsFirstSibling();}// 计算并设置内容面板的初始位置,使得第一批轮播项的左侧与可视区域的左侧对齐contentPanelTransform.localPosition = new Vector3((0 - (ItemList[0].rect.width + HLG.spacing) * ItemsToAdd), // 需要向左偏移的距离contentPanelTransform.localPosition.y, // 不需要上下偏移contentPanelTransform.localPosition.z // 不需要前后偏移);}
}
挂载脚本,配置好参数

效果

4. 向右拉无限滚动
void Update()
{// 如果内容面板偏移到可视区域左侧之外,则将其向右偏移一个完整的项的宽度if (contentPanelTransform.localPosition.x > 0){// 强制更新画布,确保UI显示正确Canvas.ForceUpdateCanvases();contentPanelTransform.localPosition -= new Vector3(ItemList.Length * (ItemList[0].rect.width + HLG.spacing), 0, 0);}// 如果内容面板偏移到可视区域右侧之外,则将其向左偏移一个完整的项的宽度if (contentPanelTransform.localPosition.x < 0 - (ItemList.Length * (ItemList[0].rect.width + HLG.spacing))){// 强制更新画布,确保UI显示正确Canvas.ForceUpdateCanvases();contentPanelTransform.localPosition += new Vector3(ItemList.Length * (ItemList[0].rect.width + HLG.spacing), 0, 0);}
}
效果

5. 修复滚动视图一卡一卡的问题
内容面板的速度会出现奇怪的行为,出现这种行为是因为当我们更改内容面板的位置时,它会影响速度计算,为了解决这个问题,当我们重置内容面板的位置时,我们需要忽略帧上的这些计算
修改代码
Vector2 Oldvelocity;// 上一帧的滚动速度
bool isUpdated;// 是否需要更新滚动速度void Start()
{isUpdated = false;Oldvelocity = Vector2.zero;//。。。
}
void Update()
{// 如果需要更新滚动速度,则将当前速度设置为上一帧的速度if(isUpdated){isUpdated = false;scrollRect.velocity = Oldvelocity;}if (contentPanelTransform.localPosition.x > 0){// 。。。// 更新滚动速度Oldvelocity = scrollRect.velocity;isUpdated = true;}// 如果内容面板偏移到可视区域右侧之外,则将其向左偏移一个完整的项的宽度if (contentPanelTransform.localPosition.x < 0 - (ItemList.Length * (ItemList[0].rect.width + HLG.spacing))){//。。。// 更新滚动速度Oldvelocity = scrollRect.velocity;isUpdated = true;}
}
效果,滚动就很平滑了

二、滚动选中视图
类似CSGO的开箱抽奖功能
1. 和前面差不多 添加滚动视图

效果

添加代码控制
x取整获得物品序号;ScrollRect.velocity判断滚动状态;Mathf.MoveTowards做平滑吸附;
using UnityEngine;
using UnityEngine.UI;
using TMPro;public class SnapToItem : MonoBehaviour
{public ScrollRect scrollRect; // 滚动视图组件public RectTransform contentPanel; // 内容面板组件public RectTransform sampleListItem; // 样本列表项组件public HorizontalLayoutGroup HLG; // 水平布局组件public TMP_Text NameLabel; // 显示当前选中项的标签public string[] ItemNames; // 列表项的名称数组bool isSnapped; // 是否已经对齐到了一个物品public float snapForce; // 对齐时的强度float snapSpeed; // 对齐时的速度void Start(){isSnapped = false;}void Update(){// 当前选中项的索引int currentItem = Mathf.RoundToInt((0 - contentPanel.localPosition.x) / (sampleListItem.rect.width + HLG.spacing));Debug.Log(currentItem);// 如果滚动速度小于200且没有对齐到一个物品,则进行对齐操作if (scrollRect.velocity.magnitude < 200 && !isSnapped){scrollRect.velocity = Vector2.zero;snapSpeed += snapForce * Time.deltaTime;contentPanel.localPosition = new Vector3(Mathf.MoveTowards(contentPanel.localPosition.x, 0 - (currentItem * (sampleListItem.rect.width + HLG.spacing)), snapSpeed),contentPanel.localPosition.y,contentPanel.localPosition.z);// 更新当前选中项的标签if (currentItem >= 0 && currentItem < ItemNames.Length){NameLabel.text = ItemNames[currentItem];}else{NameLabel.text = "_____";}// 如果已经对齐到了一个物品,则停止对齐if (contentPanel.localPosition.x == 0 - (currentItem * (sampleListItem.rect.width + HLG.spacing))){isSnapped = true;}}// 如果滚动速度大于200,则重置对齐状态if(scrollRect.velocity.magnitude > 200){NameLabel.text = "_____";isSnapped = false;snapSpeed = 0;}}
}
2. 挂载代码并配置参数

效果

源码
为了防止大家变懒,源码就不提供了,大家直接可以照着文章思路进行学习
完结
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。点赞越多,更新越快哦!当然,如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!
好了,我是向宇,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,出于兴趣爱好,于是最近才开始自习unity。如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

相关文章:
【unity小技巧】实现无限滚动视图和类似CSGO的开箱抽奖功能及Content Size Fitter组件的使用介绍
文章目录 一篇一句前言素材一、无限滚动视图1. 绘制视图2. Content Size Fitter是布局控件(1)在文本框中使用(2)控制Scroll View(Scroll Rect组件)控件下Content的大小 3. 控制视图无限滚动4. 向右拉无限滚动5. 修复滚动视图一卡一…...
Mybatis的SqlRunner执行流程
Mybatis的SqlRunner执行流程 SqlRunner exec new SqlRunner(connection); Map<String, Object> row exec.selectOne("SELECT * FROM PRODUCT WHERE PRODUCTID ?", "FI-SW-01");connection.close();assertEquals("FI-SW-01", row.ge…...
Zookeeper、Kafka集群与Filebeat+Kafka+ELK架构、部署实例
Zookeeper、Kafka集群与FilebeatKafkaELK架构、部署实例 一、Zookeeper1.1、Zookeeper 定义1.2、Zookeeper 工作机制1.3、Zookeeper 特点1.4、Zookeeper 数据结构1.5、Zookeeper 应用场景1.5、Zookeeper 选举机制1.5.1、 第一次启动选举机制1.5.2、 非第一次启动选举机制 二、Z…...
leetcode做题笔记198. 打家劫舍
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的…...
【编解码格式】DV
DV DV是指用于存储数位影片(英语:Digital video)的一种编解码器和录像带格式系列,由索尼和松下为首的摄像机制造商联盟于1995年推出。20世纪90年代末和21世纪初,DV与从模拟到数字的桌面式视频制作的过渡密切相关&…...
Flink之常用处理函数
常用处理函数 处理函数概述 基本处理函数ProcessFunction介绍使用示例 按键分区处理函数KeyedProcessFunction介绍定时器Timer和定时服务TimerService使用示例其他 窗口处理函数ProcessWindowFunction介绍ProcessAllWindowFunction介绍使用示例 流的合并处理函数CoProcessFunct…...
【C语言】善于利用指针(三)
💗个人主页💗 ⭐个人专栏——C语言初步学习⭐ 💫点击关注🤩一起学习C语言💯💫 目录 导读:1. 函数指针1.1 什么使函数指针1.2 用函数指针变量调用函数 2. 返回指针值的函数3. 函数指针数组3.1 实…...
ant design vue Message 用法以及内容为 html片段情况
ant design vue 的 Message 用法 全局展示操作反馈信息 何时使用 # 可提供成功、警告和错误等反馈信息。顶部居中显示并自动消失,是一种不打断用户操作的轻量级提示方式。 全局配置: // main.ts// 进行全局配置 message.config({top: 0.7rem,//高度…...
HotSpot算法细节实现——安全点
OopMap 垃圾回收时,如何找到垃圾? 在可达性分析算法中从GC Roots集合找引用链分析对象是否可达。 固定可作为GC Roots的节点主要在全局性的引用(例如常量或类静态属性)与执行上下文(例如栈帧中的本地变量表…...
杂谈:DC对Verilog和SystemVerilog语言的支持
DC对Verilog和SystemVerilog语言的支持 设计语言用哪种?Design Compiler对二者的支持简单的fsm电路测试测试结果对比写在最后 设计语言用哪种? 直接抛出结论:先有电路,后为描述。设计端而言,没有语言的高低好坏&#…...
网络安全评估(网络安全评估)
讨论了基于互联网的网络安全评估和渗透测试的基本原理,网络安全服务人员,安全运营人员,通过评估来识别网络中潜在的风险,并对其进行分类分级。 黑客通常采取的攻击方式如下: 突破目标外围系统,比如主站拿…...
offsetof宏计算某变量相对于首地址的偏移量
宏:offsetof的使用 //offsetof (type,member) //type是结构体的类型名,member是结构体中的成员名。struct Student {char name[5]; // 姓名int age; // 年龄float score; // 成绩 };int main() {struct Student s;printf("%zd\n", off…...
算法|每日一题|统计无向图中无法互相到达点对数|并查集
2316. 统计无向图中无法互相到达点对数 原题地址: 力扣每日一题:统计无向图中无法互相到达点对数 给你一个整数 n ,表示一张 无向图 中有 n 个节点,编号为 0 到 n - 1 。同时给你一个二维整数数组 edges ,其中 edges[i…...
浏览器的四种缓存协议
❤️浏览器缓存 在HTTP里所谓的缓存本质上只是浏览器和业务侧根据不同的报文字段做出不同的缓存动作而已 四种缓存协议如下 Cache-ControlExpiresETag/If-None-MatchLast-Modified/If-Modified-Since 🎡Cache-Control 通过响应头设置Cache-Control和max-age&…...
力扣每日一题55:跳跃游戏
题目描述: 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 …...
mssql调用外部接口
前言: 断更很久了。 是因为这段时间发现,AI出来之后,很多博客都没有记录的必要了,你问他他都能即时告诉你。 这篇博客产出的原因是,看到一份奇葩需求,说数据库改某行数据的状态字段,也要调用接…...
npx是什么命令?npx和npm有什么区别?
平时安装node模块的时候,经常使用的命令是npm。其实还有另外一个命令,叫做npx。网上的说法都是:npx是npm命令的升级版本,功能非常强大。 npx 是什么 npx是一个由Node.js官方提供的用于快速执行npm包中的可执行文件的工具。它可以…...
1997-2017年各省能源投入数据(万吨标准煤)
1997-2017年各省能源投入数据(万吨标准煤) 1、时间:1997-2017年 2、来源:中国统计年鉴 3、范围:30个省 4、指标:能源投入(各省8种能源消费总量计算得出)(万吨标准煤&…...
C++ Primer笔记001:标准输入输出/基本数据/流程控制语句
文章目录 1.标准输入cin:2.标准输入cout:3.endl:4.命名空间(namespace):5.有符号类型和无符号类型6.字面值常量7.变量的初始化和赋值8.变量的作用域9 求余运算符的符号10.关于sizeof11.switch case语句漏写break 1.标准…...
【C++进阶之路】IO流
文章目录 一、C语言的IO1.键盘与显示屏2. 文件与内存3.字符串与内存 二、CIO1.iostream1.1基本使用1.2operator bool 2. fstream2.1二进制的文件读写2.2字符串的文件读写 3. sstream3.1序列化与反序列化3.2拼接字符串3.3将数据类型转换为字符串 总结 一、C语言的IO 1.键盘与显…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...
高抗扰度汽车光耦合器的特性
晶台光电推出的125℃光耦合器系列产品(包括KL357NU、KL3H7U和KL817U),专为高温环境下的汽车应用设计,具备以下核心优势和技术特点: 一、技术特性分析 高温稳定性 采用先进的LED技术和优化的IC设计,确保在…...
设计模式-3 行为型模式
一、观察者模式 1、定义 定义对象之间的一对多的依赖关系,这样当一个对象改变状态时,它的所有依赖项都会自动得到通知和更新。 描述复杂的流程控制 描述多个类或者对象之间怎样互相协作共同完成单个对象都无法单独度完成的任务 它涉及算法与对象间职责…...
【设计模式】1.简单工厂、工厂、抽象工厂模式
every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 以下是 简单工厂模式、工厂方法模式 和 抽象工厂模式 的 Python 实现与对比,结合代码示例和实际应用场景说明: 1. 简单工厂模式&a…...
OGG-01635 OGG-15149 centos服务器远程抽取AIX oracle11.2.0.4版本
背景描述 有一套ogg远程抽取的环境,源端是AIX7.1环境的oracle 11.2.0.4版本的数据库,中间是OGG抽取服务器,目标端是centos 7.9环境的oracle 19c。 采用集成模式远程抽取源端数据正常,但是经典模式远程抽取源数据的时候抽取进程启…...
如何写一篇基于Spring Boot + Vue + 微信小程序的软件的接口文档
如何写一篇基于Spring Boot Vue 微信小程序的软件的接口文档 下面是一个例子,仅供参考! 基于Spring Boot Vue 微信小程序的博客系统接口文档 技术栈:Spring Boot 3.x Vue 3 Element Plus 微信小程序原生框架 文档版本:v1…...
