【unity 实现温度图+热力图,显示形式--MeshRender或UGUI】

【unity 实现温度图+热力图,显示形式–MeshRenderer或UGUI】

前言:总结unity使用MeshRenderer或者RawImage实现温度图和热力图的效果,源码链接地址在文章结尾处,免费开放。对你有帮助的话,给博主点赞收藏加关注,感谢支持。。。。。。



前言

博主做之前搜索了好多网站,都没有详细教程和源码,东拼西凑,博主打算记录一下,为了方便自己学习,也为了和我一样的小伙伴。。。


一、温度图热力图原理

博主的理解:像素替换。温度值设置一个颜色范围,在某一个温度值范围内,当前像素替换成对应的温度值像素。
PS:在这里3D的面片使用的等比例计算,UI使用的1:1替换像素。

二、项目步骤

1.工程准备

unity创建工程,博主在这里就不多说了,博主用的版本是unity2021.3.23f1c1

2.maya创建一个面片,长宽高100×100×1

在这里插入图片描述

三.代码详细讲解(以UI案例详细讲解)

1. 热力图代码基类设置HeatMapBase

包含颜色、半径、热力图位置点、热力图图片分辨率、热力值。代码如下:

using System;
using System.Collections.Generic;
using UnityEngine;


[CreateAssetMenu(fileName = "Heat Map", menuName = "Templet/HeatMapBase", order = 1)]
public class HeatMapBase : ScriptableObject
{
    [Tooltip("半径")] public float DisRatio = 0.5f;
    [Tooltip("分辨率")] public float Resolution = 256;
    [Tooltip("热力图相关信息")] public List<HeatMapInfo> HeatMapInfos = new List<HeatMapInfo>();

    [Serializable]
    public sealed class HeatMapInfo
    {
        [Tooltip("热力值")] public float MaxAmount;
        [Tooltip("颜色")] public Color Color;
    }
}

颜色在Inspector里面自己设置。
在这里插入图片描述

2. 在画布中新建一个RawImage,用来更新热力图最终效果。在RawImage上添加要显示热力图的点dot,每个dot上挂载HeatMapData.cs脚本,脚本中包含热力点位置、热力值大小。如下图所示:

在这里插入图片描述

需要注意的是:1.画布大小保持跟热力图分辨率一样的大小,这样就不需要计算偏移差,3D里面有计算偏移差的方法如下图
在这里插入图片描述

2.rawiamge和热力点的锚点中心点设置位置,如下图

在这里插入图片描述
在这里插入图片描述
3.HeatMapData.cs代码,如下图

using UnityEngine;

public class HeatMapData : MonoBehaviour
{
    private Vector3 pos;
    [Range(0, 120)]
    public int Amount;

    public Vector3 Pos { get { return transform.position; } set { pos = value; } }
}

3. 画出热力图,直接上代码HeatMapDemo.cs,代码中含注释

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class HeatMapDemo : MonoBehaviour
{
    public HeatMapBase heatMapBase;
    public HeatMapData[] Targets;
    public RawImage raw;

    void Start()
    {
        HeatMapCreat(heatMapBase);
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            HeatMapCreat(heatMapBase);
        }
    }
    
    /// <summary>
    /// 创建热力图
    /// </summary>
    /// <param name="heatMapBase"></param>
    public void HeatMapCreat(HeatMapBase heatMapBase)
    {
        //----初始化热力点基础信息-----
        List<HeatMapInfo> heatMapInfos = new List<HeatMapInfo>();
        for (int i = 0; i < Targets.Length; i++)
        {
            Vector3 Pixel = Targets[i].Pos;
            HeatMapInfo heatMapInfo = new HeatMapInfo();
            heatMapInfo.Pixel = new Vector2(Pixel.x, Pixel.y);
            heatMapInfo.Amount = Targets[i].Amount;
            heatMapInfos.Add(heatMapInfo);
        }

        HeatMapBuild heatMapBuild = new HeatMapBuild( heatMapBase, heatMapInfos);
        raw.texture = heatMapBuild.GetHeatMapTexture();
    }
}

4. 热力图核心代码,直接上代码HeatMapBuild.cs,代码中含注释

using System.Collections.Generic;
using UnityEngine;

 public class HeatMapInfo
    {
        Vector2 pixel;
        int amount; //数量

        public Vector2 Pixel
        {
            get => pixel;
            set => pixel = value;
        }

        public int Amount
        {
            get => amount;
            set => amount = value;
        }
    }


    public class HeatMapBuild
    {
        Texture2D HeatMapTexture;

        //Vector3 modelSize = new Vector3(100, 1, 100);

        /// <summary>
        /// 构造HeatMapBuild
        /// </summary>
        /// <param name="heatMapBase">热力图模板</param>
        /// <param name="heatMapInfos">热力图数据</param>
        public HeatMapBuild(HeatMapBase heatMapBase, List<HeatMapInfo> heatMapInfos)
        {
            HeatMapTexture = new Texture2D((int)heatMapBase.Resolution, (int)heatMapBase.Resolution);
            CreatHeatMap(ref HeatMapTexture, heatMapInfos, heatMapBase, 1);
        }

        public Texture2D GetHeatMapTexture()
        {
            if (HeatMapTexture)
            {
                return HeatMapTexture;
            }
            else
            {
                return Texture2D.whiteTexture;
            }
        }

        /// <summary>
        /// 生成热力图texture
        /// </summary>
        /// <param name="texture">热力图底图</param>
        /// <param name="heatMapInfos">热力点数据</param>
        /// <param name="heatMapBase">热力图模板</param>
        /// <param name="MapRatio">底图缩放比率,等比例是1</param>
        void CreatHeatMap(ref Texture2D texture, List<HeatMapInfo> heatMapInfos, HeatMapBase heatMapBase,
            float MapRatio)
        {
            //------初始化每个像素
            List<Vector2> my_Pixels = new List<Vector2>();
            List<float> my_Values = new List<float>();
            for (int y = 0; y < texture.height; y++)
            {
                for (int x = 0; x < texture.width; x++)
                {
                    Vector2 pixel = new Vector2(x, y);
                    my_Pixels.Add(pixel);
                    my_Values.Add(0);
                }
            }

            int allLength = my_Pixels.Count; //所有像素点数量
            int pointLength = heatMapInfos.Count; //热力图兴趣点点数量
            int colorLength = heatMapBase.HeatMapInfos.Count; //色块等级

            float my_Distance = 0;
            float my_MaxDis = 0;
            float value = 0;


            for (int i = 0; i < pointLength; i++)
            {
                for (int a = 0; a < allLength; a++)
                {
                    my_Distance = Vector2.Distance(heatMapInfos[i].Pixel * MapRatio, my_Pixels[a]);
                    my_MaxDis = heatMapBase.DisRatio * heatMapInfos[i].Amount;
                    if (my_Distance < my_MaxDis)
                    {
                        value = (1 - Mathf.Pow(my_Distance, 2) / Mathf.Pow(my_MaxDis, 2)) * heatMapInfos[i].Amount;

                        if (value > my_Values[a])
                        {
                            my_Values[a] = value;
                        }
                    }
                }
            }

            float my_CurMaxAmount = 0;
            float my_UpDiffValue = 0;
            float offset = 0;
            Color my_UpColor;

            for (int i = 0; i < allLength; i++)
            {
                if (i <= heatMapBase.Resolution || i >= allLength - heatMapBase.Resolution ||
                    i % heatMapBase.Resolution == 0 || (i - 1) % heatMapBase.Resolution == 0)
                {
                    texture.SetPixel((int)my_Pixels[i].x, (int)my_Pixels[i].y, Color.clear);
                    continue;
                }

                for (int j = 0; j < colorLength; j++)
                {
                    my_CurMaxAmount = heatMapBase.HeatMapInfos[j].MaxAmount;

                    if (my_Values[i] >= my_CurMaxAmount)
                    {
                        Color my_CurColor = heatMapBase.HeatMapInfos[j].Color;

                        if (j != 0)
                        {
                            my_UpDiffValue = heatMapBase.HeatMapInfos[j - 1].MaxAmount - my_CurMaxAmount;
                            my_UpColor = heatMapBase.HeatMapInfos[j - 1].Color;

                           
                            offset = (my_Values[i] - my_CurMaxAmount) / my_UpDiffValue;
                            texture.SetPixel((int)my_Pixels[i].x, (int)my_Pixels[i].y,
                                Color.Lerp(my_CurColor, my_UpColor, offset));
                            
                            break;
                        }
                        else
                        {
                            texture.SetPixel((int)my_Pixels[i].x, (int)my_Pixels[i].y, my_CurColor);
                            break;
                        }
                    }
                }
            }

            texture.Apply();
        }
    }

四、项目运行结果以及源码链接

UI效果图:
在这里插入图片描述
MeshRenderer效果图:
在这里插入图片描述

源码链接:
网盘链接https://pan.baidu.com/s/1RNbe7MRfc3tEE81g8JH2WQ 提取码: s8ym

链接: https://pan.baidu.com/s/1RNbe7MRfc3tEE81g8JH2WQ 提取码: s8ym

PS:若想修改热力图,修改颜色和半径大小即可。有更好办法的网友欢迎随时交流,请留言给博主,博主看到会回复,谢谢。。。。。。

  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值