Files
aibis-dream/Docs/HuoShan/LogReleaseYarnCommands.md
2026-07-28 21:34:42 +08:00

24 KiB
Raw Permalink Blame History

火山 Log 释放 Yarn 演出命令

Stage6.yarn 已改为使用原子命令编排。除特别标记为“等待”的命令外,命令只启动效果并立即让 Yarn 继续;并行效果之间的节奏用 <<wait 秒数>> 调整。

火山脸与 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`

LOG1 爆发段示例(对话推动:乱码台词 → 聚拢被打断 → 疯狂闪切 → glitch 翻转成真话):

hs: 我感觉<shake a=0.45><color=\#2B2B2B>■■■■■■</color></shake>
<<expression_truth_gather 0.55 1.1>>
<<wait 1.05>>
<<expression_actor_flash "没问题" 0.35 10.5 1.1 1.45 0.008 0.06 0.50 0>>
<<expression_truth_scatter 0.9>>
hs: ……我感觉自己<shake a=0.5><color=\#2B2B2B>■■■■</color></shake>
...
hs: 我感觉自己……像个<shake a=0.6><color=\#2B2B2B>■■</color></shake>
<<expression_truth_gather 0.92 1.6>>
<<wait 1.5>>
<<expression_face_error 0.55 0.9>>
<<expression_actor_flash "帽问题" 0.5 12.0 1.1 2.20 0.010 0.08 1.00 0>>
<<expression_truth_scatter 1.1>>
...
<<expression_truth_lie_flicker "没问题|冇问题|帽问题" "■■■■■■" 3.2 0.26 12>>
<<wait 3.2>>
<<expression_lie_morph_truth "没问题" "我就是个笑话" 0.9>>
<<expression_memory_cut>>
<<expression_truth_snap 0 0.42>>

谎话形成

命令 参数 行为
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 命令注册已删)。

示例:

<<expression_lie_prepare 0.25 0.005>>
<<expression_truth_squeeze 0.22 0.071 0.28>>
<<expression_lie_show "没问题" 0.22 14>>
<<expression_scanline 0.32 false>>
<<wait 0.25>>
<<expression_lie_shuffle "我就是个笑话" 0.55 0.045>>
<<expression_memory_jolt 0.025 0.22 0.045>>
<<expression_glitch_pulse 0.12 0.05 0.20>>

谎话开裂与泄漏

命令 参数 行为
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_joltexpression_memory_tearexpression_actor_flashexpression_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 现行三拍递进:

hs: ...我...
<<expression_truth_strain 0.45 3 1>>      // 第1拍:够到一次,被拽回一次
<<wait 2>>
hs: ...我感觉自己...
<<expression_truth_strain 0.65 2.6 2>>    // 第2拍:抽搐加剧
<<wait 2>>
hs: ...我就是个...
<<expression_truth_strain 0.86 3.2 3>>    // 第3拍:最接近,抖得最凶
<<wait 2>>
<<expression_truth_collapse 0.45>>        // 崩回 0
<<wait 0.6>>
hs: <rainb>我?*帽*问题?冇问题!...</rainb>   // 笑话覆盖,接住崩塌

| 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,因此每段不再受预设黑盒限制:

<<wait 0.55>>
<<expression_lie_crack_begin 0.48>>
<<expression_scanline 0.22 true>>
<<expression_screen_dim 0.28 0.06 0.12>>
<<expression_memory_jolt 0.08 0.24 0.11>>
<<expression_truth_leak "离开" 0.24>>

假话到真话的强反转

命令 参数 行为
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 隐藏谎话层,将所有目标字同一帧放到最终位置、改成真话并锁定。

典型反转:

<<expression_truth_blackout 0.055 0.42>>
<<expression_lie_split 0.35 0.18 1.85 0.42>>
<<expression_truth_flash 0.62 0.045 0.025 0.16>>
<<expression_memory_brightness_pulse 0.16 0.06 0.20>>
<<expression_memory_tear 0.50 0.35>>
<<expression_glitch_pulse 0.50 0.12 0.35>>
<<expression_face_dip 0.35 0.015>>
<<expression_truth_release 0.08>>
<<expression_truth_resolve 0.90 0.30 0.42>>

屏幕 Glitch

命令非阻塞,不会延迟对白:

命令 参数 行为
expression_screen_stress amount duration 蓄压:往底压罐里加 amount(建议 0.080.2),只升不降,一直保持。这是"积蓄的情绪"。有软上限 screenStressCap(默认 0.85),堆不满,顶格留给 pulse。
expression_screen_pulse strength decay 冲击:瞬间顶到「底压 + strength」(建议 0.30.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 顶满再泄:

<<expression_screen_stress 0.25 0.7>>   // 谎话开口,屏幕开始坏
hs: <rainb>广告腔台词</rainb>
<<expression_screen_stress 0.10 2>>     // 说完不回落,再坏一档
me: 火山!说出来!
<<expression_screen_stress 0.12 1.5>>   // 被逼问,再坏
hs: 我……
<<expression_truth_gather 0.8 3>>
<<expression_screen_stress 0.15 3>>     // 真话往上聚,屏幕最撑不住的时候
<<start_timeline "火山Glitch/火山头痛2">>
<<expression_screen_pulse 0.45 0.5>>    // 配合 timeline 顶满
<<expression_screen_release 0.5>>       // 一口气释放

LOG1 / LOG2 释放用 火山Glitch/火山头痛2LOG3 落幕改用更短的 火山Glitch/火山头痛3AddressableTimeline/火山头痛3,约 0.75s),收尾更干脆。

三段 LOG 的起手一段比一段重(0.25 / 0.32 / 0.38),段内各自累加到 0.6~0.85。段与段之间屏幕会淡出并自动泄压,所以递进靠起手值而不是跨段累计——唯一的例外是 LOG3:LOG疏通全部完成 从淡入到落幕全程不淡出,LOG3 爆发段积的底压会一路烧进"为什么"高潮,那里再加一口正好顶到上限。

底压参考:0.150.25 底噪憋着;0.450.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 上的连续漂移——这两种都是连续渐变,不会出现纯色块。

曾经试过"纯黑屏 + 饱和彩条"的方向(贴图只提供激发量、黑电平以下归零),结论是太卡通,已回退。现行版本保留荧光着色 + 灰蓝雪花。

_Rageexpression_screen_rage 驱动,把荧光整块换成 _RageColor

屏幕当前不转红。 _RageColor 已经设成和 _PhosphorColor 同一个青绿色,所以 LOG3 攻击段虽然仍然「武装」,屏幕颜色不变。

之所以不是把 Yarn 里的 expression_screen_rage 删掉:PunchScreenForAttackscreenRage > 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 里 lossdrop 两项雪花不受 _Grit,旋钮拧到 0 也压不下去;同时 loss 会把画面几乎乘到全黑,坏法没有底子可以作用。

现在三处都改了:雪花全部走 _Gritloss/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_squeezejitter 以及谎话前后的 wait
  • LOG1/LOG2 的"纠结"强度主要调 expression_truth_straintugs(回抽次数)和 targettarget 越接近 1,越多字会先锁上再崩开,挫败感越强。
  • 反转力度优先调 expression_truth_blackoutalphaexpression_lie_splitdistanceRatioexpression_truth_flashalphaexpression_glitch_pulsepeak
  • expression_memory_tearexpression_glitch_pulse 可以同时触发:两者都作用在记忆材质上(撕裂 vs 模拟失真脉冲)。
  • expression_truth_resolve 是等待命令。其 duration 决定 Yarn 何时继续到真话对白,并保证最后一个字符在这个总时长内稳定。
  • 硬切节奏用 start_timeline 同帧启动 Timeline,然后连续调用 expression_memory_cutexpression_truth_snap;需要等 Timeline 播完时再调用 wait_timeline
  • Stage6 三段谎话到真话均使用硬切;Light/Medium/Heavy 的差异只保留在谎话持续期间的跳字、记忆扰动和 Glitch 强度,不再影响真话稳定速度。
  • expression_memory_brightness_pulse 0.18 0.08 0.18 可直接放在某句对白前,用于精确同步亮度冲击。
  • 所有 Alpha、峰值、外围失真和 Calm 半径都会限制在 01;时间会保证至少 0.01s,避免错误参数卡住 Yarn。

LOG1 可调参数

<<expression_memory_begin "office" 2.2 0.012 0 false 1>>
<<expression_actor_flash "没问题" 0.6 10.5 1.15 1.60 0.025 0.20 0.50 0>>
<<expression_actor_truth_flash "我就是个笑话" 0.35 8.5 0.55 0.02>>
<<expression_actor_word_hit "没" 0.16 18 1.60>>
<<expression_actor_scroll "没问题|冇问题|帽问题" 1.8 0.85 0.45 5.2>>
  • expression_memory_begin 参数依次为记忆图、淡入时长、持续推进速度、旧水平速度、是否保留 Glitch(已忽略,记忆不再用 noise)、目标 Alpha。LOG1 使用 2.2 / 0.012 / 0 / false / 1,一次连续淡入,不再按对白阶梯式补透明度。
  • 记忆段不要再用 noise / glitch_transition;瞬时故障用 expression_glitch_pulseexpression_actor_flash 的 glitch 峰值(写进记忆材质)。屏幕框故障另走 expression_screen_glitch
  • expression_actor_truth_flash 后续参数依次为停留、字号、透明度、抖动幅度。
  • expression_actor_flash 后续参数依次为停留、字号、落定缩放、冲击缩放、色散距离、色散透明度、记忆冲击、Glitch 峰值。
  • expression_actor_word_hit 最后两个数是字号和冲击缩放。
  • expression_actor_scroll 最后一个数是字号。滚动固定为单列,并严格裁切在 ExpressionScreenMaskRect 内;新字幕按给定词组顺序从上方循环补入。