暂停功能

This commit is contained in:
2024-10-16 20:28:07 +08:00
parent e869e5e43f
commit 6b334ce47d
6 changed files with 132 additions and 126 deletions
@@ -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")]
+38 -2
View File
@@ -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);
}
}
}
+10 -58
View File
@@ -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);
});
}
}
+8 -1
View File
@@ -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)
{