ctx.dialogue 读取当前对话上下文,并控制对话框、快进和自动播放状态。
API
| 方法 | 返回值 | 说明 |
|---|
line() | DialogueLine | null | 获取当前可见对话行 |
choice() | ChoiceContext | null | 获取当前选项上下文 |
hideBox() | void | 隐藏对话框 |
showBox() | void | 显示对话框 |
getDefaultTextInterval() | number | null | 获取当前样式推荐的逐字间隔(ms) |
toggleSkipMode() | void | 切换快进状态 |
toggleAutoMode() | void | 切换自动播放状态 |
setSkipMode(enabled) | void | 明确设置快进状态,避免依赖当前状态翻转 |
setAutoMode(enabled) | void | 明确设置自动播放状态 |
useSpeakerPortrait() | { portrait: DialogueSpeakerPortrait | null; hidden: boolean } | React Hook;读取当前头像及隐藏状态 |
useSkipMode() | boolean | React Hook;订阅快进状态 |
useAutoMode() | boolean | React Hook;订阅自动播放状态 |
useLine() | DialogueLine | null | React Hook;订阅当前对话 |
useChoice() | ChoiceContext | null | React Hook;订阅当前选项 |
useStyle(fn) | () => void | 参与决定每句对话的样式;返回撤销函数 |
useTextAppearance(fn) | () => void | 修改每句正文 / 名字的渐变、纹理、描边与阴影;返回撤销函数 |
高级文字外观
useTextAppearance() 直接操作当前 Dialogue V2 的结构化文字外观,适合按角色、
章节或剧情状态切换渐变、图片纹理、外描边和多层阴影。回调拿到当前外观快照,
只需返回要覆盖的正文 text 或名字 name 字段。
static onRegister(ctx: ExtensionContext) {
const dispose = ctx.dialogue.useTextAppearance((line, current) => {
if (line.characterId !== "char_mayuri") return null;
return {
text: {
color: "#fff4fa", // 高级填充失败时仍可读
textFill: {
type: "linear-gradient",
angle: 20,
stops: [
{ color: "#fff8fc", position: 0 },
{ color: "#ff9fbd", position: 100 },
],
},
textStroke: { width: 1.5, color: "#351622", mode: "outer" },
textShadows: [
{ offsetX: 0, offsetY: 2, blur: 3, color: "#3a102280" },
],
},
// 不返回 name 时继续使用 current.name 的现有值。
};
});
}
图片纹理使用项目内素材 URI:
return {
text: {
color: "#ffffff",
textFill: {
type: "image",
asset: "textures/paper.webp",
scale: 120,
position: { x: 50, y: 50 },
repeat: "repeat",
},
},
};
textFill: null、textStroke: null 会清除对应效果。
textShadows: [] 会清除全部阴影。
- 多个回调按注册顺序组合,后注册的同名字段生效。
useTextAppearance() 在全部 useStyle() 之后执行,因此高级字段不会经过旧格式转换。
- 为避免高度自定义样式拖慢对白,运行时最多消费 16 个渐变色标和 8 层阴影;回调仍只在每句上屏前执行一次,不会逐字或逐帧执行。
此 API 从 SDK 2.0.0 提供。老扩展项目先在 Studio 中执行「同步 SDK」,并在
extension.json 声明 "sdkVersion": ">=2.0.0",避免安装到不支持该 API 的旧引擎。
参与对话样式
useStyle() 是兼容既有扩展的旧样式接口。它让扩展在每句对话上屏前修改样式,回调拿到这句话的信息和
当前样式配置,返回想改的部分即可 —— 返回值会跟原配置深合并,没提到的字段
保持原样;返回 null 或 undefined 表示不改。
static onRegister(ctx: ExtensionContext) {
const dispose = ctx.dialogue.useStyle((line, _style) => {
if (line.characterId !== "char_yuki") return null; // 别的角色不动
return { styles: { name_card: { text_styles: { color: "#8ecae6" } } } };
});
// 扩展卸载时调 dispose() 摘掉自己这一份
}
常用的样式路径:
| 路径 | 作用 |
|---|
styles.name_card.text_styles.color | 名字牌文字颜色 |
styles.dialogue.text_styles.color | 对话正文颜色 |
回调在每句对话上屏前同步执行,不要在里面做耗时操作 —— 会拖慢每一句话。
高级填充、外描边和多层阴影请使用 useTextAppearance(),不要把它们塞进旧式
useStyle() 的 Record<string, unknown> 对象。
几个要点:
- 多个扩展可以同时用,互不覆盖;改同一字段时后注册的赢。
- 单个回调抛错只跳过它自己,不会影响别的扩展或搞垮对话框。
- 它在写名字和正文之前执行,所以颜色和文字是同一帧出现的,不会闪。
案例:显示当前台词摘要
输入: 游戏正在显示角色 alice 的台词“今晚也能看到星星呢。”。
function DialogueSummary() {
const ctx = useExtensionContext();
const line = ctx.dialogue.useLine();
if (!line) return <span>当前没有对话</span>;
return <span>{line.characterId ?? "旁白"}:{line.text}</span>;
}
输出:
当对话框被隐藏、销毁或当前没有台词时,line() 与 useLine() 输出 null,组件会改为显示“当前没有对话”。
toggleSkipMode() 控制“是否正在快进”;ctx.config.get("skipMode") 控制“跳过全部内容还是只跳已读内容”。两者不是同一个状态。