Unity3D日常开发】(三十九)Unity3D中解析Txt文档,赋值给Text案例

网友投稿 560 2022-05-30

推荐阅读

CSDN主页

GitHub开源地址

Unity3D插件分享

简书地址

我的个人博客

QQ群:1040082875

一、前言

有小伙伴跟我说,公司现在需要解析JSON,但是百度的解析JSON的又各种各样,我都看懵了,有没有好一点的解析方案,然后我就将我这篇文章推送给了他【Unity3D日常】Unity写Json数据,以及在Unity读取、解析Json数据。

过了一晚上,又跟我说,不行啊,虽然只要解析JSON了,但是步骤还是不太理解,怎么保存值呀,怎么赋值呀,都不会。

我说,那你把文档发给我,把需求跟我说一下,我整理一篇文章,让小伙们下次遇到这个问题知道总体流程了。

二、需求分析

需求

要从文档中读取所有的地铁线路和每条线路的站点,然后可以点击不同的线路切换显示不同的站点。

流程步骤

数据文档→读取数据→解析数据→保存数据

【Unity3D日常开发】(三十九)Unity3D中解析Txt文档,赋值给Text案例

分析

(1)要有线路和站点的对应关系数据文档,这个已经有了:

(2)读取数据

读取数据没啥好说的,无论是json文件还是xml文件还是txt文件

使用File FileStream SteamReader StreamWriter 读取文件 都可以

每种写法都能百度出来

(3)解析数据

解析数据,方式也很多,以JSON为类,可以使用插件,也可以使用Unity自带的JSON解析类

插件:LitJSON解析、Newtonsoft.Json.dll

Unity自带解析JSON的类:JsonUtility

用那个都可以。

如果是txt数据,那么就要分析每一行的数据,如何切分,然后进行保存,比如:

1 1号线 103 苹果园 1 1号线 104 古城 1 1号线 105 八角游乐园 1 1号线 106 八宝山 1 1号线 107 玉泉路 1 1号线 108 五棵松 1 1号线 109 万寿路 1 1号线 110 公主坟 1 1号线 111 军事博物馆 1 1号线 112 木樨地 1 1号线 113 南礼士路

这段数据,最后是\r\n表示跳到下一行,中间以空格切分也就是\t

那么就可以先用\r\n切分每一行,然后用\t切换每一列,这样就将数据分析出来了。

(4)保存数据

最后一步,是保存,JSON解析完之后,需要保存到特定的跟JSON解析后匹配的类中,比如:

{ "name":"小明", "age":20, "interests":["sing","run"] }

那么,解析的类也要有这几个值,而且要一一对应,不能有错,包括字母大小写:

[System.Serializable] public class ModelTest { public string name; public int age; public string[] interests; }

那么,接收到的JSON数据怕生成类的时候出错怎么办,这时候就可以使用JSON数据转实体的功能:

https://www.json.cn/json/json2csharp.html

一键生成实体类,妈妈再也不用担心我出错了。

然后,用这个实体去接收解析好的JSON数据就可以了:

ModelTest obj = JsonUtility.FromJson(jsonTest);

jsonTest是JSON数据,ModelTest就是跟JSON数据匹配的实体。

那如果是txt一行一行读取的数据呢,比如:

1 1号线 103 苹果园 1 1号线 104 古城 1 1号线 105 八角游乐园 1 1号线 106 八宝山 1 1号线 107 玉泉路 1 1号线 108 五棵松 1 1号线 109 万寿路 1 1号线 110 公主坟 1 1号线 111 军事博物馆 1 1号线 112 木樨地 1 1号线 113 南礼士路

这个,就需要分析结构,然后使用数组或者List或者字典去保存了。

这个是一条地铁线,包含多个站点,每个站点有多个属性,可以使用自定义类,然后使用List去接收这个数据,比如:

using System.Collections; using System.Collections.Generic; using UnityEngine; public class ReadData : MonoBehaviour { List Stations; void Start() { } } public struct StationInfo { public int lineid; //线路编号 public string linename; //线路名称 public string stationid; //车站编号 public string stationname; //车站名称 }

三、实现

3-1 读取数据

using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; public class ReadData : MonoBehaviour { List Stations; string Content; void Start() { //读取数据 ReadFileData(); } void ReadFileData() { string pathstations = Application.streamingAssetsPath + "/Stations_2018.txt"; using (StreamReader SR = new StreamReader(pathstations)) { //将所有的数据从文件以流形式保存到 Content Content = SR.ReadToEnd(); SR.Close(); SR.Dispose(); } } } public struct StationInfo { public int lineid; //线路编号 public string linename; //线路名称 public string stationid; //车站编号 public string stationname; //车站名称 }

3-2 解析数据

//解析数据 List ParseStations() { if (!string.IsNullOrEmpty(Content)) { List info = new List(); string[] strarray = Content.Split(new char[] { '\r', '\n' }, System.StringSplitOptions.RemoveEmptyEntries); for (int i = 1; i < strarray.Length; i++) { string[] Columns = strarray[i].Split(new char[] { '\t' }, System.StringSplitOptions.RemoveEmptyEntries); StationInfo stationInfo = new StationInfo(); stationInfo.lineid = int.Parse(Columns[0]); stationInfo.linename = Columns[1]; stationInfo.stationid = Columns[2]; stationInfo.stationname = Columns[3]; info.Add(stationInfo); } return info; } return null; }

3-3 保存数据

//保存数据 Stations = ParseStations();//线路编号 线路名称 车站编号 车站名称

完整代码:

using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; public class ReadData : MonoBehaviour { List Stations; string Content; void Start() { //读取数据 ReadFileData(); } void ReadFileData() { string pathstations = Application.streamingAssetsPath + "/Stations_2018.txt"; using (StreamReader SR = new StreamReader(pathstations)) { //将所有的数据从文件以流形式保存到 Content Content = SR.ReadToEnd(); SR.Close(); SR.Dispose(); //保存数据 Stations = ParseStations();//线路编号 线路名称 车站编号 车站名称 } } //解析数据 List ParseStations() { if (!string.IsNullOrEmpty(Content)) { List info = new List(); string[] strarray = Content.Split(new char[] { '\r', '\n' }, System.StringSplitOptions.RemoveEmptyEntries); for (int i = 1; i < strarray.Length; i++) { string[] Columns = strarray[i].Split(new char[] { '\t' }, System.StringSplitOptions.RemoveEmptyEntries); StationInfo stationInfo = new StationInfo(); stationInfo.lineid = int.Parse(Columns[0]); stationInfo.linename = Columns[1]; stationInfo.stationid = Columns[2]; stationInfo.stationname = Columns[3]; info.Add(stationInfo); } return info; } return null; } } public struct StationInfo { public int lineid; //线路编号 public string linename; //线路名称 public string stationid; //车站编号 public string stationname; //车站名称 }

3-4 生成地铁线

先摆个UI:

将这两个按钮分别做成预制体,命名为MetroLinePar、MetroSitePar,放到Resources文件夹下面:

编写代码:

using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.UI; public class ReadData : MonoBehaviour { List Stations; string Content; public GameObject MetroLinePanel; private GameObject MetroLinePar; public GameObject MetroSitePanel; private GameObject MetroSitePar; void Start() { //读取数据 ReadFileData(); MetroLinePar = Resources.Load("MetroLinePar"); MetroLinePar = Resources.Load("MetroSitePar"); //生成UI CreateUI(); } void CreateUI() { //找出所有地铁线 Dictionary MetroLine = new Dictionary(); for (int i = 0; i < Stations.Count; i++) { if (!MetroLine.ContainsKey(Stations[i].lineid)) { MetroLine.Add(Stations[i].lineid, Stations[i].linename); } } //生成地铁线 foreach (var item in MetroLine) { GameObject MetroLineItem = Instantiate(MetroLinePar, Vector3.zero, Quaternion.identity, MetroLinePanel.transform); MetroLineItem.GetComponentInChildren().text = item.Value; } } void ReadFileData() { string pathstations = Application.streamingAssetsPath + "/Stations_2018.txt"; using (StreamReader SR = new StreamReader(pathstations)) { //将所有的数据从文件以流形式保存到 Content Content = SR.ReadToEnd(); SR.Close(); SR.Dispose(); //保存数据 Stations = ParseStations();//线路编号 线路名称 车站编号 车站名称 } } //解析数据 List ParseStations() { if (!string.IsNullOrEmpty(Content)) { List info = new List(); string[] strarray = Content.Split(new char[] { '\r', '\n' }, System.StringSplitOptions.RemoveEmptyEntries); for (int i = 1; i < strarray.Length; i++) { string[] Columns = strarray[i].Split(new char[] { '\t' }, System.StringSplitOptions.RemoveEmptyEntries); StationInfo stationInfo = new StationInfo(); stationInfo.lineid = int.Parse(Columns[0]); stationInfo.linename = Columns[1]; stationInfo.stationid = Columns[2]; stationInfo.stationname = Columns[3]; info.Add(stationInfo); } return info; } return null; } } public struct StationInfo { public int lineid; //线路编号 public string linename; //线路名称 public string stationid; //车站编号 public string stationname; //车站名称 }

运行:

所有的地铁线有,下面就需要将每条地铁线的每个站点对应起来。

3-5 生成站点

using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.UI; public class ReadData : MonoBehaviour { List Stations; string Content; public GameObject MetroLinePanel; private GameObject MetroLinePar; public GameObject MetroSitePanel; private GameObject MetroSitePar; void Start() { //读取数据 ReadFileData(); MetroLinePar = Resources.Load("MetroLinePar"); MetroSitePar = Resources.Load("MetroSitePar"); //生成UI CreateMetroLine(); } void CreateMetroLine() { //找出所有地铁线 Dictionary MetroLine = new Dictionary(); for (int i = 0; i < Stations.Count; i++) { if (!MetroLine.ContainsKey(Stations[i].lineid)) { MetroLine.Add(Stations[i].lineid, Stations[i].linename); } } //生成地铁线 foreach (var item in MetroLine) { GameObject MetroLineItem = Instantiate(MetroLinePar, Vector3.zero, Quaternion.identity, MetroLinePanel.transform); MetroLineItem.GetComponentInChildren().text = item.Value; //生成站点 MetroLineItem.GetComponent

上一篇:内幕:阿里老测试员告诉你,新人如何做好功能测试,学会这几项
下一篇:【Java基础】大厂都开始重视的基础很重要吗?快来加入基础的学习,巩固一下细枝末角,刷刷面试题吧
相关文章