Unity3D日常开发】(十三)Unity3D中实现热力图、风向图、温度图效果

网友投稿 1251 2022-05-30

推荐阅读

CSDN主页

GitHub开源地址

Unity3D插件分享

简书地址

我的个人博客

QQ群:1040082875

大家好,我是佛系工程师

☆恬静的小魔龙☆

,不定时更新Unity开发技巧,觉得有用记得一键三连哦。

一、前言

因一个任务要完成如何在Unity上面实现热力图的效果,所以百度了很久,发现资料很少,现在就把我总结的如何在Unity上面基于Canvas实现热力图效果的实现过程分享出来, 此前转载了一篇主要讲的是如何根据数据值,在Canvas上重新绘制RGBA的值,完成热力图的绘制,不过用的是H5写的,我修改了一下,用C#重写的

效果图:

项目源文件已经上传CSDN:

https://download.csdn.net/download/q764424567/13109963

二、参考资料

1.基于Canvas的热力图绘制方法【http://www.blueidea.com/tech/web/2010/7933.asp 】

2.Unity(OpenGL)实现“阴阳师画符”、划线功能【https://blog.csdn.net/yuanhandsome/article/details/78366250】

三、正文

实现过程:

1.首先从文档中解析数据,获取需要的数据(当然,这一步也可以在网上获取数据,然后再解析)

2.将获取的数据进行分析

3.保存贴图到Texture,将保存的贴图赋值给Image的Sprite(保存的贴图也可以赋值给物理对象的贴图)

4.清除数据

第一步、解析数据

就以下面这一组数据为例

第一行数据,代表是的模拟网格 160160

【Unity3d日常开发】(十三)Unity3D中实现热力图、风向图、温度图效果

第二行数据,模拟半径 -80km至80km范围;东西方向(x轴)区间范围,西→东

第三行数据,剂量值(z轴),即160160网格范围内的最小值和最大值

第6-164,表示各个网格点的浓度值

就是说有160*160个数据,可以用二维数组去接收数据

然后用一个List数组去接收解析完的数据

using System.Collections.Generic; using UnityEngine; using System.IO; using UnityEngine.UI; using UnityEngine.EventSystems; public class Draw : MonoBehaviour { //文件路径名 private string fileName; //读取数据 private string str; //保存数据 private List numberList = new List(); string tempData_Space; string[] tempData_Array; int[] tempData_IntArray; //保存解析完的数据 private int[,] m_Sum = new int[159, 159]; void Start() { ReadFile(); } //读指定目录下的文件 public void ReadFile() { //指定目录下的文件 fileName = "X:/2015_m01_d01_0000(utc+0800)_l00_csi_1hr_conc.grd"; StreamReader sr = File.OpenText(fileName); while (true) { //按行读取,str保存的是一行的数据 str = sr.ReadLine(); int lineLength = 0; if (str != null) { //得到获取到的这行数据的长度 lineLength = str.Length; //过滤掉前几行和后几行的数据 if (lineLength >= 1000) { //SPlit函数只能分割单个空格,所以两个空格替换成一个空格 tempData_Space = str.Replace(" ", " "); //分割字符串 tempData_Array = tempData_Space.Split(' '); //保存获取到的数据 tempData_IntArray = new int[tempData_Array.Length]; //取后两位数据 for (int i = 0; i < tempData_Array.Length; i++) { tempData_IntArray[i] = int.Parse(tempData_Array[i].Substring(8, 2)); } //添加到List数组中 for (int i = 0; i < tempData_IntArray.Length; i++) { numberList.Add(tempData_IntArray[i]); } } } if (str == null) { break; } } //将List数组中保存的数据赋值给二维数组 for (int x = 0; x < m_Width; x++) { for (int y = 0; y < m_Height; y++) { int i = y + x * m_Width; m_Sum[x, y] = numberList[i]; } } //关闭数据流 sr.Close(); }

第二步、分析数据

数据保存到m_Sum二维数组中,剩下的就是从二维数组中读取数据,然后进行分析

读取到的数据是最后两位的数据,然后将数据转成int类型进行对比

实现代码

//对比数据 public void DataCompare() { //因为二维数组的数量是159*159所以就在这个范围内读取 for (int i = 0; i < 159; i++) { for (int j = 0; j < 159; j++) { //数据对比 int temp = m_Sum[i, j]; if (temp <= 6) { Debug.Log("透明"); } else if (temp > 6 && temp <= 7) { Debug.Log("红色"); } else if (temp > 7 && temp <= 8) { Debug.Log("橘色"); } else if (temp > 8 && temp <= 9) { Debug.Log("黄色"); } else if (temp > 9 && temp <= 10) { Debug.Log("绿色"); } else if (temp > 10 && temp <= 11) { Debug.Log("蓝色"); } else if (temp > 11 && temp <= 12) { Debug.Log("靛蓝色"); } else if (temp > 12) { Debug.Log("紫色"); } } } }

第三步、保存贴图

最重要的一步,如何将分析过的数据生成贴图,并且赋值给Image呢

主要就是这两行的代码

//保存贴图变量 private Texture2D texture; private Image targetMaterial; //创建设置贴图文件 void CreatTexture() { texture = new Texture2D(m_Width, m_Height); int targetWidth = m_Width; int targetHeight = m_Height; for (int i = 0; i < targetWidth; i++) { for (int j = 0; j < targetHeight; j++) { int temp = m_Sum[i, j]; if (temp <= 6) { texture.SetPixel(i, j, m_ColorTransparency); } else if (temp > 6 && temp <= 7) { texture.SetPixel(i, j, m_ColorRed); } else if (temp > 7 && temp <= 8) { texture.SetPixel(i, j, m_ColorOrange); } else if (temp > 8 && temp <= 9) { texture.SetPixel(i, j, m_ColorYellow); } else if (temp > 9 && temp <= 10) { texture.SetPixel(i, j, m_ColorGreen); } else if (temp > 10 && temp <= 11) { texture.SetPixel(i, j, m_ColorBlue); } else if (temp > 11 && temp <= 12) { texture.SetPixel(i, j, m_ColorIndigo); } else if (temp > 12) { texture.SetPixel(i, j, m_ColorPurple); } } } //应用贴图 texture.Apply(); //将贴图数据赋值给Image的sprite targetMaterial.sprite = Sprite.Create(texture, new Rect(0, 0, m_Width, m_Height), Vector2.zero); ; }

第四步、清除数据

清除数组中的数据,供下次读取数据

//清理数组中的数据 public void ClearList() { numberList.Clear(); }

整体代码

using System.Collections.Generic; using UnityEngine; using System.IO; using UnityEngine.UI; using UnityEngine.EventSystems; public class Draw : MonoBehaviour { //颜色设置 public Color m_ColorTransparency; public Color m_ColorRed; public Color m_ColorOrange; public Color m_ColorYellow; public Color m_ColorGreen; public Color m_ColorBlue; public Color m_ColorIndigo; public Color m_ColorPurple; //保存贴图 private Texture2D texture; private Image targetMaterial; //文件路径名 private string fileName; //读取数据 private string str; //保存数据 private List numberList = new List(); string tempData_Space; string[] tempData_Array; int[] tempData_IntArray; //保存解析完的数据 private int[,] m_Sum = new int[159, 159]; //长宽设置 private int m_Width = 159; private int m_Height = 159; void Start() { targetMaterial = gameObject.GetComponent(); targetMaterial.color = Color.white; ReadFile(); CreatTexture(); ClearList(); } //清理数组中的数据 public void ClearList() { numberList.Clear(); } //读指定目录下的文件 public void ReadFile() { //指定目录下的文件 fileName = "X:/2015_m01_d01_0000(utc+0800)_l00_csi_1hr_conc.grd"; StreamReader sr = File.OpenText(fileName); while (true) { //按行读取,str保存的是一行的数据 str = sr.ReadLine(); int lineLength = 0; if (str != null) { //得到获取到的这行数据的长度 lineLength = str.Length; //过滤掉前几行和后几行的数据 if (lineLength >= 1000) { //SPlit函数只能分割单个空格,所以两个空格替换成一个空格 tempData_Space = str.Replace(" ", " "); //分割字符串 tempData_Array = tempData_Space.Split(' '); //保存获取到的数据 tempData_IntArray = new int[tempData_Array.Length]; //取后两位数据 for (int i = 0; i < tempData_Array.Length; i++) { tempData_IntArray[i] = int.Parse(tempData_Array[i].Substring(8, 2)); } //添加到List数组中 for (int i = 0; i < tempData_IntArray.Length; i++) { numberList.Add(tempData_IntArray[i]); } } } if (str == null) { break; } } //将List数组中保存的数据赋值给二维数组 for (int x = 0; x < m_Width; x++) { for (int y = 0; y < m_Height; y++) { int i = y + x * m_Width; m_Sum[x, y] = numberList[i]; } } //关闭数据流 sr.Close(); } //创建设置贴图文件 void CreatTexture() { texture = new Texture2D(m_Width, m_Height); int targetWidth = m_Width; int targetHeight = m_Height; for (int i = 0; i < targetWidth; i++) { for (int j = 0; j < targetHeight; j++) { int temp = m_Sum[i, j]; if (temp <= 6) { texture.SetPixel(i, j, m_ColorTransparency); } else if (temp > 6 && temp <= 7) { texture.SetPixel(i, j, m_ColorRed); } else if (temp > 7 && temp <= 8) { texture.SetPixel(i, j, m_ColorOrange); } else if (temp > 8 && temp <= 9) { texture.SetPixel(i, j, m_ColorYellow); } else if (temp > 9 && temp <= 10) { texture.SetPixel(i, j, m_ColorGreen); } else if (temp > 10 && temp <= 11) { texture.SetPixel(i, j, m_ColorBlue); } else if (temp > 11 && temp <= 12) { texture.SetPixel(i, j, m_ColorIndigo); } else if (temp > 12) { texture.SetPixel(i, j, m_ColorPurple); } } } //应用贴图 texture.Apply(); //将贴图数据赋值给Image的sprite targetMaterial.sprite = Sprite.Create(texture, new Rect(0, 0, m_Width, m_Height), Vector2.zero); ; } }

四、工程文件

链接:https://pan.baidu.com/s/1akdyDVrwHjQJm9RvD4Rh8w

提取码:y4be

Github地址:

https://github.com/764424567/Demo_DrawImg

Gitee地址(嫌弃Github地址下载太慢可以用码云):

https://gitee.com/itMonon/Demo_DrawImg

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:excel序列填充出错提示合并单元格需相同方法是什么
下一篇:20个 CSS 快速提升技巧
相关文章