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 ? "启用" : "禁用")}"); } } }