using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
using System.Collections;
using AibisDream;
using AibisDream.FixSystem;
using AibisDream.Kit;
public class HeatMapController : MonoBehaviour
{
public Material heatMaterial; // 需要传递数据的材质
public Transform[] Pos;
public Button coolingButton;
private BodyModuleSystem bodyModuleSystem;
public GameObject heatmapGameobject;
public RectTransform imageToMove; // 需要移动的Image
public Transform imageToRotate; // 需要旋转的Image
public Vector3 inPos; // Heatmap进入位置
public Vector3 outPos; // Heatmap退出位置
private Vector3 imageInitialPos; // Image的初始位置
[HideInInspector] private Vector4[] points = new Vector4[7]; // 存储6个点的数组,(x, y, z) = center, w = temperature
[HideInInspector] private Vector4[] properties = new Vector4[7]; // 存储6个盒子大小的数组, (x,y) = boxsize
private float uftempture = 1;
private float backtemture = 1;
private float modulesTempture = 1;
private float tempture = 1;
private Tween _temptureTween;
/// 热力图面板当前是否在显示(用于 SetHeat 决定硬切还是平滑)。
public bool IsHeatMapVisible =>
heatmapGameobject != null && heatmapGameobject.activeInHierarchy;
public float Tempture
{
get => tempture;
set
{
if (tempture != value)
{
tempture = value;
SetDataToMaterial(); // 调用方法更新材质数据
}
}
}
public void ShowHeatMap()
{
StartCoroutine(ShowHeatMapCoroutine());
}
private IEnumerator ShowHeatMapCoroutine()
{
// 初始化Heatmap位置
heatmapGameobject.transform.localPosition = outPos;
heatmapGameobject.SetActive(true);
SetDataToMaterial();
heatmapGameobject.transform.DOLocalMove(inPos, 1f);
yield return new WaitForSeconds(1f); // 等待动画完成
heatmapGameobject.GetComponent().UnlockDrag();
coolingButton.interactable = false;
}
public void HideHeatMap()
{
var draggableUI = heatmapGameobject.GetComponent();
heatmapGameobject.transform.DOLocalMove(outPos, 1f).OnComplete(() => { draggableUI.UnlockDrag(); heatmapGameobject.SetActive(false);});
}
public void StartCooling()
{
coolingButton.interactable = false;
StartCoroutine(ReduceValueCoroutine());
}
IEnumerator ReduceValueCoroutine()
{
var draggableUI = heatmapGameobject.GetComponent();
draggableUI.LockDrag();
// 存储初始位置
imageInitialPos = imageToMove.localPosition;
// 移动和旋转动画
imageToMove.DOLocalMoveX(imageInitialPos.x + 3.5f, 1f);
var rotationTween = imageToRotate.DORotate(new Vector3(0, 0, 360), 0.2f, RotateMode.FastBeyond360)
.SetLoops(-1, LoopType.Restart)
.SetEase(Ease.Linear);
if (Tempture < 2)
{
Debug.Log("降温成功");
float duration = 3.5f;
SetTemptureSmooth(0.5f, duration);
AudioManager.Instance.PlaySfx("event:/FollowInput/cooler_cooling");
yield return new WaitForSeconds(duration);
rotationTween.Kill();
imageToRotate.localRotation = Quaternion.identity;
// 恢复初始状态
imageToMove.DOLocalMove(imageInitialPos, 1f);
yield return new WaitForSeconds(1.5f);
DialogController.Instance.StartDialogNode("降温成功");
bodyModuleSystem.OnCooling();
}
else
{
Debug.Log("降温失败");
yield return new WaitForSeconds(3f);
DialogController.Instance.StartDialogNode("降温失败");
}
// 停止旋转
rotationTween.Kill();
imageToRotate.localRotation = Quaternion.identity;
// 恢复初始状态
imageToMove.DOLocalMove(imageInitialPos, 1f);
}
void Start()
{
bodyModuleSystem = FindObjectOfType();
SetDataToMaterial();
}
void OnDestroy()
{
_temptureTween?.Kill();
}
///
/// 热点尺寸(世界单位):自身 Sprite/Image → 父级 Sprite → RectTransform。
/// UFheatmap 等空 Sprite 锚点会回退到父级 Module Pic,避免静默变成 (1,1) 导致热区偏小。
///
private static bool TryGetHotspotSize(Transform t, out Vector2 size)
{
size = default;
if (t == null) return false;
if (TryGetSpriteLocalSize(t, out size))
return true;
// 空 SpriteRenderer / 纯锚点:沿父链找有 sprite 的模块图
for (var p = t.parent; p != null; p = p.parent)
{
if (TryGetSpriteLocalSize(p, out size))
return true;
}
var image = t.GetComponent();
if (image != null && image.sprite != null)
{
var b = image.sprite.bounds.size;
size = new Vector2(b.x, b.y);
return true;
}
if (t is RectTransform rt)
{
size = new Vector2(rt.rect.width, rt.rect.height);
return size.x > 0f || size.y > 0f;
}
return false;
}
private static bool TryGetSpriteLocalSize(Transform t, out Vector2 size)
{
size = default;
var sr = t.GetComponent();
if (sr == null || sr.sprite == null)
return false;
var b = sr.sprite.bounds.size;
var ls = t.lossyScale;
size = new Vector2(b.x * Mathf.Abs(ls.x), b.y * Mathf.Abs(ls.y));
return size.x > 0.001f || size.y > 0.001f;
}
public void SetDataToMaterial()
{
// 逻辑温度 0~2 → shader 侧发热强度;各段端点连续,避免跨档跳变。
// t=0 冷态压低,接近「看不见」;t=1/2 保持原有发热观感。
if (tempture <= 1f)
{
float t = Mathf.Clamp01(tempture);
uftempture = Mathf.Lerp(0.85f, 2.8f, t);
modulesTempture = Mathf.Lerp(0.55f, 1.6f, t);
backtemture = Mathf.Lerp(0.7f, 2.25f, t);
}
else
{
float t = Mathf.Clamp01(tempture - 1f);
uftempture = Mathf.Lerp(2.8f, 3.2f, t);
modulesTempture = Mathf.Lerp(1.6f, 2.3f, t); // 原 1.8 起点与上一段不连续
backtemture = Mathf.Lerp(2.25f, 3.4f, t);
}
if (Pos == null || heatMaterial == null)
return;
for (int i = 0; i < 7; i++)
{
if (Pos[i] == null)
{
points[i] = Vector4.zero;
properties[i] = Vector4.zero;
continue;
}
Transform currentTransform = Pos[i].GetComponent();
if (i == 0)
{
points[i] = new Vector4(Pos[i].position.x, Pos[i].position.y, uftempture, 0);
}
else if (i == 6)
{
points[i] = new Vector4(Pos[i].position.x, Pos[i].position.y, backtemture, 0);
}
else
{
points[i] = new Vector4(Pos[i].position.x, Pos[i].position.y, modulesTempture,
0); // (x, y, z, temperature)
}
if (!TryGetHotspotSize(currentTransform, out var boxSize))
{
Debug.LogWarning($"[HeatMapController] Pos[{i}] '{Pos[i].name}' 无法取得热点尺寸,回退为 (1,1)。请检查 Sprite 或父级 Module Pic。", Pos[i]);
boxSize = Vector2.one;
}
properties[i] = new Vector4(boxSize.x, boxSize.y, 0.0f, 0.0f);
}
// 将数据传递给 Shader
heatMaterial.SetVectorArray("_Points", points);
heatMaterial.SetVectorArray("_Properties", properties);
}
public void SetTemptureDirect(float value)
{
_temptureTween?.Kill();
Tempture = value;
}
public void SetTemptureSmooth(float targetValue, float duration)
{
_temptureTween?.Kill();
_temptureTween = DOTween.To(() => tempture, x => Tempture = x, targetValue, duration)
.SetEase(Ease.InOutQuad)
.SetTarget(this);
}
}