201 lines
6.0 KiB
C#
201 lines
6.0 KiB
C#
using System;
|
|
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, IBubble
|
|
{
|
|
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] private ActorRole role;
|
|
[SerializeField] private int idx;
|
|
[SerializeField] private int maxWidth;
|
|
[SerializeField] private int minWidth;
|
|
|
|
public ActorRole Role => role;
|
|
public int Idx => idx;
|
|
|
|
#endregion
|
|
|
|
public event Action<Bubble> OnDisposed;
|
|
public event Action OnLineShown;
|
|
|
|
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);
|
|
// 注册事件
|
|
_typewriter.onTextShowed.AddListener(InvokeLineShown);
|
|
}
|
|
|
|
private void InvokeLineShown()
|
|
{
|
|
OnLineShown?.Invoke();
|
|
OnLineShown = null;
|
|
}
|
|
|
|
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<Sprite>(spritePath);
|
|
}
|
|
|
|
private void InitRefs()
|
|
{
|
|
_typewriter = GetComponentInChildren<TypewriterCore>();
|
|
_actorName = transform.Find("名称").GetComponent<TMP_Text>();
|
|
_typewriter.onTextShowed.RemoveAllListeners();
|
|
_typewriter.onTextShowed.AddListener(() => EnumEventSystem.Global.Send(DialogEventEnum.LineShown));
|
|
// 获取内容文字
|
|
_lineText = _typewriter.GetComponent<TMP_Text>();
|
|
_layoutElement = _typewriter.GetComponent<LayoutElement>();
|
|
// 气泡自身
|
|
_layoutGroup = GetComponent<LayoutGroup>();
|
|
_bubbleImage = GetComponent<Image>();
|
|
_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 bool SkipLine()
|
|
{
|
|
if (_typewriter.isShowingText)
|
|
{
|
|
_typewriter.SkipTypewriter();
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void Hide()
|
|
{
|
|
gameObject.SetActive(false);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Hide();
|
|
_typewriter.onTextShowed.RemoveAllListeners();
|
|
OnDisposed?.Invoke(this);
|
|
OnDisposed = null;
|
|
}
|
|
|
|
private void HandleLayout(string line)
|
|
{
|
|
// 先去除富文本标签
|
|
var width = BubbleGroup.Instance.EstimateTextWidth(line.RemoveRichTextTags(), _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
|
|
}
|
|
|
|
public interface IBubble
|
|
{
|
|
public ActorRole Role { get; }
|
|
public int Idx { get; }
|
|
|
|
public event Action OnLineShown;
|
|
public void ShowActorName(CharacterVo characterVo);
|
|
public void ShowLine(string line);
|
|
public bool SkipLine();
|
|
public void Hide();
|
|
}
|
|
} |