【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.键盘与显…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...
热烈祝贺埃文科技正式加入可信数据空间发展联盟
2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...
