写在前面
最近协作完成了一个地震波模拟的项目,其中涉及了许多从没接触过的知识点,在项目完成之际,做一篇经验汇总,总结一下学习到的东西。
项目内容有以下几点:
1.读取文件数据。(多个文件合成一个文件方便读取)
2.利用文件数据建立粒子系统。
3.根据数据改变粒子系统的位置并附带相应的颜色。
4.Button触发分段状态。
5.分段状态执行结束后回到原模型状态。
6.设置Slider动态调节粒子系统的偏移量的放大效果。
7.实时天气的获取。
8.根据实时获取到的天气更改场景特效。
9.DOTween实现UI的动画效果。
10.网页嵌入。
根据完成的难易程度,将会总结第一点,第二点,第三点,第七点,第九点的制作经验。
读文件数据
- 读取单独的文件
当文件数量有限时,可以直接读取文件(txt),在读取文件前,要将需要的文件放到Unity一个文件夹下,这个文件夹就作为读取文件时的路径。
Path.Combine(String,String);是一个将多个字符串组合成一个新路径的方法,官方介绍文档。
例如:var path = Path.Combine(Application.streamingAssetsPath, BuildingName);
表示的路径是streamingAssets文件夹下的BuildingName文件夹,还不是文件,即路径为streamingAssets/BuildingName。
Directory.GetFiles(String,String);是返回指定目录中与指定的搜索模式匹配的文件的名称。官方介绍文档。
例如:var files = Directory.GetFiles(path, "*.txt");
表示的是获取path这个目录下的txt文件,将文件存在files这个数组中。
在获取到文件后,就可以读文件了,这里新建了一个ReadFile的方法,并在里面添加如下内容:
File.ReadAllLines(String);打开一个文本文件,将文件的所有行读入一个字符串数组,然后关闭该文件。
例如:var lines = File.ReadAllLines(path);
表示的是打开path下的文件,将文件的每一行数据读到lines这个数组中。
在完成读取文件操作后,就可以根据自己所读文件得到数据的结构和类型设计存储结构,并通过遍历获取到每个数据点的具体数据。
建立并改变数据点(粒子系统)的位置以及颜色
由于本项目用于模拟地震波的状态,所以每个数据点都有很多个时间点的位置信息。在开始改变位置和颜色之前,已经准备好了存有初始帧时每个点数据的Point[]一维数组和存有不同帧数时每个点数据的Offets[][]二维数组。
建立初始粒子系统
首先在Unity的Hirerachy上右键选择新建一个ParticleSystem,然后打开脚本,新建一个BuildParticles的方法用于建立粒子系统。
1.进行粒子系统的一些初始设置,初始速度:startSpeed,生命周期:startLifetime。(生命周期尽可能地长)
2.将粒子数目设为Point[]数组的长度,即Point.Length,然后根据获取到的粒子数目建立粒子系统,即new ParticleSystem.Particle[粒子数目]。
3.在粒子系统创建完成后,还要设置粒子系统中粒子数目的最大值:maxParticles=粒子数目。
4.将粒子发射:Emit(粒子数目)。
5.获取当前存活的粒子数(不能缺少的一步):GetParticles(新建的粒子系统)。
6.遍历初始帧时存储每个点数据的Point[]数组,依次设置每个点的初始位置positon、初始颜色startColor以及初始粒子大小startSize。
7.将第六步获取的每个点都载入粒子系统:SetParticles(新建的粒子系统,粒子数目)。根据时间帧的粒子偏移信息改变粒子位置
在已经获取到偏移数据的情况下(即前面提到过的Offset[][]二维数组),只需在方法中将每一帧每一个点的位置改为原始位置加上偏移的位置信息即可:
点数.position=Point[点数]+Offsets[帧数][点数]-
根据时间帧的粒子偏移信息改变粒子的颜色
在操作之前,先找到一张要对应颜色的Image,并在这张图片的属性面板上勾选Read/Write Enabled,并且点击Apply。1.先获取到数据的偏移量(使用绝对值),然后将偏移量与图片的像素点匹配,从而不同点有不同的偏移量时可以显示出不同的颜色。
2.由于点的偏移量要与图片映射,所以要先算出偏移量的最大值,然后拿每个点当前的偏移量/最大值(乘以图片宽度-1)作为对应图片像素点的X坐标,Y坐标同理。
横坐标X:value * (heatMapImage.width - 1)
输出颜色:heatMapImage.GetPixel(横坐标, 纵坐标)
3.将每一帧每一个点的颜色改为输出颜色:startColor=输出颜色
获取实时天气
-
天气API
我选择的是百度地图的API,点进官方界面,选择服务文档,页面中会有操作提示。http://api.map.baidu.com/weather/v1/?district_id=222405&data_type=all&ak=你的ak //GET请求
-
获取信息
链接打开会是一段很长的Json字符串,可以通过Json在线解析网站对代码进行解析,可以看到解析出来就是想要的天气信息,接下来就要根据这些信息来写一个数据类用来接收这些数据。
1.编写数据类
通过解析出来的代码可以看出,数据是有层级关系的,在上面这张图中,最高的一层是最外面的括号,下一层是status,result,message,result下一层有location,now,forecsts,location的下一层就有country,province,city,name,id这些信息,在编辑数据类是也要根据这些层级关系来写。
举例Location部分public class CityData { public Result result; } public class Result { public Location location; } public class Location { public string country; public string province; public string city; public string name; public string id; }
注意:不需要的数据可以不写。
2.下载并导入json库,下载地址。找到下载路径(Download\litjson-develop\src\LitJson)下的LitJson文件夹,直接拖入Unity中。
3.在脚本中声明地区的天气查询地址,添加如下代码,运行后Log里会显示天气信息以及城市信息。IEnumerator RequestCityName() { using (UnityWebRequest request = UnityWebRequest.Get(url)) { yield return request.SendWebRequest(); yield return request; if (request.isNetworkError || request.isHttpError) { Debug.Log("NetWork Error"); } else { CityData cData = LitJson.JsonMapper.ToObject<CityData>(request.downloadHandler.text); Debug.Log(request.downloadHandler.text); Debug.Log(cData.result.location.city); } } }
UnityWebRequest.Get(string url);是用于从URL中检索数据的对象,使用这个方法前要在命名空间中添加using UnityEngine.Networking,官方介绍文档。
DownloadHandler,是用于管理和处理从远程服务器接收的 HTTP 响应主体数据。官方介绍文档。
DOTween实现动画效果
-
DOTween的下载导入
打开Unity的Asset Store,搜索DOTween,找到Free版本,下载后选择import导入当前项目。
1.创建队列:DOTween.Sequence()。
2.创建一个补间动画即要对对象实现的动画:Tweener xx=对象.DOMoveX(移动操作,持续时间),这里我是要对象X方向移动,所以选择了DOMoveX,如果是其他的坐标系方向,选择对应的DOMove方法即可。
3.在队列的最后添加一个tween即第二部创建的补间动画:创建的队列.Append(创建的补间动画)。
总结
这次的地震波项目虽然功能不是很复杂,但包含的知识非常多,暴露了我很多的盲区,C#的基础不好,导致在理解代码以及根据需求重新撰写代码时无从下手,在项目完成之后,我对项目内的很多方法知识的理解还是只停留在了表面,未来还有待我深入的学习。