气泡组件和配置项
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
using Febucci.UI;
|
||||
using System;
|
||||
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;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
// 获取预制体
|
||||
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; });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user