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

【Unity】实现从Excel读取数据制作年份选择器

效果预览:

此处利用Excel来读取数据来制作年份选择器,具体步骤如下。

如果只是制作年份选择器可以参考我这篇文章:构建简单实用的年份选择器(简单原理示范)

目录

效果预览:

一、 Excel准备与存放

1.1 Excel准备

1.2 存放Excel

1.3 读取Excel准备

二、场景准备 

三、编写脚本 

四、总结 


一、 Excel准备与存放

1.1 Excel准备

打开Excel,填写内容,保存命名为“年份”。示例如下:

1.2 存放Excel

将命名为“年份”的excel文件存放在Assets根目录下

1.3 读取Excel准备

读取Excel的几种方式可以参考这篇文章:读取Excel的几种方式

此处使用DLL插件读取

将所需插件放入Plugins文件夹中

二、场景准备 

 场景包括显示年份的背景和字体等内容,具体可以参考这篇文章: 构建简单实用的年份选择器(简单原理示范)

三、编写脚本 

此处编写了两个脚本,分别是ExcelTool和YearAdsorption,ExcelTool实现读取Excel内容并记录,YearAdsorption来实现生成年份。

using System.Data; // 引入System.Data命名空间,用于处理数据表
using System.IO; // 引入System.IO命名空间,用于文件操作
using Excel; // 引入Excel命名空间,用于读取Excel文件
using UnityEngine; // 引入UnityEngine命名空间,用于Unity相关功能public class ExcelTool : MonoBehaviour
{public static string[] YearsItemsStr;//用来存放Excel中的年份public static int YearsItemsNum; //用来存放Excel中的年份数量void Start(){ReadExcel("/年份.xlsx"); // 调用读取Excel方法,并传入文件路径}// 读取Excel文件public void ReadExcel(string xmlName){FileStream stream = File.Open(Application.dataPath + xmlName, FileMode.Open, FileAccess.Read, FileShare.Read); // 打开Excel文件流//IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);//读取 Excel 1997-2003版本IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream); // 使用OpenXml读取 Excel 2007及以后的版本DataSet result = excelReader.AsDataSet(); // 将Excel数据读取到DataSet中if (stream != null){stream.Close(); // 关闭文件流}//DataSet可以包含多个数据表,索引从0开始,所以result.Tables[0]代表第一个表格。int[] counts = GetCount(result.Tables[0]); // 获取Excel表格的行数和列数int rows = counts[0]; // 行数int columns = counts[1]; // 列数YearsItemsNum = rows - 1;//记录年份数量Debug.Log("Excel年份数YearsItemsNum:" + YearsItemsNum);YearsItemsStr = new string[rows - 1];Debug.Log("row:" + rows + "...col:" + columns); // 打印行数和列数信息// 遍历Excel表格并打印内容for (int i = 1; i < rows; i++)//将表头"年份"不包括在内于是i!=0{for (int j = 0; j < columns; j++){Debug.Log(result.Tables[0].Rows[i][j].ToString()); // 打印单元格内容YearsItemsStr[i-1] = result.Tables[0].Rows[i][j].ToString();}}}// 获取数据表的行数和列数private int[] GetCount(DataTable dt){int i = dt.Rows.Count; // 获取行数for (int m = 0; m < dt.Rows.Count; m++){if (string.IsNullOrEmpty(dt.Rows[m][0].ToString())) // 判断第一列是否为空{i = m; // 如果为空,记录有效行数break;}}int j = dt.Columns.Count; // 获取列数for (int n = 0; n < dt.Columns.Count; n++){if (string.IsNullOrEmpty(dt.Rows[0][n].ToString())) // 判断第一行是否为空{j = n; // 如果为空,记录有效列数break;}}return new int[] { i, j }; // 返回行数和列数的数组}
}

using UnityEngine;
using UnityEngine.UI;public class YearAdsorption : MonoBehaviour
{public GameObject yearTextPrefab; // 预设的年份Text对象public ScrollRect scrollRect;public float scaleDifference = 0.5f; // 缩放差异public RectTransform contentRectTrans; // Scroll Rect Content的RectTransformprivate RectTransform[] items;//用来存放生成的年份//int yearsCount = 40; // 年份总数float viewPortSize;float center;int itemCount;void Start(){// 获取ScrollView的视图大小300;viewPortSize = scrollRect.viewport.rect.height;Debug.Log("ScrollView的视图大小:" + viewPortSize);// 计算ScrollView的中心位置center = scrollRect.transform.position.y;// - viewPortSize / 2;       Debug.Log("ScrollView的中心位置:" + center);Debug.Log("YearAdsorption的YearsItemsNum:" + ExcelTool.YearsItemsNum);for (int i = 0; i < ExcelTool.YearsItemsNum; i++)//int i = 0; i < yearsCount; i++{GenerateYearText(ExcelTool.YearsItemsStr[i]);//1950+iint.Parse(ExcelTool.YearsItemsStr[i])Debug.Log("YearAdsorption年份:" + ExcelTool.YearsItemsStr[i]);}//for (int i = 0; i < yearsCount; i++)//int i = 0; i < yearsCount; i++//{//    GenerateYearText((1950 + i).ToString());//1950+iint.Parse(ExcelTool.YearsItemsStr[i])//}// 获取ScrollView中的所有子对象itemCount = scrollRect.content.childCount;items = new RectTransform[itemCount];for (int i = 0; i < itemCount; i++){items[i] = scrollRect.content.GetChild(i).GetComponent<RectTransform>();//Debug.Log("items[i]: " + i);}}void Update(){foreach (RectTransform item in items){// 计算每个项目的中心位置float itemCenter = item.transform.position.y;// - item.rect.height / 2;//Debug.Log("每个项目的中心位置: " + itemCenter);// 计算每个项目相对于ScrollView中心的偏移量float distanceFromCenter = Mathf.Abs(center - itemCenter);// 根据偏移量计算缩放比例float scale = Mathf.Clamp(1 - distanceFromCenter * scaleDifference / viewPortSize, 0.5f, 1f);//Debug.Log("根据偏移量计算缩放比例: " + scale);// 应用缩放item.localScale = new Vector3(scale, scale, 1f);}// 如果用户停止滑动,则吸附到最近的年份if (scrollRect.velocity.magnitude <= 20.0f){SnapToNearestYear();Debug.Log("不移动了!");}}private void GenerateYearText(string year){GameObject yearText = Instantiate(yearTextPrefab, contentRectTrans);yearText.transform.SetAsFirstSibling();yearText.transform.GetComponent<Text>().text = year.ToString();}void SnapToNearestYear(){RectTransform closestItem = null;foreach (RectTransform item in items){float distance = Mathf.Abs(center - item.position.y);if (distance < 35)// 根据需求调整阈值{closestItem = item;Debug.Log("装入了一个Item");}}// 将最近的年份吸附到ScrollView的中心if (closestItem != null){// 计算需要移动的距离float distanceToMove = center - closestItem.position.y;// 将ScrollView的内容向上或向下移动,使最近的年份对象出现在ScrollView的中心scrollRect.content.anchoredPosition += new Vector2(0f, distanceToMove);}}
}

这里注意两个脚本的执行顺序,ExcelTool需要在YearAdsorption之前执行

修改执行顺序可以参考我这篇文章:如何设置Unity脚本的执行顺序?

将两个脚本挂载Canvas上,拖入相应物体并运行 。

四、总结 

以上实现步骤具体内容可参考以下文章:

如何在 Unity 中创建带有缩放效果的滚动视图?(简单方法)

如何在Unity 中创建带有缩放效果的滚动视图(具有吸附效果的实现与优化)

http://www.lryc.cn/news/310354.html

相关文章:

  • Sqli-labs靶场第18关详解[Sqli-labs-less-18]自动化注入-SQLmap工具注入
  • 【测开求职】2023秋招快手一面面经
  • 【Go语言】Go语言中的字典
  • Matlab 机器人工具箱 创建机器人
  • 跨平台指南:在 Windows 和 Linux 上安装 OpenSSL 的完整流程
  • JAVA请求示例获取1688商品详情数据API接口item_get-获得阿里巴巴商品详情(按关键词搜索商品列表)
  • 安卓手机安装termux、kali linux及基本配置
  • Python 实现海康机器人工业相机 MV-CS050-10GC 的实时显示视频流及拍照功能(实时显示视频流同时可以进行拍照)
  • 武器大师——操作符详解(下)
  • 鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:Popup控制)
  • Python系列(20)—— 排序算法
  • MySQL中json类型的字段
  • 算法学习——GCD与欧拉函数
  • 40. 组合总和 II(力扣LeetCode)
  • Ubuntu上Jenkins自动化部署Gitee上SpringBoot项目
  • 延迟任务基于DeyalQueue
  • Linux 查询端口被占用命令
  • 【c++】string类---标准库中的string类
  • GO语言学习笔记(与Java的比较学习)(五)
  • Sora:探索大型视觉模型的前世今生、技术内核及未来趋势
  • 基于springboot实现图书馆管理系统项目【项目源码+论文说明】计算机毕业设计
  • MATLAB环境下基于高斯滤波器-广义拉普拉斯算子的细胞核自动检测
  • 【探索AI】十一 深度学习之第1周:深度学习概述与基础
  • 【简说八股】Spring事务失效可能是哪些原因?
  • 【语音识别】- CTC损失计算的原理
  • MySQL字符集和比较规则
  • 备忘录模式(Memento Pattern)
  • LeetCode 刷题 [C++] 第121题.买卖股票的最佳时机
  • ORACLE 基础
  • Adobe illustrator CEP插件调试