对话框系统
对话框系统是引擎中所有模态UI的中心枢纽——从简单的文本框到全屏菜单,如背包、图鉴或宝可梦列表。它围绕 DialogManager 单例构建,使用基于队列的架构,包含打字机动画、本地化和分支选择。
DialogManager
位置: Assets/OpenMon/Core/Runtime/UI/Dialogs/DialogManager.cs
命名空间: OpenMon.MCE.UI.Dialogs
DialogManager 继承 Singleton<DialogManager> 并实现 IInputReceiver。它提供一个完全静态的API——所有公共方法都作为 DialogManager.ShowDialog(...)、DialogManager.ShowChoiceMenu(...) 等调用。
通过Zenject工厂实例化
DialogManager不会手动放置在场景中。它在运行时通过Zenject实例化:
// DialogManagerInstaller.cs
[CreateAssetMenu(menuName = "MCE/Dependency Injection/Dialog Manager Installer",
fileName = "DialogManagerInstaller")]
public class DialogManagerInstaller : ScriptableObjectInstaller
{
public DialogManager Prefab;
public override void InstallBindings() =>
Container.BindFactory<DialogManager, DialogManager.Factory>()
.FromComponentInNewPrefab(Prefab);
}
DialogManager.Factory 是一个 GameObjectFactory<DialogManager>,它创建预制件并让Zenject注入所有依赖项。
注入的依赖项
[Inject] private IInputManager inputManager;
[Inject] private ILocalizer localizer;
[Inject] private Roster playerRoster;
[Inject] private EvolutionManager evolutionManager;
[Inject] private MapSceneLauncher mapSceneLauncher;
基本文本对话框
显示简单对话框
// 即发即忘:显示文本并等待玩家输入
DialogManager.ShowDialog("Dialogs/Welcome");
// 带有角色说话者
DialogManager.ShowDialog("Dialogs/ProfGreeting", character: professorData);
// 带有文本修饰符(通过本地化的字符串插值)
DialogManager.ShowDialog("Dialogs/XPGain/Single",
localizableModifiers: false,
modifiers: new[] { monsterName, "500" });
显示并等待(协程)
对于顺序对话流,使用协程变体:
yield return DialogManager.ShowDialogAndWait("Dialogs/Moves/Learnt",
localizableModifiers: false,
modifiers: new[] { monsterName, moveName });
这将阻塞协程,直到玩家关闭对话框。
ShowDialog完整签名
public static void ShowDialog(
string localizationKey,
CharacterData character = null,
MonsterInstance monster = null,
bool acceptInput = true,
float typewriterSpeed = .01f,
float switchToNextAfterSeconds = -1, // -1 = 等待输入
bool localizableModifiers = true,
BasicDialogBackground background = BasicDialogBackground.Normal,
HorizontalAlignmentOptions horizontalAlignment = HorizontalAlignmentOptions.Left,
params string[] modifiers
);
参数说明
| 参数 | 用途 |
|---|---|
localizationKey | 本地化系统的键(例如 "Dialogs/Welcome") |
character | 如果设置,在说话者面板中显示角色名称 |
monster | 如果设置,在说话者面板中显示宝可梦名称/昵称 |
acceptInput | 玩家是否可以推进/关闭对话框 |
typewriterSpeed | 打字机动画每个字符的秒数 |
switchToNextAfterSeconds | N秒后自动推进(-1 = 手动) |
localizableModifiers | 如果为true,修饰符字符串作为本地化键处理;如果为false,作为字面文本使用 |
background | Normal 或 Sign(不同的视觉背景) |
modifiers | 替换到本地化字符串中 {0}、{1} 等的值 |
DialogText结构体
每个对话框内部表示为一个只读结构体 DialogText:
public readonly struct DialogText
{
public readonly string LocalizationKey;
public readonly string[] Modifiers;
public readonly bool LocalizableModifiers;
public readonly CharacterData Character;
public readonly MonsterInstance Monster;
public readonly float TypewriterSpeed;
public readonly float SwitchToNextAfterSeconds;
public readonly BasicDialogBackground Background;
public readonly HorizontalAlignmentOptions HorizontalAlignment;
}
ToString(ILocalizer) 方法解析本地化键并替换修饰符:
public string ToString(ILocalizer localizer)
{
string text = localizer[LocalizationKey];
for (int i = 0; i < Modifiers.Length; i++)
{
string modifier = Modifiers[i];
text = text.Replace("{" + i + "}", LocalizableModifiers ? localizer[modifier] : modifier);
}
return text;
}