using System;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
namespace DefaultNamespace.Component
{
///
/// 自动调整Image高度的组件
/// 监听子对象中的TMP_Text组件,根据文本高度自动调整Image的高度
///
public class AutoResizeImage : MonoBehaviour
{
[Header("UI组件引用")]
[SerializeField] private Image targetImage; // 目标Image组件
[SerializeField] private TMP_Text targetText; // 目标TMP_Text组件
[Header("高度调整设置")]
[SerializeField] private float topPadding = 10f; // 顶部边距
[SerializeField] private float bottomPadding = 10f; // 底部边距
[SerializeField] private float minHeight = 50f; // 最小高度
[SerializeField] private bool enableDebugLog = true; // 是否启用调试日志
[Header("更新设置")]
[SerializeField] private bool updateOnStart = true; // 启动时是否更新
[SerializeField] private bool updateOnTextChange = true; // 文本变化时是否更新
// 私有字段
private RectTransform imageRectTransform; // Image的RectTransform引用
private RectTransform textRectTransform; // Text的RectTransform引用
private float lastTextHeight = -1f; // 上次的文本高度,用于避免重复更新
///
/// 初始化组件
///
private void Awake()
{
InitializeComponents();
}
///
/// 组件启用时的处理
///
private void OnEnable()
{
RegisterTextEvents();
if (updateOnStart)
{
// 延迟一帧更新,确保所有组件都已初始化
Invoke(nameof(UpdateImageHeight), 0.1f);
}
}
///
/// 组件禁用时的处理
///
private void OnDisable()
{
UnregisterTextEvents();
}
///
/// 初始化组件引用
///
private void InitializeComponents()
{
try
{
// 获取Image组件
if (targetImage == null)
{
targetImage = GetComponent();
if (targetImage == null)
{
LogDebug("未找到Image组件,请手动指定或确保脚本挂载在Image对象上");
return;
}
}
imageRectTransform = targetImage.GetComponent();
if (imageRectTransform == null)
{
LogDebug("Image组件没有RectTransform,无法调整高度");
return;
}
// 获取TMP_Text组件
if (targetText == null)
{
targetText = GetComponentInChildren();
if (targetText == null)
{
LogDebug("未找到TMP_Text组件,请手动指定或确保子对象中有TMP_Text组件");
return;
}
}
textRectTransform = targetText.GetComponent();
if (textRectTransform == null)
{
LogDebug("TMP_Text组件没有RectTransform,无法获取高度");
return;
}
LogDebug("组件初始化完成");
}
catch (Exception ex)
{
LogDebug($"初始化组件时发生异常: {ex.Message}");
}
}
///
/// 注册文本变化事件
///
private void RegisterTextEvents()
{
try
{
if (targetText != null && updateOnTextChange)
{
// 监听文本变化事件
targetText.RegisterDirtyVerticesCallback(OnTextChanged);
LogDebug("文本变化事件已注册");
}
}
catch (Exception ex)
{
LogDebug($"注册文本事件时发生异常: {ex.Message}");
}
}
///
/// 取消注册文本变化事件
///
private void UnregisterTextEvents()
{
try
{
if (targetText != null)
{
targetText.UnregisterDirtyVerticesCallback(OnTextChanged);
LogDebug("文本变化事件已取消注册");
}
}
catch (Exception ex)
{
LogDebug($"取消注册文本事件时发生异常: {ex.Message}");
}
}
///
/// 文本变化时的回调
///
private void OnTextChanged()
{
if (updateOnTextChange)
{
UpdateImageHeight();
}
}
///
/// 更新Image高度
///
public void UpdateImageHeight()
{
try
{
if (imageRectTransform == null || textRectTransform == null)
{
LogDebug("RectTransform引用为空,无法更新高度");
return;
}
// 强制更新文本布局
Canvas.ForceUpdateCanvases();
// 获取文本的实际高度
float textHeight = GetTextHeight();
// 检查是否需要更新
if (Mathf.Abs(textHeight - lastTextHeight) < 0.1f)
{
LogDebug($"文本高度未变化 ({textHeight:F2}),跳过更新");
return;
}
// 计算新的Image高度
float newHeight = textHeight + topPadding + bottomPadding;
newHeight = Mathf.Max(newHeight, minHeight);
// 更新Image高度
Vector2 sizeDelta = imageRectTransform.sizeDelta;
sizeDelta.y = newHeight;
imageRectTransform.sizeDelta = sizeDelta;
lastTextHeight = textHeight;
LogDebug($"Image高度已更新: {newHeight:F2} (文本高度: {textHeight:F2}, 边距: {topPadding + bottomPadding:F2})");
}
catch (Exception ex)
{
LogDebug($"更新Image高度时发生异常: {ex.Message}");
}
}
///
/// 获取文本的实际高度
///
/// 文本高度
private float GetTextHeight()
{
try
{
if (targetText == null)
{
LogDebug("TMP_Text组件为空");
return 0f;
}
// 强制重新计算文本布局
targetText.ForceMeshUpdate();
// 获取文本的实际高度
float textHeight = targetText.preferredHeight;
LogDebug($"获取到文本高度: {textHeight:F2}");
return textHeight;
}
catch (Exception ex)
{
LogDebug($"获取文本高度时发生异常: {ex.Message}");
return 0f;
}
}
///
/// 记录调试日志
///
/// 日志消息
private void LogDebug(string message)
{
if (enableDebugLog)
{
Debug.Log($"[AutoResizeImage] {message}");
}
}
///
/// 手动设置目标组件(供外部调用)
///
/// 目标Image组件
/// 目标TMP_Text组件
public void SetTargetComponents(Image image, TMP_Text text)
{
targetImage = image;
targetText = text;
InitializeComponents();
LogDebug("目标组件已手动设置");
}
///
/// 设置边距参数
///
/// 顶部边距
/// 底部边距
public void SetPadding(float top, float bottom)
{
topPadding = top;
bottomPadding = bottom;
LogDebug($"边距已设置: 顶部={top}, 底部={bottom}");
}
///
/// 设置最小高度
///
/// 最小高度
public void SetMinHeight(float minHeight)
{
this.minHeight = minHeight;
LogDebug($"最小高度已设置: {minHeight}");
}
///
/// 启用或禁用调试日志
///
/// 是否启用
public void SetDebugLog(bool enable)
{
enableDebugLog = enable;
LogDebug($"调试日志已{(enable ? "启用" : "禁用")}");
}
}
}