231 lines
6.6 KiB
C#
231 lines
6.6 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();
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
} |