EnergyEfficiencyManagement/Assets/Scripts/HeatMapEmitter.cs

90 lines
2.5 KiB
C#

using UnityEngine;
using System.Collections.Generic;
[ExecuteAlways] // 允许在编辑器非运行状态下预览效果
public class HeatMapEmitter : MonoBehaviour
{
[Header("热源列表")]
public List<Transform> heatSources = new List<Transform>(); // 拖入多个热源物体
[Header("热力设置")]
public float heatRadius = 5f;
public AnimationCurve heatFalloff = AnimationCurve.EaseInOut(0, 1, 1, 0);
[Header("颜色设置")]
public Color coldColor = new Color(0, 0, 0.5f, 1); // 深蓝
public Color hotColor = Color.red;
private MeshFilter meshFilter;
private Mesh mesh;
private Vector3[] baseVertices;
private Color[] vertexColors;
void OnEnable()
{
InitializeMesh();
}
[ContextMenu("Refresh Mesh Data")]
void InitializeMesh()
{
meshFilter = GetComponent<MeshFilter>();
if (meshFilter == null || meshFilter.sharedMesh == null) return;
// 注意:在编辑器模式下建议操作 sharedMesh
mesh = meshFilter.sharedMesh;
baseVertices = mesh.vertices;
vertexColors = new Color[baseVertices.Length];
// 初始化颜色
UpdateHeatMap();
}
void Update()
{
if (baseVertices == null || heatSources == null || heatSources.Count == 0) return;
UpdateHeatMap();
}
void UpdateHeatMap()
{
Matrix4x4 localToWorld = transform.localToWorldMatrix;
for (int i = 0; i < baseVertices.Length; i++)
{
Vector3 vertexWorldPos = localToWorld.MultiplyPoint3x4(baseVertices[i]);
float maxHeat = 0f;
// --- 核心逻辑:遍历所有热源,取影响最大的那个 ---
foreach (var source in heatSources)
{
if (source == null) continue;
float distance = Vector3.Distance(vertexWorldPos, source.position);
float t = Mathf.Clamp01(distance / heatRadius);
float currentHeat = heatFalloff.Evaluate(t);
// 取所有热源中对该点影响最大的热度
if (currentHeat > maxHeat)
{
maxHeat = currentHeat;
}
}
// 映射颜色
vertexColors[i] = Color.Lerp(coldColor, hotColor, maxHeat);
}
mesh.colors = vertexColors;
}
void OnDrawGizmosSelected()
{
// 选中物体时画出所有热源范围
Gizmos.color = new Color(1, 1, 0, 0.2f);
foreach (var source in heatSources)
{
if (source != null) Gizmos.DrawWireSphere(source.position, heatRadius);
}
}
}