using System; using System.Text.RegularExpressions; using AibisDream.Framework; using AibisDream.Kit; using AibisDream.Utility; using Febucci.UI.Core; using TMPro; using UnityEngine; using UnityEngine.UI; namespace AibisDream { public class Bubble : MonoBehaviour { private TypewriterCore _typewriter; private TMP_Text _actorName; private TMP_Text _lineText; private LayoutElement _layoutElement; private LayoutGroup _layoutGroup; private RectTransform _rect; private Image _bubbleImage; #region 参数 [SerializeField] public ActorRole role; [SerializeField] public int idx; [SerializeField] private int maxWidth; [SerializeField] private int minWidth; #endregion public event Action OnDisposed; public bool IsShowingText => _typewriter.isShowingText; public void LoadConfig(BubbleSlotData data) { InitRefs(); role = data.actorRole; idx = data.idx; maxWidth = data.maxWidth; minWidth = data.minWidth; var rect = transform as RectTransform; rect.localPosition = UIManager.GetDialogUIPos(data.slotPosition); // 设置style SetStyle(data.bubbleStyle, data.pivotType); } private void SetStyle(BubbleStyle bubbleStyle, PivotType pivotType) { _bubbleImage.color = bubbleStyle.imageColor; // padding内容 _layoutGroup.padding = bubbleStyle.BubblePadding; _lineText.margin = bubbleStyle.linePadding; _lineText.fontSize = bubbleStyle.lineFontSize; _actorName.margin = bubbleStyle.actorPadding; _actorName.fontSize = bubbleStyle.actorFontSize; // 是否展示名称 _actorName.gameObject.SetActive(bubbleStyle.hasActorName); // 锚点相关 _rect.pivot = CommonUtil.GetPivotByType(pivotType); var spritePath = bubbleStyle.bubbleSpriteAddress.EndsWith("]") ? $"{bubbleStyle.bubbleSpriteAddress}" : $"{bubbleStyle.bubbleSpriteAddress}[{pivotType.ToString()}]"; _bubbleImage.sprite = ResourceKit.LoadAssetSync(spritePath); } private void InitRefs() { _typewriter = GetComponentInChildren(); _actorName = transform.Find("名称").GetComponent(); _typewriter.onTextShowed.RemoveAllListeners(); _typewriter.onTextShowed.AddListener(() => EnumEventSystem.Global.Send(DialogEventEnum.LineShown)); // 获取内容文字 _lineText = _typewriter.GetComponent(); _layoutElement = _typewriter.GetComponent(); // 气泡自身 _layoutGroup = GetComponent(); _bubbleImage = GetComponent(); _rect = _bubbleImage.rectTransform; } public void ShowActorName(CharacterVo characterVo) { if (_actorName == null) return; _actorName.text = string.IsNullOrEmpty(characterVo.GetActorName()) ? string.Empty : characterVo.GetActorName(); } public void ShowLine(string line) { _typewriter.TextAnimator.SetText(""); gameObject.SetActive(true); HandleLayout(line); _typewriter.ShowText(line); } public void SkipLine() { if (_typewriter.isShowingText) { _typewriter.SkipTypewriter(); } } public void Hide() { gameObject.SetActive(false); } public void Dispose() { Hide(); OnDisposed?.Invoke(this); OnDisposed = null; } private void HandleLayout(string line) { // 先去除富文本标签 line = Regex.Replace(line.Replace("
", "\n"), "[<|{].*?[>|}]", string.Empty); var width = DialogCanvasManager.Instance.EstimateTextWidth(line, _lineText.fontSize); if (width > maxWidth) { _layoutElement.preferredWidth = maxWidth; } else { _layoutElement.preferredWidth = -1; } _layoutElement.minWidth = minWidth; LayoutRebuilder.ForceRebuildLayoutImmediate(_rect); } #if UNITY_EDITOR [Header("测试参数")] public int testMinWidth; public int testMaxWidth; public BubbleStyle testBubbleStyle; public PivotType testPivotType; public void LoadStyle() { InitRefs(); SetStyle(testBubbleStyle, testPivotType); _layoutElement.minWidth = testMinWidth; _layoutElement.preferredWidth = testMaxWidth; } public void SaveStyle() { if (!testBubbleStyle) return; InitRefs(); testBubbleStyle.linePadding = _lineText.margin; testBubbleStyle.lineFontSize = _lineText.fontSize; testBubbleStyle.actorPadding = _actorName.margin; testBubbleStyle.actorFontSize = _actorName.fontSize; testBubbleStyle.BubblePadding = _layoutGroup.padding; testBubbleStyle.hasActorName = _actorName.gameObject.activeSelf; } #endif } }