暂停功能
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
title: Start
|
||||
title: Start
|
||||
---
|
||||
<<character_init Art/Character/Express_1>>
|
||||
me: 这是选项测试文件 #line:069537f
|
||||
@@ -21,36 +21,7 @@ peipei: 做一点测试
|
||||
<<declare $visitedState1 = false>>
|
||||
<<declare $visitedState2 = false>>
|
||||
|
||||
[command name=show_buttons /] #line:006eeaa
|
||||
<<jump OptionButton>>
|
||||
===
|
||||
|
||||
title: OptionButton
|
||||
position: -42,237
|
||||
---
|
||||
[options /] // 如果选项需要跳转回来重复选择,需要加这行,不然会出问题
|
||||
-> 按钮1 #line:0db0f08
|
||||
<<if !$visitedState1>>
|
||||
我: 按下了按钮1 #line:0d84460
|
||||
<<set $visitedState1 to true>>
|
||||
<<change_button_name Canvas 0 点击进入深度1>> // 这里可以添加其他功能,比如按钮打开
|
||||
<<else>>
|
||||
我: 已经按过按钮1了 #line:0f6f363
|
||||
<<endif>>
|
||||
<<jump OptionButton>>
|
||||
-> 按钮2 #line:0556913
|
||||
<<if !$visitedState2>>
|
||||
我: 按下了按钮2 #line:0b552f4
|
||||
<<set $visitedState2 to true>>
|
||||
<<change_button_name Canvas 1 点击进入深度2>> // 这里可以添加其他功能,比如按钮打开
|
||||
<<else>>
|
||||
我: 已经按过按钮2了 #line:09081bc
|
||||
<<endif>>
|
||||
<<jump OptionButton>>
|
||||
-> 点击进入深度1 #line:0b33abc // 在代码里判断选项是否可用
|
||||
我: 已进入深度1 #line:00ffa7f
|
||||
-> 点击进入深度2 #line:02d1695
|
||||
我: 已进入深度2 #line:072a4b9
|
||||
|
||||
我: 测试完成 #line:011c95f
|
||||
[pause name="show_buttons" /]
|
||||
我: 继续对话
|
||||
我: 结束
|
||||
===
|
||||
|
||||
@@ -9,10 +9,6 @@ namespace AibisDream
|
||||
// 进入指令选项模式
|
||||
private bool _waitCommandOptions;
|
||||
private string _commandName;
|
||||
|
||||
// 进入暂停后
|
||||
private bool _isInPause;
|
||||
private Action _pauseNextStep;
|
||||
|
||||
public override void RunLine(LocalizedLine dialogueLine, Action onDialogueLineFinished)
|
||||
{
|
||||
@@ -58,13 +54,17 @@ namespace AibisDream
|
||||
switch (commandLineType)
|
||||
{
|
||||
case CommandLineType.Pause:
|
||||
DialogController.Instance.PauseTalk(onDialogueLineFinished);
|
||||
// 获取选项名称
|
||||
dialogueLine.Text.TryGetPauseCommandAttr(out var pauseCommandName);
|
||||
// 传递暂停指令
|
||||
var step = YarnContinueStep.GeneContinueStep(onDialogueLineFinished);
|
||||
DialogController.Instance.InvokePauseCommand(pauseCommandName, step);
|
||||
break;
|
||||
case CommandLineType.OptionCommand:
|
||||
// 选项指令
|
||||
_waitCommandOptions = true;
|
||||
|
||||
dialogueLine.Text.TryGetCommandAttr(out var curCommandName);
|
||||
dialogueLine.Text.TryGetOptionCommandAttr(out var curCommandName);
|
||||
// 保存指令
|
||||
_commandName = curCommandName;
|
||||
// 进入下一步
|
||||
@@ -73,6 +73,7 @@ namespace AibisDream
|
||||
case CommandLineType.NonCommand:
|
||||
default:
|
||||
// 非Command直接跳过
|
||||
_waitCommandOptions = false;
|
||||
base.RunLine(dialogueLine, onDialogueLineFinished);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace AibisDream
|
||||
private VariableStorageBehaviour _variableStorage;
|
||||
|
||||
private readonly Dictionary<string, Action<YarnOption[]>> commandMap = new();
|
||||
private readonly Dictionary<string, Action<YarnContinueStep>> _pauseCommandMap = new();
|
||||
|
||||
# region controller状态标识
|
||||
|
||||
@@ -47,9 +48,8 @@ namespace AibisDream
|
||||
public bool quickRunMode;
|
||||
|
||||
// 暂停对话
|
||||
private bool _isInPause;
|
||||
private Action _pauseNextStep;
|
||||
|
||||
public bool isInPause;
|
||||
|
||||
# endregion
|
||||
|
||||
public static UnityAction OnDialogueStart;
|
||||
@@ -112,29 +112,7 @@ namespace AibisDream
|
||||
dialogueRunner.StartDialogue("Start");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 继续对话
|
||||
/// </summary>
|
||||
public bool TryContinueTalk()
|
||||
{
|
||||
// 如果对话系统在暂停状态
|
||||
if (_isInPause)
|
||||
{
|
||||
_pauseNextStep.Invoke();
|
||||
_isInPause = false;
|
||||
_pauseNextStep = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 如果对话系统不在暂停状态
|
||||
return false;
|
||||
}
|
||||
|
||||
public void PauseTalk(Action pauseNextStep)
|
||||
{
|
||||
_isInPause = true;
|
||||
_pauseNextStep = pauseNextStep;
|
||||
}
|
||||
#region 选项指令
|
||||
|
||||
/// <summary>
|
||||
/// 调用命令
|
||||
@@ -190,6 +168,67 @@ namespace AibisDream
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 暂停选项指令
|
||||
|
||||
/// <summary>
|
||||
/// 执行暂停命令
|
||||
/// </summary>
|
||||
/// <param name="commandName">命令名</param>
|
||||
/// <param name="pauseCommand">参数</param>
|
||||
public void InvokePauseCommand(string commandName, YarnContinueStep pauseCommand)
|
||||
{
|
||||
if (string.IsNullOrEmpty(commandName))
|
||||
{
|
||||
Debug.Log("命令名为空");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_pauseCommandMap.TryGetValue(commandName, out var action))
|
||||
{
|
||||
action(pauseCommand);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"命令 {commandName} 不存在");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册暂停命令
|
||||
/// </summary>
|
||||
/// <param name="commandName">命令名</param>
|
||||
/// <param name="commandAction">注册命令函数</param>
|
||||
public void RegisterPauseCommand(string commandName, Action<YarnContinueStep> commandAction)
|
||||
{
|
||||
if (_pauseCommandMap.ContainsKey(commandName))
|
||||
{
|
||||
Debug.Log($"命令 {commandName} 已经存在,将被替换");
|
||||
}
|
||||
|
||||
_pauseCommandMap[commandName] = commandAction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除命令
|
||||
/// </summary>
|
||||
/// <param name="commandName">命令名称</param>
|
||||
public void RemovePauseCommand(string commandName)
|
||||
{
|
||||
if (_pauseCommandMap.ContainsKey(commandName))
|
||||
{
|
||||
_pauseCommandMap.Remove(commandName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"命令 {commandName} 不存在");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 命令名
|
||||
|
||||
[YarnCommand("switch_tv")]
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Yarn.Unity;
|
||||
|
||||
@@ -69,5 +67,43 @@ namespace AibisDream
|
||||
return yarnOptions;
|
||||
}
|
||||
}
|
||||
|
||||
public class YarnContinueStep
|
||||
{
|
||||
private Action _nextStep;
|
||||
|
||||
public YarnContinueStep(Action nextStep)
|
||||
{
|
||||
_nextStep = nextStep;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 继续对话
|
||||
/// </summary>
|
||||
public void ContinueTalk()
|
||||
{
|
||||
if (_nextStep != null)
|
||||
{
|
||||
_nextStep.Invoke();
|
||||
DialogController.Instance.isInPause = false;
|
||||
_nextStep = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("对话已经继续,请勿重复触发");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成继续命令
|
||||
/// </summary>
|
||||
/// <param name="nextStep">下一句命令</param>
|
||||
/// <returns>命令</returns>
|
||||
public static YarnContinueStep GeneContinueStep(Action nextStep)
|
||||
{
|
||||
DialogController.Instance.isInPause = true;
|
||||
return new YarnContinueStep(nextStep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,72 +20,24 @@ namespace AibisDream.Test
|
||||
// 初始化时注册Command
|
||||
// 第一个参数为[command name=xxx]的参数
|
||||
// 第二个参数是注册的函数,在Yarn走到选择项时触发
|
||||
DialogController.Instance.RegisterOptionCommand("show_buttons", ShowButtons);
|
||||
DialogController.Instance.RegisterPauseCommand("show_buttons", ShowButtons);
|
||||
|
||||
// 不重要
|
||||
panel = transform.GetChild(0).gameObject;
|
||||
prefab = Resources.Load<GameObject>("Prefabs/UI/Choice Button");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册的命令
|
||||
/// </summary>
|
||||
/// <param name="options">触发时提供的选择项</param>
|
||||
public void ShowButtons(YarnOption[] options)
|
||||
public void ShowButtons(YarnContinueStep step)
|
||||
{
|
||||
// 将前两个选项生成清单
|
||||
buttonGroup = InstantiateButtons(options);
|
||||
|
||||
_options = options;
|
||||
}
|
||||
|
||||
private GameObject[] InstantiateButtons(YarnOption[] options)
|
||||
{
|
||||
// 这里默认是前两个选项生成按钮,你也可以利用Text或Index来判断哪些是需要生成按钮的选项
|
||||
GameObject[] res = new GameObject[2];
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
var option = options[i];
|
||||
var instance = Instantiate(prefab, panel.transform, true);
|
||||
var textMesh = instance.GetComponentInChildren<TextMeshProUGUI>();
|
||||
textMesh.text = option.Text;
|
||||
var option = step;
|
||||
var instance = Instantiate(prefab, panel.transform, true);
|
||||
var textMesh = instance.GetComponentInChildren<TextMeshProUGUI>();
|
||||
textMesh.text = "继续对话";
|
||||
|
||||
instance.GetComponent<Button>().onClick.AddListener(() => {
|
||||
// 执行SelectOption(), 对话就会从对应的选项往下继续执行
|
||||
option.SelectOption();
|
||||
});
|
||||
|
||||
res[i] = instance;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public void OnDestroy()
|
||||
{
|
||||
// 注意在合适的时机移除命令
|
||||
DialogController.Instance?.RemoveOptionCommand("show_buttons");
|
||||
}
|
||||
|
||||
[YarnCommand("change_button_name")]
|
||||
public void ChangeButtonName(float idx, string buttonName)
|
||||
{
|
||||
var realIdx = Mathf.RoundToInt(idx);
|
||||
GameObject targetButton = buttonGroup[realIdx];
|
||||
|
||||
var textMesh = targetButton.GetComponentInChildren<TextMeshProUGUI>();
|
||||
textMesh.text = buttonName;
|
||||
|
||||
var button = targetButton.GetComponentInChildren<Button>();
|
||||
button.onClick.RemoveAllListeners();
|
||||
button.onClick.AddListener(() =>
|
||||
{
|
||||
var option = _options[realIdx + 2];
|
||||
DialogController.Instance.TryGetVariable($"$visitedState{realIdx + 1}", out bool visitedState);
|
||||
if (visitedState)
|
||||
{
|
||||
option.SelectOption();
|
||||
}
|
||||
instance.GetComponent<Button>().onClick.AddListener(() => {
|
||||
// 执行SelectOption(), 对话就会从对应的选项往下继续执行
|
||||
option.ContinueTalk();
|
||||
instance.SetActive(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,12 +38,19 @@ namespace AibisDream.Utility
|
||||
return CommandLineType.NonCommand;
|
||||
}
|
||||
|
||||
public static bool TryGetCommandAttr(this MarkupParseResult text, out string commandName)
|
||||
public static bool TryGetOptionCommandAttr(this MarkupParseResult text, out string commandName)
|
||||
{
|
||||
bool res = text.TryGetAttributeWithName(CommandAttr, out var attribute);
|
||||
commandName = res ? attribute.Properties[CommandProp].StringValue : null;
|
||||
return res;
|
||||
}
|
||||
|
||||
public static bool TryGetPauseCommandAttr(this MarkupParseResult text, out string commandName)
|
||||
{
|
||||
bool res = text.TryGetAttributeWithName(PauseAttr, out var attribute);
|
||||
commandName = res ? attribute.Properties[CommandProp].StringValue : null;
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void AddCommandListener(this DialogueRunner runner, CommandHandler onCommand)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user