Files
aibis-dream/Assets/Scripts/UI/DialogUI/DialogUiViewer.cs
T
2024-09-19 01:12:10 +08:00

187 lines
6.2 KiB
C#

using Febucci.UI;
using System;
using AibisDream.Kit;
using AibisDream.Utility;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Yarn.Unity;
namespace AibisDream
{
public class DialogUiViewer : Singleton<DialogUiViewer>
{
#region 组件名称
private const string DialogBox = "Dialog Box";
private const string ActorName = "Actor Name";
private const string DialogText = "Dialog Text";
private const string NextButton = "Next Button";
private const string ChoiceBox = "Choice Box";
private const string QuickTalk = "Quick Talk";
#endregion
#region 对话框UI
private GameObject dialogBox;
private TypewriterByCharacter dialogText;
private TextMeshProUGUI actorName;
private Button nextButton;
private GameObject choiceBox;
private GameObject choiceButtonPrefab;
private GameObject quickTalkButton;
#endregion
private bool _skipLineDelay;
public override void OnSingletonInit()
{
// 获取预制体
choiceButtonPrefab = Resources.Load<GameObject>("Prefabs/UI/Choice Button");
// 获取子物体
dialogBox = transform.Find(DialogBox).gameObject;
GetDialogComponentInBox(dialogBox);
}
private void OnEnable()
{
DialogController.OnDialogueComplete += HideDialog;
}
private void OnDisable()
{
DialogController.OnDialogueComplete -= HideDialog;
}
/// <summary>
/// 显示文字
/// </summary>
/// <param name="dialogLine">对话内容</param>
/// <param name="actor">名称</param>
/// <param name="nextStep">下一步</param>
public void ShowLine(string dialogLine, string actor, Action nextStep)
{
dialogBox.SetActive(true);
dialogText.ShowText("");
dialogText.gameObject.SetActive(true);
choiceBox.SetActive(false);
actorName.text = actor;
dialogText.ShowText(dialogLine);
// 显示完成后处理
dialogText.onTextShowed.RemoveAllListeners();
dialogText.onTextShowed.AddListener(() => nextButton.gameObject.SetActive(true));
nextButton.onClick.RemoveAllListeners();
}
/// <summary>
/// 显示文字,显示完成自动跳过
/// </summary>
/// <param name="dialogLine"></param>
/// <param name="actor"></param>
/// <param name="nextStep"></param>
public void ShowAutoLine(string dialogLine, string actor, Action nextStep)
{
dialogBox.SetActive(true);
dialogText.ShowText("");
dialogText.gameObject.SetActive(true);
choiceBox.SetActive(false);
actorName.text = actor;
nextButton.onClick.RemoveAllListeners();
dialogText.ShowText(dialogLine);
// 对话显示完成后自动跳过
dialogText.onTextShowed.RemoveAllListeners();
dialogText.onTextShowed.AddListener(() => CommonUtil.Delay(200, nextStep));
}
/// <summary>
/// 显示选项
/// </summary>
/// <param name="dialogueOptions">选项</param>
/// <param name="onOptionSelected"></param>
public void ShowOptions(DialogueOption[] dialogueOptions, Action<int> onOptionSelected)
{
dialogBox.SetActive(true);
choiceBox.SetActive(true);
dialogText.gameObject.SetActive(false);
dialogText.ShowText("");
actorName.text = "";
// 销毁原来的按钮
foreach (Transform child in choiceBox.transform)
{
Destroy(child.gameObject);
}
// 生成新按钮
foreach (DialogueOption option in dialogueOptions)
{
if (option.IsAvailable)
{
var choiceInstance = Instantiate(choiceButtonPrefab, Vector3.zero, Quaternion.identity);
choiceInstance.transform.SetParent(choiceBox.transform);
choiceInstance.GetComponentInChildren<TextMeshProUGUI>().text =
option.Line.TextWithoutCharacterName.Text;
choiceInstance.GetComponent<Button>().onClick
.AddListener(() => onOptionSelected.Invoke(option.DialogueOptionID));
}
}
}
public void HideDialog()
{
dialogBox?.SetActive(false);
}
public void SwitchQuickTalkMode()
{
DialogController.Instance.quickRunMode = !DialogController.Instance.quickRunMode;
quickTalkButton.GetComponent<Image>().color =
DialogController.Instance.quickRunMode ? Color.gray : Color.white;
}
public bool TrySkipLine()
{
// 开始后0.5秒不给跳过
if (_skipLineDelay) return true;
if (dialogText.isShowingText)
{
dialogText.SkipTypewriter();
return true;
}
else
{
return false;
}
}
public void AfterEndLine()
{
nextButton.gameObject.SetActive(false);
}
private void GetDialogComponentInBox(GameObject box)
{
actorName = box.transform.Find(ActorName).gameObject.GetComponent<TextMeshProUGUI>();
dialogText = box.transform.Find(DialogText).gameObject.GetComponent<TypewriterByCharacter>();
nextButton = box.transform.Find(NextButton).GetComponent<Button>();
choiceBox = box.transform.Find(ChoiceBox).gameObject;
quickTalkButton = box.transform.Find(QuickTalk).gameObject;
quickTalkButton.GetComponent<Button>().onClick.AddListener(SwitchQuickTalkMode);
dialogText.onTypewriterStart.AddListener(() =>
{
_skipLineDelay = true;
CommonUtil.Delay(300, () => { _skipLineDelay = false; });
});
}
}
}