在Unity3D中实现热力图、风向图、温度图效果(Unity3D)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 因一个任务要完成如何在Unity上面实现热力图的效果,所以百度了很久,发现资料很少,现在就把我总结的如何在Unity上面基于Canvas实现热力图效果的实现过程分享出来, 此前转载了一篇主要讲的是如何根据数据值,在Canvas上重新绘制RGBA的值,完成热力图的绘制,不过用的是H5写的,我修改了一下,用C#重写的

一、前言

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

效果图:

网络异常,图片无法展示
|

项目源文件已经上传CSDN:download.csdn.net/download/q7…


二、参考资料

1.基于Canvas的热力图绘制方法【www.blueidea.com/tech/web/20… 】 2.Unity(OpenGL)实现“阴阳师画符”、划线功能【blog.csdn.net/yuanhandsom…


三、正文

实现过程:

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

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

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

第一步、解析数据

就以下面这一组数据为例

网络异常,图片无法展示
|

第一行数据,代表是的模拟网格 160160 第二行数据,模拟半径 -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<int> numberList = new List<int>();
    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<int> numberList = new List<int>();
    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<Image>();
        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); ;
    }
}
复制代码


四、工程文件

链接:pan.baidu.com/s/1akdyDVrw…提取码:y4be

Github地址:github.com/764424567/D…

Gitee地址(嫌弃Github地址下载太慢可以用码云):gitee.com/itMonon/Dem…



相关文章
|
3月前
|
C# 图形学 C语言
Unity3D学习笔记3——Unity Shader的初步使用
Unity3D学习笔记3——Unity Shader的初步使用
44 0
|
5月前
|
图形学
【unity小技巧】unity3d创建和实现破碎打破物品,万物可破碎
【unity小技巧】unity3d创建和实现破碎打破物品,万物可破碎
212 0
【unity小技巧】unity3d创建和实现破碎打破物品,万物可破碎
|
5月前
|
图形学
【unity小技巧】unity3D寻路指示轨迹预测
【unity小技巧】unity3D寻路指示轨迹预测
69 0
|
5月前
|
图形学
【unity小技巧】unity3d环境带雾的昼夜系统变化
【unity小技巧】unity3d环境带雾的昼夜系统变化
42 0
|
5月前
|
数据处理 图形学
【unity实战】unity3D中的PRG库存系统和换装系统(附项目源码)
【unity实战】unity3D中的PRG库存系统和换装系统(附项目源码)
48 0
|
5月前
|
开发工具 图形学 git
【实现100个unity特效之7】unity 3d实现各种粒子效果
【实现100个unity特效之7】unity 3d实现各种粒子效果
103 0
|
5月前
|
算法 图形学
【推荐100个unity插件之4】OpenFracture插件实现unity3d物体破裂和切割
【推荐100个unity插件之4】OpenFracture插件实现unity3d物体破裂和切割
68 0
|
5月前
|
API C# 图形学
【推荐100个unity插件之3】切割unity3d物体插件——Ezy-Slice的使用
【推荐100个unity插件之3】切割unity3d物体插件——Ezy-Slice的使用
166 0
|
6月前
|
JSON C# 图形学
【Unity 3D】利用C#、Unity和Socket实现简单的在线聊天室工具(附源码 简单易懂)
【Unity 3D】利用C#、Unity和Socket实现简单的在线聊天室工具(附源码 简单易懂)
147 0
|
6月前
|
图形学
【Unity3D开发小游戏】Unity3D零基础一步一步教你制作跑酷类游戏
【Unity3D开发小游戏】Unity3D零基础一步一步教你制作跑酷类游戏