Storyline+Dialog初步

This commit is contained in:
SoulliesOfficial
2026-07-05 16:08:23 -04:00
parent afa8a56e1d
commit d031afd075
464 changed files with 25716 additions and 4209 deletions

View File

@@ -0,0 +1,73 @@
using UnityEngine;
using Yarn.Unity;
namespace Ichni.Story.Dialogue
{
/// <summary>
/// 【临时 / 调试用】将 Yarn 对话行以"本地化后的文本"输出到 Console 的呈现器。
/// <para>用途:在没有 VN 对话 UI 的情况下,验证整条 Yarn 管线是否跑通,以及
/// Unity Localization 是否正确返回当前语言的文本(点击文本块即可在 Console 看到结果)。</para>
/// <para>阶段 3 接入 <c>VNDialoguePresenter</c> 后,可从 DialogueRunner 的呈现器列表移除本组件并删除此脚本。</para>
/// </summary>
public class ConsoleLinePresenter : DialoguePresenterBase
{
public override YarnTask OnDialogueStartedAsync()
{
Debug.Log("[ConsoleLinePresenter] === 对话开始 ===");
return YarnTask.CompletedTask;
}
/// <summary>
/// 输出本地化后的台词文本。
/// <para>注意:必须 async + YarnTask.Yield()。Yarn Spinner 3.x 的 RunLocalisedLine 在所有
/// presenter 均同步完成时会错误地调用 Dialogue.SignalContentComplete()(该方法仅对
/// command dispatch 合法),导致 InvalidOperationException。Yield 确保任务进入异步路径。</para>
/// </summary>
public override async YarnTask RunLineAsync(LocalizedLine line, LineCancellationToken token)
{
string speaker = string.IsNullOrEmpty(line.CharacterName) ? "(旁白)" : line.CharacterName;
string body = line.TextWithoutCharacterName.Text;
Debug.Log($"[ConsoleLinePresenter] {speaker}: {body}\n" +
$" (lineID={line.TextID}, rawText=\"{line.RawText}\")");
await YarnTask.Yield();
}
/// <summary>
/// 调试用:打印所有选项并自动选择第一个可用选项,以便管线可以跑完整个对话树。
/// </summary>
public override async YarnTask<DialogueOption?> RunOptionsAsync(
DialogueOption[] options,
LineCancellationToken token)
{
for (int i = 0; i < options.Length; i++)
{
string optText = options[i].Line.TextWithoutCharacterName.Text;
string tag = options[i].IsAvailable ? "" : " [不可用]";
Debug.Log($"[ConsoleLinePresenter] 选项 {i}{tag}: {optText}");
}
// 自动选择第一个可用选项
foreach (DialogueOption opt in options)
{
if (opt.IsAvailable)
{
Debug.Log($"[ConsoleLinePresenter] → 自动选择: {opt.Line.TextWithoutCharacterName.Text}");
await YarnTask.Yield();
return opt;
}
}
// 无可用选项时返回 null触发 DialogueRunner 的 fallthrough 逻辑)
await YarnTask.Yield();
return null;
}
public override YarnTask OnDialogueCompleteAsync()
{
Debug.Log("[ConsoleLinePresenter] === 对话结束 ===");
return YarnTask.CompletedTask;
}
}
}