当前位置: 首页 > 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.键盘与显…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...