using System; using AibisDream.Framework; using AibisDream.Kit; using AibisDream.Utility; using Febucci.UI; using TMPro; using UnityEngine; using UnityEngine.UI; namespace AibisDream { public class DialogBox : MonoBehaviour, IDialogView { #region box组件名称 private const string ActorName = "Actor Name"; private const string DialogText = "Dialog Text"; private const string NextArray = "Next Array"; private const string ChoiceBox = "Choice Box"; #endregion #region box组件 private TypewriterByCharacter _dialogText; private TextMeshProUGUI _actorName; private GameObject _nextArray; private GameObject _choiceBox; #endregion private TextParam _textParam; private bool _skipLineDelay; private Action _nextStep; [Header("跳过阻塞延迟时间/ms")] [SerializeField] private int delayTime = 300; [SerializeReference] private GameObject choiceButtonPrefab; private void Awake() { InitComponents(); AddSomeListener(); } private void AddSomeListener() { // 对话显示后有一段延时不可跳过 _dialogText.onTypewriterStart.AddListener(() => { _skipLineDelay = true; _ = CommonUtil.Delay(delayTime, () => { _skipLineDelay = false; }); }); } #region 初始化 private void InitComponents() { _actorName = transform.Find(ActorName)?.gameObject.GetComponentInChildren(); _dialogText = transform.Find(DialogText)?.gameObject.GetComponent(); _nextArray = transform.Find(NextArray)?.gameObject; _choiceBox = transform.Find(ChoiceBox)?.gameObject; } #endregion /// /// 隐藏对话盒 /// public void HideDialog() { gameObject.SetActive(false); } /// /// 显示对话 /// /// 对话内容 /// 角色内容 /// 下一步 /// 行号 /// 是否自动跳过,默认为false public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId, bool isAutoSkip = false) { gameObject.SetActive(true); // 把原有对话清掉 ClearBox(); _dialogText.gameObject.SetActive(true); _choiceBox?.SetActive(false); // 显示内容 ShowActorName(character); _dialogText.ShowText(dialogLine); // 自动跳过的回调很难独立Remove,只能全部清空再注册,下策 _dialogText.onTextShowed.RemoveAllListeners(); _dialogText.onTextShowed.AddListener(() => _nextArray.gameObject.SetActive(true)); _dialogText.onTextShowed.AddListener(() => EnumEventSystem.Global.Send(DialogEventEnum.LineShown)); _nextStep = nextStep; // 执行自动跳过结局 if (isAutoSkip) { _dialogText.onTextShowed.AddListener(() => _ = CommonUtil.Delay(200, NextStep)); } } public void NextStep() { if (_nextStep == null) return; EnumEventSystem.Global.Send(DialogEventEnum.LineEnd); var next = _nextStep; _nextStep = null; next.Invoke(); } public void OnLocalizationChanged(string value) { _textParam = JsonUtil.ReadBeanByText(value); var tmp = _dialogText.GetComponent(); // 修改对话文本 tmp.characterSpacing = _textParam.charSpace; _actorName.characterSpacing = _textParam.charSpace; } /// /// 展示选项 /// /// 对话选项 public void ShowOptions(DialogOption[] dialogueOptions) { gameObject.SetActive(true); // 没有选择框直接不显示选项 if (!_choiceBox) { return; } // 把原有对话清掉 ClearBox(); _choiceBox.SetActive(true); _dialogText.gameObject.SetActive(false); HideActorName(); // 销毁原来的按钮 foreach (Transform child in _choiceBox.transform) { Destroy(child.gameObject); } // 生成新按钮 foreach (var option in dialogueOptions) { if (!option.IsAvailable) continue; var choiceInstance = Instantiate(choiceButtonPrefab, _choiceBox.transform); var optionText = choiceInstance.GetComponentInChildren(); optionText.text = option.Line; optionText.characterSpacing = _textParam.charSpace; choiceInstance.GetComponent