# 火山 Log 释放 Yarn 演出命令 `Stage6.yarn` 已改为使用原子命令编排。除特别标记为“等待”的命令外,命令只启动效果并立即让 Yarn 继续;并行效果之间的节奏用 `<>` 调整。 ## 火山脸与 LOG1 大字 | 命令 | 参数 | 行为 | |---|---|---| | `expression_face_fade_in` | `duration` | 显式淡入火山脸并等待完成。三条 LOG 都在完成节点中调用,不再由粒子系统自动淡入。 | | `expression_actor_flash` | `"text" holdDuration` | 清晰的大字重击;连续调用会逐级增强,但每次结束都退回晃动粒子字。 | | `expression_actor_flash_in` | 与 `expression_actor_flash` 相同 | 阻塞播放相同的大字重击入场,但保持最后一帧、不退场;用于段落结尾定格。 | | `expression_actor_slot` | `"characterPool" duration interval fontSize "truthPool"` | 中央大字持续换字。`truthPool` 非空时其字符也混入换字池,并在主字上以真话暖色(`truthAccentColor`)显示——真假字符交替闪烁即"争夺"。命令不等待,节奏由紧随其后的同长度 `wait` 控制;结束后停在最后一帧。 | | `expression_actor_truth_flash` | `"text" holdDuration fontSize alpha jitter` | 真话闪现(等待):谎话大字之间,暖色完整真话带细微抖动挣扎浮现一拍。不推进谎话冲击等级、不累积记忆损伤;"被掐断"由紧随其后的 `expression_glitch_pulse` 表现。 | | `expression_actor_word_hit` | `"text" holdDuration` | 单字或短词独占屏幕重击,并等待该拍完成。 | | `expression_actor_scroll` | `"phrase1|phrase2" scrollDuration loopDuration holdDuration` | 多列词组在火山脸范围内无缝向下滚动;移动结束后定格 `holdDuration`,再清理并继续 Yarn。 | LOG1 爆发段示例(对话推动:乱码台词 → 聚拢被打断 → 疯狂闪切 → glitch 翻转成真话): ```yarn hs: 我感觉■■■■■■ <> <> <> <> hs: ……我感觉自己■■■■ ... hs: 我感觉自己……像个■■ <> <> <> <> <> ... <> <> <> <> <> ``` ## 谎话形成 | 命令 | 参数 | 行为 | |---|---|---| | `expression_lie_prepare` | `freezeDuration noiseTarget` | 在指定时间内停止记忆推近/横移,并将记忆材质 `_SimGlitch` 降到目标值。进入谎话状态。 | | `expression_truth_squeeze` | `duration jitter alpha` | 将原始真话字符挤到屏幕边缘;`jitter` 控制边缘抖动幅度,`alpha` 控制字符亮度。 | | ~~`expression_lie_show`~~ | — | **已移除**(Yarn 命令注册已删,`ShowLieKeyword` 仅剩内部实现)。 | | `expression_lie_shuffle` | `"characterPool" duration interval` | 只在谎话关键词现有字符槽位里高速替换字符,不增加新字符。命令不等待。 | | ~~`expression_scanline`~~ | — | **已移除**(Yarn 命令注册已删)。 | 示例: ```yarn <> <> <> <> <> <> <> <> ``` ## 谎话开裂与泄漏 | 命令 | 参数 | 行为 | |---|---|---| | `expression_lie_crack_begin` | `lieAlpha` | 进入开裂状态并压暗谎话。 | | `expression_screen_dim` | `alpha riseDuration fallDuration` | 冷色屏幕暗脉冲;命令不等待。 | | `expression_memory_jolt` | `offset duration tear` | 记忆图水平错位后返回,`tear` 同时设置撕裂强度;命令不等待。 | | `expression_truth_leak` | `"characterPool" duration` | 兼容旧节点:在谎话字符槽位中进行跳字并等待完成,不再额外点亮真话片段。新节点优先使用 `expression_lie_shuffle`。 | | ~~`expression_system_message`~~ | — | **已移除**(Yarn 命令注册已删)。 | | ~~`expression_system_message_hide`~~ | — | **已移除**(Yarn 命令注册已删)。 | ## 记忆显影与轻微失真 `expression_memory_begin` 非阻塞启动记忆画面:SpriteRenderer 在对白继续执行的同时从 0 平滑淡入到 1,并按 `pushSpeed` 持续推近,基础层不再横移。记忆预设由图片自动选择(`office / sunset / private_office` 分别对应轻 / 中 / 重),Yarn 不再传预设名。**所有记忆相关失真都写在 `HuoshanMemory` 材质上**(`_SimGlitch` 常驻轻微 UV/色散,冲击走 `_Impact` / `_HorizontalTear` / `_Damage`),不再使用 `noise` 叠层。争夺真话/假话时,`expression_memory_jolt`、`expression_memory_tear`、`expression_actor_flash`、`expression_glitch_pulse` 都作用在同一张记忆材质上。 | 命令 | 参数 | 行为 | |---|---|---| | `expression_memory_sim` | `target duration` | 把模拟感调到目标值;命令不等待。用于演出中微调,进入记忆时无需调用。 | | `expression_memory_alpha` | `target duration` | 把当前记忆透明度推进到 `target`;命令不等待,适合放在对白之间逐段显影。 | ## LOG1 / LOG2 爆发段:写在聚合曲线里的挣扎 > **2026-07 改版。** 早先有一个 `expression_focus_interference` 命令,让真话的字逐个变成「帽问题/冇问题」并红色跳动,反馈是**出戏**——读起来是老虎机 / UI 故障,是机器在坏,不是火山在痛;`expression_face_error` 的红脸报错同样被判定为"很怪"。**该命令连同其实现已整体删除**(Yarn 注册、`ExpressionManager` / `LanguageParticleManager` 中的传播协程与私有辅助方法),不要再引用;`CandidateParticle` 上的 `focusInterference*` 字段被 focus 阶段与 LOG3 真话攻击共用,予以保留。 > > 现行方案:**失败感全部来自聚合进度曲线本身**。`BeginTruthGather` 原本是单条 `Ease.InOutSine`,平滑单调的曲线天然读作"顺利",所以挣扎只能靠外挂特效补。`expression_truth_strain` 改用带回抽的 Sequence,回抽幅度跨过 `UpdateTruthGatherLock` 的 0.08 解锁带,**字就会自己锁上又崩开、反复**;末拍 `expression_truth_collapse` 把进度一口气拽回 0。 > > **LOG1 / LOG2 全段不使用红色,也不使用脸部报错。** 红(`#FF304D` / `truthAttackColor`)只留给 LOG3 的愤怒攻击段,第一次出现才有力量。 | 命令 | 参数 | 行为 | |---|---|---| | `expression_truth_gather` | `target duration` | 真话聚合尝试(不等待):目标字被慢慢拉向最终位置、乱跳收敛,并按字序逐个锁定成真心话字符。`target<1` 时最后几个字永远差一点锁不住(锁字判定用原始进度,阈值 0.45~0.95 阶梯)。 | | `expression_truth_strain` | `target duration tugs` | **聚合挣扎(不等待)**:推进途中做 `tugs` 次"够到一点又被拽回去",每次比上次够得更远,最后一次刚好摸到 `target` 再被拽回,末尾单独一段推进停在 `target`。回抽幅度 0.10 起、逐次加深,保证越过解锁带让已锁的字崩开重新乱跳。`tugs` 取 0~4;`<=0` 时退化为 `expression_truth_gather`。 | | `expression_truth_collapse` | `duration` | **聚合崩塌(不等待)**:进度被一口气拽回 0,所有字沿原路退回悬浮位并恢复乱跳。用 `Ease.InBack`,会先向上顶一点点再垮掉——"又够了一下下,然后整个塌了"。与 `expression_truth_scatter` 的区别:scatter 是径向爆散,collapse 是被拽回去。 | | `expression_truth_scatter` | `burst` | 聚合被打断(不等待):目标字向外爆散(世界单位距离)并恢复乱跳、解除已锁定字符。谎话 flash 期间粒子隐藏,所以要放在 flash 命令之后,让字符"带着爆散重现"。 | | `expression_face_error` | `duration intensity` | 火山脸错误闪红(不等待):短暂替换为红屏 Sprite,随后恢复,并轻微下沉。**已被反馈判定为出戏,LOG1/LOG2 不再使用**,仅保留兼容。 | LOG1 / LOG2 现行三拍递进: ```yarn hs: ...我... <> // 第1拍:够到一次,被拽回一次 <> hs: ...我感觉自己... <> // 第2拍:抽搐加剧 <> hs: ...我就是个... <> // 第3拍:最接近,抖得最凶 <> <> // 崩回 0 <> hs: 我?*帽*问题?冇问题!... // 笑话覆盖,接住崩塌 ``` | `expression_truth_lie_flicker` | `"lie1\|lie2" "censored" duration interval fontSize` | 快速真假闪切(不等待,节奏由同长度 `wait` 控制):乱码块(暖色字+暖底色)与谎话(冷白字+冷底色)交替独占屏幕,越到后面切得越快,**结束定格在第一条谎话**。底色即"电视头背景",在 Inspector 的 `truthBackdropColor` / `lieBackdropColor` 调。 | | `expression_lie_morph_truth` | `"lie" "truth" duration` | 定格的谎话被 glitch 翻转成真话(等待):大字乱跳中长度从谎话渐变到真话、真假底色抢闪,最后落在暖色真话并轻微收缩定住。紧接 `expression_memory_cut` + `expression_truth_snap`,说出口的那一刻其余效果全部消失。 | | `expression_truth_blackout` | `duration alpha` | 顿挫黑一拍(等待):停掉闪切、隐藏大字并保持黑场。当前 LOG1 未使用,保留备用。 | 停顿时长直接写成 Yarn 的 `wait`,因此每段不再受预设黑盒限制: ```yarn <> <> <> <> <> <> ``` ## 假话到真话的强反转 | 命令 | 参数 | 行为 | |---|---|---| | `expression_truth_blackout` | `duration alpha` | 保持一次短促闪黑。此命令等待指定时长,遮罩由紧接着的暖闪/暗脉冲覆盖,或在演出清理时关闭。 | | `expression_lie_split` | `duration distanceRatio stretchX squashY` | 谎话产生冷暖双影,向左右分裂并横向拉伸、纵向压扁;命令不等待。 | | `expression_truth_flash` | `alpha riseDuration holdDuration fallDuration` | 暖色真话闪光;命令不等待。 | | `expression_memory_brightness_pulse` | `amount riseDuration fallDuration` | 只改变记忆图亮度,可用于反转或对白冲击;命令不等待。 | | `expression_memory_tear` | `peak duration` | 记忆撕裂从峰值回落;命令不等待。 | | `expression_glitch_pulse` | `peak riseDuration fallDuration` | 记忆材质瞬时失真脉冲(抬升 `_SimGlitch` 后回落);命令不等待。撕裂仍用 `expression_memory_tear`。 | | `expression_face_dip` | `duration ratio` | 火山脸向下抽动后回弹;`ratio` 是脸 Bounds 高度比例。 | | `expression_truth_release` | `alphaDuration` | 原始真话字符从屏幕边缘返回、转暖并恢复亮度,建立记忆材质 CalmField。 | | `expression_truth_resolve` | `duration peripheral calmRadius` | 在总时长内稳定全部真话字符;控制记忆外围失真和清晰区半径。此命令等待稳定完成。 | | `expression_memory_cut` | 无 | 同一帧隐藏两张记忆图,并清空记忆撕裂、失真与 CalmField。 | | `expression_truth_snap` | `peripheral calmRadius` | 隐藏谎话层,将所有目标字同一帧放到最终位置、改成真话并锁定。 | 典型反转: ```yarn <> <> <> <> <> <> <> <> <> ``` ## 屏幕 Glitch 命令非阻塞,不会延迟对白: | 命令 | 参数 | 行为 | |---|---|---| | `expression_screen_stress` | `amount duration` | **蓄压**:往底压罐里加 `amount`(建议 `0.08–0.2`),只升不降,一直保持。这是"积蓄的情绪"。有软上限 `screenStressCap`(默认 0.85),堆不满,顶格留给 pulse。 | | `expression_screen_pulse` | `strength decay` | **冲击**:瞬间顶到「底压 + `strength`」(建议 `0.3–0.8`),随后在 `decay` 内自动落回底压。一句狠话打一记。 | | `expression_screen_release` | `duration` | **泄压**:底压和脉冲一起放掉归零。屏幕淡出时会自动调用,正常不用手写。 | | `expression_screen_rage` | `level duration` | **转红**:荧光色从青绿推向愤怒红(`#FF304D`)。**武装期间每个 `expression_truth_attack` 会自动 punch 一下屏幕**,力度跟着该词的 `impact` 走——不要在 Yarn 里逐条手写 pulse,攻击列表一重调两边就脱节。`0` 收回。 | | `expression_screen_glitch` | `level duration` | **绝对档位**(旧命令,保留):清掉脉冲并把底压直接设成 `level`。只在"我就是要现在正好这个档位"时用。 | ### 屏幕 Glitch 的用法 情绪用**底压 + 冲击**两个量叠加,而不是每句手写一个绝对档位。手写绝对档位等于让编剧扮演积分器——既要记得上次是多少,又因为"开场想给一记狠的就必须把持续档位拉高"而在后面失去余量。 - **底压**(`stress`)只升不降,随剧情推进一口一口加。它是积蓄本身。 - **冲击**(`pulse`)瞬时叠在底压上再自动衰回去。开场底压才 0.1,一记 `0.6` 的 pulse 照样打得很响,打完落回安静。 **Stage6 的实际写法是"谎话一开口就坏,一路坏到释放"**——谎话段落里不写任何回落,每被逼问一次就再加一口,最后配合 timeline 顶满再泄: ```yarn <> // 谎话开口,屏幕开始坏 hs: 广告腔台词 <> // 说完不回落,再坏一档 me: 火山!说出来! <> // 被逼问,再坏 hs: 我…… <> <> // 真话往上聚,屏幕最撑不住的时候 <> <> // 配合 timeline 顶满 <> // 一口气释放 ``` LOG1 / LOG2 释放用 `火山Glitch/火山头痛2`;LOG3 落幕改用更短的 `火山Glitch/火山头痛3`(Addressable:`Timeline/火山头痛3`,约 0.75s),收尾更干脆。 三段 LOG 的**起手**一段比一段重(`0.25 / 0.32 / 0.38`),段内各自累加到 `0.6~0.85`。段与段之间屏幕会淡出并自动泄压,所以递进靠起手值而不是跨段累计——唯一的例外是 LOG3:`LOG疏通全部完成` 从淡入到落幕全程不淡出,LOG3 爆发段积的底压会一路烧进"为什么"高潮,那里再加一口正好顶到上限。 底压参考:`0.15–0.25` 底噪憋着;`0.45–0.6` 明显被顶开;`0.7+` 开始掉台。`pulse` 只在两种场合用:配合 timeline 的释放(短衰减),和攻击词的 punch(由 `expression_screen_rage` 自动代劳)。 **升级感靠新症状解锁,不靠"同样的东西更多"**——shader 内部把强度分成三段:`0.15+` 撕裂带与划痕、`0.35+` 场滚动、`0.55+` 掉台(塌成雪花再闪回)。所以底压每爬一格,观众看到的是"电视又多了一种坏法"。 ### Shader 结构与调参 `HuoshanScreenGlitch` 是一台坏掉的电视,遵守三条原则: 1. **屏幕是发光体,不是贴图。** 贴图的绿色固有色被抛弃——只取它的**亮度结构**,颜色由 `_PhosphorColor` 荧光色给出。哪怕 `_GlitchIntensity = 0`,屏幕也有荧光面、缓慢下移的刷新暗带、亮度微颤和待机扫描线,所以它平时就"通着电"而不是一张静态贴图。整体乘 `_Emissive` 抬过 1,超出部分交给场景 Bloom 发光。 2. **坏掉丢的是「画面」,不是屏幕。** 信号越差,画面内容越暗淡(只在随机某几拍挣扎着闪回一下),顶上来的是电子枪自己画的东西:灰蓝雪花、消隐黑条、回扫亮痕。所以高损坏时屏幕**不再是绿色**——他想说的话正在丢失。 3. **症状分段解锁**(见上文),而不是同一种坏法线性变多。 故障语汇全部来自真实电视:场同步失锁(整幅上滚 + 接缝黑条 + 条附近横向弯折)、行同步误差(逐行细抖 + 撕裂带,带内亮度错档、色相硬错)、色度不稳(YIQ 空间色相漂移 + 色度增益波动)、雪花、掉台。 > **踩过两次的坑**:偏色一旦改成从色轮 / HSV 取纯 R/G/B/C/M/Y,画面立刻变卡通。偏色只能来自"三个通道对不齐"(通道分离的彩色镶边)或 YIQ 上的连续漂移——这两种都是连续渐变,不会出现纯色块。 > > 曾经试过"纯黑屏 + 饱和彩条"的方向(贴图只提供激发量、黑电平以下归零),结论是**太卡通**,已回退。现行版本保留荧光着色 + 灰蓝雪花。 `_Rage` 由 `expression_screen_rage` 驱动,把荧光整块换成 `_RageColor`。 > **屏幕当前不转红。** `_RageColor` 已经设成和 `_PhosphorColor` 同一个青绿色,所以 LOG3 攻击段虽然仍然「武装」,屏幕颜色不变。 > > 之所以不是把 Yarn 里的 `expression_screen_rage` 删掉:`PunchScreenForAttack` 用 `screenRage > 0` 当武装开关、并且拿它缩放力度,删掉命令会让攻击段 25 记自动 punch 全部静默失效。要改回红屏只需把 `_RageColor` 调回 `#FF304D`,不用动 Yarn 和代码。 **观感的唯一真相源是材质 `M_HuoshanScreenGlitch`**(已默认挂在屏幕 SpriteRenderer 上),选中屏幕物件所见即所得地调。代码只驱动 `_GlitchIntensity` 档位,ExpressionManager 上不再有任何观感字段。 > 历史教训:曾经有过 40 个属性、且同时散落在材质和组件两边,结果**根本没法调**。加参数前先想清楚能不能从现有旋钮推导出来。 只有 6 个宏观旋钮,内部十几个系数全部由它们推导: | 旋钮 | 作用 | 默认 | |---|---|---| | `_Scale` | **效果尺度**。屏幕物件小、觉得"全是细线"就调大它,扫描线/雪花/撕裂带一起变粗 | 1.6 | | `_ColorDamage` | 色彩损伤:色相漂移 + 色度增益不稳 + 彩色镶边(色散)。嫌偏色过头就减 | 1.45 | | `_Warp` | 撕裂与滚屏的总位移量 | 1.25 | | `_Chaos` | **掉台频率**:信号中断爆发的概率(仅高档解锁) | 0.3 | | `_Grit` | 雪花与扫描线。嫌脏就减,调到 0 会失去"被拍下来"的质感 | 0.55 | > **雪花配平(2026-07)**:早先高档位时屏幕会糊成一片白噪点,压过了撕裂 / 滚屏 / 色散。原因是 shader 里 `loss`、`drop` 两项雪花**不受 `_Grit` 管**,旋钮拧到 0 也压不下去;同时 `loss` 会把画面几乎乘到全黑,坏法没有底子可以作用。 > > 现在三处都改了:雪花全部走 `_Grit`、`loss`/`drop` 的系数下调(0.30→0.16、0.9→0.55)、画面保留约三分之一底(`loss * 0.66`)。想再少一点白就减 `_Grit`,想多一点"绕、色散"就加 `_ColorDamage` 和 `_Warp`。 | `_SurgeRate` | 情绪节奏,越大越焦躁 | 0.5 | 外加基调: | 属性 | 作用 | 默认 | |---|---|---| | `_PhosphorColor` | **屏幕自身的荧光色**(替代贴图固有色) | 青绿白 | | `_RageColor` | 愤怒红,由 `_Rage` 混入 | `#FF304D` | | `_Emissive` | 发光增益,>1 的部分喂给 Bloom | 1.5 | | `_Ghost` / `_BloomBoost` / `_Vignette` | 鬼影 / 掉台恢复过冲 / 暗角 | 0.35 / 0.6 / 0.28 | 想换屏幕颜色直接改 `_PhosphorColor`,不用碰贴图——贴图只提供亮度结构。 > **`screenOverlayRenderer` 的材质绝不能置 null**——SpriteRenderer 的 material 为 null 会渲染成品红方块,表现为 `switch_fix_system_to Expression` 后闪一下粉色。需要换掉 Glitch 材质时走 `GetScreenFallbackMaterial()`(`Sprites/Default` 兜底)。 ### 记忆图上的减弱版 `HuoshanMemory.shader` 里加了一层同源的轻量模拟信号层,参数在 `M_HuoshanMemory` 上,同样只有三个:`_AnalogGlitch`(总量,默认 0.25)、`_AnalogScale`(尺度,默认 1.6)、`_AnalogChroma`(色偏)。 它只做色偏 + 扫描线 + 颗粒,**不改变画面结构**(色偏以 0 为中心,只染色不提亮),并且 Calm 区(要读字的地方)会自动让位。想让记忆图更脏就调 `_AnalogGlitch`,别去动 `_SimGlitch`——后者是记忆自己的全息模拟层。 ## 调节建议 - 谎话“不自然”的主要旋钮是 `expression_truth_squeeze` 的 `jitter` 以及谎话前后的 `wait`。 - LOG1/LOG2 的"纠结"强度主要调 `expression_truth_strain` 的 `tugs`(回抽次数)和 `target`;`target` 越接近 1,越多字会先锁上再崩开,挫败感越强。 - 反转力度优先调 `expression_truth_blackout` 的 `alpha`、`expression_lie_split` 的 `distanceRatio`、`expression_truth_flash` 的 `alpha` 和 `expression_glitch_pulse` 的 `peak`。 - `expression_memory_tear` 与 `expression_glitch_pulse` 可以同时触发:两者都作用在记忆材质上(撕裂 vs 模拟失真脉冲)。 - `expression_truth_resolve` 是等待命令。其 `duration` 决定 Yarn 何时继续到真话对白,并保证最后一个字符在这个总时长内稳定。 - 硬切节奏用 `start_timeline` 同帧启动 Timeline,然后连续调用 `expression_memory_cut` 与 `expression_truth_snap`;需要等 Timeline 播完时再调用 `wait_timeline`。 - Stage6 三段谎话到真话均使用硬切;Light/Medium/Heavy 的差异只保留在谎话持续期间的跳字、记忆扰动和 Glitch 强度,不再影响真话稳定速度。 - `expression_memory_brightness_pulse 0.18 0.08 0.18` 可直接放在某句对白前,用于精确同步亮度冲击。 - 所有 Alpha、峰值、外围失真和 Calm 半径都会限制在 `0–1`;时间会保证至少 `0.01s`,避免错误参数卡住 Yarn。 ## LOG1 可调参数 ```yarn <> <> <> <> <> ``` - `expression_memory_begin` 参数依次为记忆图、淡入时长、持续推进速度、旧水平速度、是否保留 Glitch(已忽略,记忆不再用 noise)、目标 Alpha。LOG1 使用 `2.2 / 0.012 / 0 / false / 1`,一次连续淡入,不再按对白阶梯式补透明度。 - 记忆段不要再用 `noise` / `glitch_transition`;瞬时故障用 `expression_glitch_pulse` 或 `expression_actor_flash` 的 glitch 峰值(写进记忆材质)。屏幕框故障另走 `expression_screen_glitch`。 - `expression_actor_truth_flash` 后续参数依次为停留、字号、透明度、抖动幅度。 - `expression_actor_flash` 后续参数依次为停留、字号、落定缩放、冲击缩放、色散距离、色散透明度、记忆冲击、Glitch 峰值。 - `expression_actor_word_hit` 最后两个数是字号和冲击缩放。 - `expression_actor_scroll` 最后一个数是字号。滚动固定为单列,并严格裁切在 `ExpressionScreenMaskRect` 内;新字幕按给定词组顺序从上方循环补入。