当前位置: 首页 > news >正文

【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是布局控件&#xff08;1&#xff09;在文本框中使用&#xff08;2&#xff09;控制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. 打家劫舍

你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个房屋存放金额的…...

【编解码格式】DV

DV DV是指用于存储数位影片&#xff08;英语&#xff1a;Digital video&#xff09;的一种编解码器和录像带格式系列&#xff0c;由索尼和松下为首的摄像机制造商联盟于1995年推出。20世纪90年代末和21世纪初&#xff0c;DV与从模拟到数字的桌面式视频制作的过渡密切相关&…...

Flink之常用处理函数

常用处理函数 处理函数概述 基本处理函数ProcessFunction介绍使用示例 按键分区处理函数KeyedProcessFunction介绍定时器Timer和定时服务TimerService使用示例其他 窗口处理函数ProcessWindowFunction介绍ProcessAllWindowFunction介绍使用示例 流的合并处理函数CoProcessFunct…...

【C语言】善于利用指针(三)

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C语言初步学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读&#xff1a;1. 函数指针1.1 什么使函数指针1.2 用函数指针变量调用函数 2. 返回指针值的函数3. 函数指针数组3.1 实…...

ant design vue Message 用法以及内容为 html片段情况

ant design vue 的 Message 用法 全局展示操作反馈信息 何时使用 # 可提供成功、警告和错误等反馈信息。顶部居中显示并自动消失&#xff0c;是一种不打断用户操作的轻量级提示方式。 全局配置&#xff1a; // main.ts// 进行全局配置 message.config({top: 0.7rem,//高度…...

HotSpot算法细节实现——安全点

OopMap 垃圾回收时&#xff0c;如何找到垃圾&#xff1f; 在可达性分析算法中从GC Roots集合找引用链分析对象是否可达。 固定可作为GC Roots的节点主要在全局性的引用&#xff08;例如常量或类静态属性&#xff09;与执行上下文&#xff08;例如栈帧中的本地变量表&#xf…...

杂谈:DC对Verilog和SystemVerilog语言的支持

DC对Verilog和SystemVerilog语言的支持 设计语言用哪种&#xff1f;Design Compiler对二者的支持简单的fsm电路测试测试结果对比写在最后 设计语言用哪种&#xff1f; 直接抛出结论&#xff1a;先有电路&#xff0c;后为描述。设计端而言&#xff0c;没有语言的高低好坏&#…...

网络安全评估(网络安全评估)

讨论了基于互联网的网络安全评估和渗透测试的基本原理&#xff0c;网络安全服务人员&#xff0c;安全运营人员&#xff0c;通过评估来识别网络中潜在的风险&#xff0c;并对其进行分类分级。 黑客通常采取的攻击方式如下&#xff1a; 突破目标外围系统&#xff0c;比如主站拿…...

offsetof宏计算某变量相对于首地址的偏移量

宏&#xff1a;offsetof的使用 //offsetof (type,member) //type是结构体的类型名&#xff0c;member是结构体中的成员名。struct Student {char name[5]; // 姓名int age; // 年龄float score; // 成绩 };int main() {struct Student s;printf("%zd\n", off…...

算法|每日一题|统计无向图中无法互相到达点对数|并查集

2316. 统计无向图中无法互相到达点对数 原题地址&#xff1a; 力扣每日一题&#xff1a;统计无向图中无法互相到达点对数 给你一个整数 n &#xff0c;表示一张 无向图 中有 n 个节点&#xff0c;编号为 0 到 n - 1 。同时给你一个二维整数数组 edges &#xff0c;其中 edges[i…...

浏览器的四种缓存协议

❤️浏览器缓存 在HTTP里所谓的缓存本质上只是浏览器和业务侧根据不同的报文字段做出不同的缓存动作而已 四种缓存协议如下 Cache-ControlExpiresETag/If-None-MatchLast-Modified/If-Modified-Since &#x1f3a1;Cache-Control 通过响应头设置Cache-Control和max-age&…...

力扣每日一题55:跳跃游戏

题目描述&#xff1a; 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 …...

mssql调用外部接口

前言&#xff1a; 断更很久了。 是因为这段时间发现&#xff0c;AI出来之后&#xff0c;很多博客都没有记录的必要了&#xff0c;你问他他都能即时告诉你。 这篇博客产出的原因是&#xff0c;看到一份奇葩需求&#xff0c;说数据库改某行数据的状态字段&#xff0c;也要调用接…...

npx是什么命令?npx和npm有什么区别?

平时安装node模块的时候&#xff0c;经常使用的命令是npm。其实还有另外一个命令&#xff0c;叫做npx。网上的说法都是&#xff1a;npx是npm命令的升级版本&#xff0c;功能非常强大。 npx 是什么 npx是一个由Node.js官方提供的用于快速执行npm包中的可执行文件的工具。它可以…...

1997-2017年各省能源投入数据(万吨标准煤)

1997-2017年各省能源投入数据&#xff08;万吨标准煤&#xff09; 1、时间&#xff1a;1997-2017年 2、来源&#xff1a;中国统计年鉴 3、范围&#xff1a;30个省 4、指标&#xff1a;能源投入&#xff08;各省8种能源消费总量计算得出&#xff09;&#xff08;万吨标准煤&…...

C++ Primer笔记001:标准输入输出/基本数据/流程控制语句

文章目录 1.标准输入cin&#xff1a;2.标准输入cout&#xff1a;3.endl&#xff1a;4.命名空间&#xff08;namespace)&#xff1a;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.键盘与显…...

户外摄像头监控如何兼顾安全实时监控

一、技术手段提升隐私安全性 硬件与功能设计 采用支持隐私保护技术的设备&#xff0c;例如带电子开关的摄像头&#xff08;可远程控制摄像头启闭&#xff09;3&#xff0c;或搭载本地AI算法的设备&#xff0c;仅识别人形、车辆等目标&#xff0c;减少无关信息采集。 使用安全…...

深度学习赋能图像识别:技术、应用与展望

论文&#xff1a; 一、引言​ 1.1 研究背景与意义​ 在当今数字化时代&#xff0c;图像作为信息的重要载体&#xff0c;广泛存在于各个领域。图像识别技术旨在让计算机理解和识别图像内容&#xff0c;将图像中的对象、场景、行为等信息转化为计算机能够处理的符号或数据 &am…...

循环神经网络(RNN)全面教程:从原理到实践

循环神经网络(RNN)全面教程&#xff1a;从原理到实践 引言 循环神经网络(Recurrent Neural Network, RNN)是处理序列数据的经典神经网络架构&#xff0c;在自然语言处理、语音识别、时间序列预测等领域有着广泛应用。本文将系统介绍RNN的核心概念、常见变体、实现方法以及实际…...

数据库包括哪些?关系型数据库是什么意思?

目录 一、数据库包括哪些 &#xff08;一&#xff09;关系型数据库 &#xff08;二&#xff09;非关系型数据库 &#xff08;三&#xff09;分布式数据库 &#xff08;四&#xff09;内存数据库 二、关系型数据库是什么 &#xff08;一&#xff09;关系模型的基本概念 …...

Linux 驱动之设备树

Linux 驱动之设备树 参考视频地址 【北京迅为】嵌入式学习之Linux驱动&#xff08;第七期_设备树_全新升级&#xff09;_基于RK3568_哔哩哔哩_bilibili 本章总领 1.设备树基本知识 什么是设备树&#xff1f; ​ Linux之父Linus Torvalds在2011年3月17日的ARM Linux邮件列表…...

Vue 树状结构控件

1、效果图如下所示&#xff1a; 2、网络请求的数据结构如下&#xff1a; 3、新建插件文件&#xff1a;menu-tree.vue&#xff0c;插件代码如下&#xff1a; <template><div class"root"><div class"parent" click"onParentClick(pare…...

AIGC学习笔记(9)——AI大模型开发工程师

文章目录 AI大模型开发工程师008 LangChain之Chains模块1 Chain模块核心知识2 Chain模块代码实战LLMSequentialTransformationRouter AI大模型开发工程师 008 LangChain之Chains模块 1 Chain模块核心知识 组合常用的模块 LLM&#xff1a;最常见的链式操作类型SequentialChain…...

期货反向跟单运营逻辑推导思路

期货反向跟单运营逻辑推导思路 很多刚接触期货反向跟的朋友第一印象就是&#xff1a;这绝对是一个完美的策略&#xff0c;在认知不到位的情况下就开始运营&#xff0c;结果就是赔的稀里哗啦。然后告诉身边所有的人&#xff0c;期货反向跟单不靠谱。 这就是一个很有意思的事情&…...

奥威BI+AI数据分析:企业数智化转型的加速器

在当今数据驱动的时代&#xff0c;企业对于数据分析的需求日益增长。奥威BIAI数据分析的组合&#xff0c;正成为众多企业数智化转型的加速器。 奥威BI以其强大的数据处理和可视化能力著称。它能够轻松接入多种数据源&#xff0c;实现数据的快速整合与清洗。通过内置的ETL工具&…...

SOC-ESP32S3部分:28-BLE低功耗蓝牙

飞书文档https://x509p6c8to.feishu.cn/wiki/CHcowZMLtiinuBkRhExcZN7Ynmc 蓝牙是一种短距的无线通讯技术&#xff0c;可实现固定设备、移动设备之间的数据交换&#xff0c;下图是一个蓝牙应用的分层架构&#xff0c;Application部分则是我们需要实现的内容&#xff0c;Protoc…...