90 lines
2.5 KiB
C#
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);
|
|
}
|
|
}
|
|
} |