using System; using System.Collections.Generic; using System.Linq; using AibisDream.Framework; using AibisDream.Kit; using UnityEngine; namespace AibisDream { public class BubbleGroup : Singleton, IDialogView { private BubbleOption[] _options; private Dictionary _bubbleDict; public DialogViewType CurDialogType { get; private set; } private BubbleFactory _bubbleFactory; private SimpleObjectPool _bubblePool; private SimpleObjectPool _optionPool; #region 一些索引 private Action _nextStep; private Bubble _curBubble; private IUnRegister _unRegister; #endregion #region 生命周期 public override void OnSingletonInit() { // 注册泡泡 _unRegister = EnumEventSystem.Global.Register(DialogEventEnum.OptionSelected, _ => HideOptions()); // 工厂 _bubbleFactory = new BubbleFactory(transform.Find("Bubbles")); // 加载选项 InitOptions(); } private void Start() { HideDialog(); } public override void OnSingletonDestroy() { _unRegister.UnRegister(); } public void LoadBubbles(BubbleSlotGroupData groupData) { CurDialogType = groupData.dialogViewType; // 回收旧泡泡 foreach (var oldBubble in _bubbleDict.Values.SelectMany(item => item)) { oldBubble.Dispose(); } // 加载新泡泡 _bubbleDict = groupData.bubbleSlots .Select(item => _bubbleFactory.Create(item)) .GroupBy(item => item.role) .ToDictionary(group => group.Key, group => group.ToArray()); // 更新选项的位置 if (groupData.bubbleOptionSlots is { Length: 0 }) { return; } foreach (var optionSlotData in groupData.bubbleOptionSlots) { if (optionSlotData.optionIdx >= _options.Length) continue; _options[optionSlotData.optionIdx].LoadData(optionSlotData); } } private void InitOptions() { _options = transform.Find("Options") .GetComponentsInChildren(true) .OrderBy(item => item.optionIdx) .ToArray(); _bubbleDict = new Dictionary(); } #endregion #region 对话框功能实现 public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, string lineId, bool isAutoSkip = false) { Debug.Log($"[BubbleGroup] ShowLine - 开始显示对话: {lineId}"); Debug.Log($"[BubbleGroup] ShowLine - nextStep是否为null: {nextStep == null}"); gameObject.SetActive(true); if (TryGetBubble(character.role, character.bubbleIdx, out var bubble)) { bubble.ShowActorName(character); bubble.ShowLine(dialogLine); // 将非选定的Bubble隐藏 HideDialog(bubble); } else { Debug.LogWarning($"{character.GetActorName()}的Role没有对应Bubble"); return; } // 保留信息 _nextStep = nextStep; _curBubble = bubble; Debug.Log($"[BubbleGroup] ShowLine - 设置完成,_nextStep是否为null: {_nextStep == null}"); } public void ShowOptions(DialogOption[] dialogueOptions) { HideDialog(); var availableOptions = dialogueOptions.Where(item => item.IsAvailable).ToArray(); // 如果仅由一个选项 if (availableOptions.Length == 1) { _options[0].ShowOption(availableOptions[0]); } else { for (var i = 0; i < availableOptions.Length; i++) { _options[i + 1].ShowOption(availableOptions[i]); } } } public void HideDialog() { foreach (var textBubble in _bubbleDict.Values.SelectMany(inner => inner)) { textBubble.Hide(); } HideOptions(); } public bool TrySkipLine(bool isForceSkip = false) { if (!_curBubble) { return true; } if (_curBubble && _curBubble.IsShowingText) { _curBubble.SkipLine(); return true; } return false; } public void NextStep() { Debug.Log($"[BubbleGroup] NextStep - _nextStep是否为null: {_nextStep == null}"); if (_nextStep == null) { Debug.Log("[BubbleGroup] NextStep - _nextStep为null,提前返回"); return; } Debug.Log("[BubbleGroup] NextStep - 发送LineEnd事件"); EnumEventSystem.Global.Send(DialogEventEnum.LineEnd); var next = _nextStep; _nextStep = null; _curBubble?.Hide(); _curBubble = null; Debug.Log("[BubbleGroup] NextStep - 调用回调"); next?.Invoke(); Debug.Log("[BubbleGroup] NextStep - 回调调用完成"); } public void OnLocalizationChanged(string value) { } #endregion private void HideDialog(Bubble activeBubble) { foreach (var textBubble in _bubbleDict.Values.SelectMany(inner => inner)) { if (activeBubble != textBubble) { textBubble.Hide(); } } HideOptions(); } private bool TryGetBubble(ActorRole role, int idx, out Bubble bubble) { if (_bubbleDict.TryGetValue(role, out var bubbles)) { bubble = bubbles.FirstOrDefault(item => item.idx == idx); return bubble != null; } bubble = null; return false; } private void HideOptions() { foreach (var option in _options) { option.Hide(); } } } }