Files
aibis-dream/Assets/Scripts/UI/DialogUI/Bubbles/BubbleGroup.cs
T

230 lines
6.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using AibisDream.Framework;
using AibisDream.Kit;
using UnityEngine;
namespace AibisDream
{
public class BubbleGroup : Singleton<BubbleGroup>, IDialogView
{
private BubbleOption[] _options;
private Dictionary<ActorRole, Bubble[]> _bubbleDict;
public DialogViewType CurDialogType { get; private set; }
private BubbleFactory _bubbleFactory;
private SimpleObjectPool<Bubble> _bubblePool;
private SimpleObjectPool<BubbleOption> _optionPool;
#region 一些索引
private Action _nextStep;
private Bubble _curBubble;
private IUnRegister _unRegister;
#endregion
#region 生命周期
public override void OnSingletonInit()
{
// 注册泡泡
_unRegister =
EnumEventSystem.Global.Register<DialogEventEnum, DialogText>(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<BubbleOption>(true)
.OrderBy(item => item.optionIdx)
.ToArray();
_bubbleDict = new Dictionary<ActorRole, Bubble[]>();
}
#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();
// 如果仅由一个选项
if (dialogueOptions.Length == 1)
{
_options[0].ShowOption(dialogueOptions[0]);
}
else
{
for (var i = 0; i < dialogueOptions.Length; i++)
{
_options[i + 1].ShowOption(dialogueOptions[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();
}
}
}
}