6.4 KiB
6.4 KiB
Scene JSON 完整字段参考
顶层结构
{
"assetBase": "",
"locales": { "path": "locales/", "languages": ["zh", "en"] },
"startScene": "intro",
"variables": { "trust": 50, "courage": 0 },
"introVideo": "__intro__/logo.mp4",
"menuVideo": "__intro__/menu_bg.mp4",
"scenes": { ... },
"chapters": [ ... ],
"achievements": [ ... ],
"endings": [ ... ]
}
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
assetBase |
string | 否 | 所有资源路径前缀,默认 ""。设 "demo/" 后 videoUrl: "intro/video.mp4" 自动拼成 demo/intro/video.mp4。改 CDN 只需改这一行 |
locales |
object | 否 | 多语言配置。path 为 locale 文件目录(相对于 assetBase),languages 为支持的语言列表 |
startScene |
string | 是 | 开始场景的 ID |
variables |
object | 否 | 全局变量初始值 |
introVideo |
string | 否 | 开场视频路径 |
menuVideo |
string | 否 | 主菜单背景视频路径(自动循环播放) |
scenes |
object | 是 | 所有场景的集合,key 为场景 ID |
chapters |
array | 否 | 章节列表 |
achievements |
array | 否 | 成就列表 |
endings |
array | 否 | 结局列表 |
SceneNode
interface SceneNode {
id: string
type?: 'video' | 'image'
videoUrl: string
imageUrl?: string
contentSize?: { w: number; h: number }
subtitleUrl?: string
subtitles?: Record<string, string>
choices?: Choice[]
hotspots?: Hotspot[]
qte?: QTEDefinition
nextScene?: string
onEnter?: Effect[]
loopStart?: number
loopEnd?: number
bgmUrl?: string
bgmVolume?: number
bgmCrossFade?: number
bgmDuckLevel?: number
bgmDuckFade?: number
videoMuted?: boolean
skippable?: boolean
}
| 字段 | 类型 | 说明 |
|---|---|---|
id |
string | 场景唯一标识 |
type |
string | "video" (默认) 或 "image"。image 类型展示图片+热点,不播放视频 |
videoUrl |
string | 视频文件路径。image 场景可为空 |
imageUrl |
string | 图片场景的图片路径 |
contentSize |
object | 内容基准分辨率 { w: 1280, h: 720 },Hotspot 坐标基于此计算。用于 object-fit: contain 的偏移补偿 |
subtitleUrl |
string | 回退字幕路径。优先使用 subtitles |
subtitles |
object | 多语言字幕 { "zh": "...", "en": "..." }。语言切换时自动选择 |
choices |
Choice[] | 选项列表 |
hotspots |
Hotspot[] | 可点击热点区域 |
qte |
QTEDefinition | QTE 定义 |
nextScene |
string | 无选项时的默认跳转场景 |
onEnter |
Effect[] | 进入场景时触发的效果 |
loopStart |
number | 循环起始时间(秒) |
loopEnd |
number | 循环结束时间(秒)。视频播放到 loopEnd 时跳回 loopStart |
bgmUrl |
string | 背景音乐路径 |
bgmVolume |
number | 背景音乐音量(0-1),默认 0.8 |
bgmCrossFade |
number | 背景音乐交叉淡化时长(秒),默认 2.0 |
bgmDuckLevel |
number | BGM Duck 压低比例(0-1),默认 0.35 |
bgmDuckFade |
number | BGM Duck 过渡时长(秒),默认 0.5 |
videoMuted |
boolean | 视频静音(配合独立 BGM 使用) |
skippable |
boolean | false = 禁止跳过(用于 QTE 等关键场景) |
Choice
interface Choice {
text: string
textKey?: string
prompt?: string
promptKey?: string
targetScene: string
conditions?: Condition[]
effects?: Effect[]
timeLimit?: number
}
| 字段 | 说明 |
|---|---|
text |
选项文本(回退值) |
textKey |
i18n key,优先于 text。如 "intro.choice.left_door" |
prompt |
选择后浮现的提示文字(回退值) |
promptKey |
prompt 的 i18n key。如 "left_door.prompt.handshake" |
targetScene |
目标场景 ID |
conditions |
显示条件,不满足的选项隐藏 |
effects |
选择后触发的效果 |
timeLimit |
限时秒数,0=不限时 |
Hotspot
interface Hotspot {
id: string
label: string
labelKey?: string
targetScene: string
x: number
y: number
width: number
height: number
showAt?: number
hideAt?: number
conditions?: Condition[]
effects?: Effect[]
}
| 字段 | 说明 |
|---|---|
id |
热点唯一标识 |
label |
显示标签(回退值) |
labelKey |
i18n key |
x, y |
左上角坐标(像素,基于 contentSize) |
width, height |
尺寸(像素) |
showAt |
视频时间(秒),此时间后显示。不设则始终可见 |
hideAt |
视频时间(秒),此时间后隐藏 |
targetScene |
点击后跳转的场景 |
conditions |
显示条件 |
effects |
点击后触发的效果 |
QTEDefinition
interface QTEDefinition {
triggerTime: number
prompt: string
promptKey?: string
keys: string[]
timeLimit: number
successScene: string
failScene: string
effects?: {
success: Effect[]
fail: Effect[]
}
}
| 字段 | 说明 |
|---|---|
triggerTime |
触发时间(秒),视频播放到此时间弹出 QTE |
prompt |
提示文字(回退值) |
promptKey |
i18n key。如 "right_door.qte.dodge" |
keys |
有效按键列表,如 ["ArrowLeft", "ArrowRight", "a", "d"] |
timeLimit |
限时秒数 |
successScene |
成功跳转场景 |
failScene |
失败/超时跳转场景 |
effects |
成功/失败分别触发效果 |
其他类型
Condition
interface Condition {
variable: string
op: '>' | '<' | '>=' | '<=' | '==' | '!='
value: number | string | boolean
}
Effect
interface Effect {
type: 'set' | 'add'
target: string
value?: number | string | boolean
}
set— 设置变量值add— 变量增加/减少
ChapterInfo
interface ChapterInfo {
id: string
label: string
labelKey?: string
startScene: string
thumbnail?: string
defaultVariables?: Record<string, number>
}
AchievementDef
interface AchievementDef {
id: string
title: string
titleKey?: string
description: string
descKey?: string
icon?: string
hidden?: boolean
condition: Condition
}
EndingDef
interface EndingDef {
id: string
label: string
labelKey?: string
sceneId: string
chapterId?: string
thumbnail?: string
}
LocalesConfig
interface LocalesConfig {
path: string
languages: string[]
}