using System; using AibisDream.Framework; using AibisDream.Kit; using AibisDream.Utility; using Febucci.UI; using TMPro; using UnityEngine; using UnityEngine.UI; namespace AibisDream { public abstract class DialogBoxBase : 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组件 protected TypewriterByCharacter dialogText; protected TextMeshProUGUI actorName; protected GameObject nextArray; protected GameObject choiceBox; #endregion private bool _skipLineDelay; private Action _nextStep; [Header("跳过阻塞延迟时间/ms")] [SerializeField] private int delayTime = 300; protected GameObject choiceButtonPrefab; protected virtual void Awake() { LoadChoiceButton(); InitComponents(); AddSomeListener(); } private void AddSomeListener() { // 对话显示后有一段延时不可跳过 dialogText.onTypewriterStart.AddListener(() => { _skipLineDelay = true; _ = CommonUtil.Delay(delayTime, () => { _skipLineDelay = false; }); }); } #region 初始化 protected virtual void LoadChoiceButton() { Debug.Log("无选项对话框"); } private void InitComponents() { actorName = transform.Find(ActorName)?.gameObject.GetComponent(); 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 virtual void ShowLine(string dialogLine, CharacterVo character, Action nextStep, Action onTextShowed, bool isAutoSkip = false) { gameObject.SetActive(true); // // 没有dialogText说明不能显示对话,直接跳过 // if (!dialogText) // { // return; // } // 把原有对话清掉 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(() => onTextShowed?.Invoke()); dialogText.onTextShowed.AddListener(() => EnumEventSystem.Global.Send(DialogEventEnum.LineShowed)); _nextStep = nextStep; // 执行自动跳过结局 if (isAutoSkip) { dialogText.onTextShowed.AddListener(() => _ = CommonUtil.Delay(200, NextStep)); } } public virtual void NextStep() { if (_nextStep == null) return; EnumEventSystem.Global.Send(DialogEventEnum.LineEnd); var next = _nextStep; _nextStep = null; next.Invoke(); } /// /// 展示选项 /// /// 对话选项 public virtual void ShowOptions(DialogOption[] dialogueOptions) { gameObject.SetActive(true); // 没有选择框直接不显示选项 if (!choiceBox) { return; } // 把原有对话清掉 ClearBox(); choiceBox.SetActive(true); dialogText.gameObject.SetActive(false); // 销毁原来的按钮 foreach (Transform child in choiceBox.transform) { Destroy(child.gameObject); } // 生成新按钮 foreach (var option in dialogueOptions) { if (!option.IsAvailable) continue; var choiceInstance = Instantiate(choiceButtonPrefab, choiceBox.transform); choiceInstance.GetComponentInChildren().text = option.Line; choiceInstance.GetComponent