using UnityEngine; using System.Collections.Generic; [ExecuteAlways] // 允许在编辑器非运行状态下预览效果 public class HeatMapEmitter : MonoBehaviour { [Header("热源列表")] public List heatSources = new List(); // 拖入多个热源物体 [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(); 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); } } }