Repository navigation
fix(story-player): characteraction 阻塞键/exit 方向表/shake 阻塞/zoom pivot 等原生语义对齐 - #349
Merged
Merged
Conversation
…vot 语义 依据 2.7.61(build 2761)GameAssembly.dll IDA 反编译复核: - 阻塞只读 isblock(native _AddFinishCommand 不读 block=),消除语料 4183 条 block= 拼写凭空产生的停顿 - exit 缺省 direction=left,支持 up/down,位移改用 _GenExitPosition 原生表(l/m/r 槽位 -952/1352 等),xpos/ypos 双双存在时作绝对坐标 - shake 按原生 _AddFinishCommand 语义阻塞完整时长 - zoom 的 xpos/ypos 改为 [0,1] pivot(越界整条 no-op),缩放围绕 pivot - fadetime 全分支过 CalculateFadetime(animateRatio),exit/zoom 默认 1.0s; jump/shake 在快进/零时长下退化为瞬时 move(NeedSkipAnimation) - power 默认 10、times 默认 3、randomness 读原生 random 键默认 10 - jump 改单 tween(总时长=fadeTime,times 次跳动内含),阻塞覆盖全程
daflyinbed
force-pushed
the
fix/story-player-characteraction
branch
from
October 19, 2026 15:12
fe0ab22 to
5e95bee
Compare
按 2.7.81 反编译复核(DOTween::Shake 0x18424e2d0 逐行还原)对齐: - shake 重写为路点模型:路点数 trunc(vibrato×时长) 钳 2、方向逐次 180°±random 度、幅度线性衰减、段长按 (i+1) 加权归一、末路点归零, OutCubic 全局扭曲;isblock 时 await 该 tween。charslot 的 action=shake 共用同一路径(原生 _GenCharslotShake 即转调 CharShake),删除旧 pickShakeOffset 概率-抽档模型 - type/name/direction 改 String.op_Equality 精确比较(去 trim/小写归一); name 缺失先取 GetOrDefault 默认 "left" 再进真值表(exit 缺 name 走左槽) - times/random/exit 显式 xpos/ypos 改走 Convert.ToInt32 银行家舍入 (toNativeInt);scale/power 去掉 Math.max(0,·) 钳制 - zoom fadetime=0 仍阻塞(DOTween.To 零时长返回非 null tween) - move/exit 补 Ease.OutCubic、jump x 轴保持 Linear(sequence 自身 ease 无效) - 测试:isblock shake 用例改两次 tween 断言,新增 move/exit/jump ease 用例 vue-tsc -b、eslint、vitest 760/760 通过
daflyinbed
marked this pull request as ready for review
October 20, 2026 13:26
- shake:DOShakePosition 标记 SpecialStartupMode.SetShake,启动时
SpecialPluginsUtils.SetShake(0x18427f590)把 easeType 强制为 Linear,
CharShake 的 SetEase(OutCubic) 被覆盖;Vector3ArrayPlugin 逐段求值
缓动,故每段线性插值。去掉全局 OutCubic 扭曲,并复用 core/ShakePath
(DOShakePosition 传 ignoreZAxis=false,Full 模式 tilt 与镜头抖动一致)
- jump:Sequence.DoApplyTween(0x1842525c0)会先用 sequence 自身 ease
扭曲时间轴,CharJump 的 SetEase(OutCubic) 生效;DOLocalJump 的 y 位移
走 EasedValue(OutQuad)(<DOLocalJump>b__7)。x=OutCubic、
y=OutQuad∘OutCubic、弹跳弧采样 OutCubic 时间
- exit 显式 xpos/ypos:SetCharPos 直接写 _offset.localPosition,与
_GenExitPosition 同一槽位位移空间,不再按 baseX/baseY 换算故事坐标
- charslot times 默认对齐原生 GetOrDefault<int>("times", 0)
- 复用已有 toNativeIntParam,移除重复的 toNativeInt 与失效的 shakeTimeout
Member
Review(对照 2.7.81 GameAssembly.dll 复核)我对照 2.7.81 的反编译逐条复核了 PR 描述和两个 commit 里的原生结论。大部分对齐都成立,但有 3 处与原生不符,已在 b343ba4 里直接修好。 已修复1. shake 不应有 OutCubic 全局扭曲
2. jump:sequence 自身的 ease 是生效的
3. exit 的显式
顺手清理
验证: 复核一致(未改动)
非阻塞备注(未在本 PR 处理)
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
本 PR 修复 StoryPlayer 对 AVG
characteraction命令移植中的全部 P1/P2 行为差异与可顺手对齐的 P3 默认值(共 10 项)。依据是对明日方舟官服客户端(2.7.61 / build 2761,Unity IL2CPP)GameAssembly.dll 的逆向分析,关键结论已在下文直接给出,不依赖外部文档。背景:native 的 characteraction 机制(2.7.61 逆向结论)
命令由
Torappu.AVG.CharacterPanel处理(与character命令共用面板),分发入口_ExecuteCharacterAction(VA0x183E699F0),按type明文比较分move/jump/exit/zoom/shake五支,未知 type 记 LogError 且不阻塞。关键语义:_AddFinishCommand,VA0x183E698E0):只读isblock参数;block=键被整个 CharacterPanel 忽略(全库仅 cutin panel 读block)。tween 非空且 isblock 时OnComplete(FinishCommand)阻塞,tween 为空(零时长)不阻塞。AVGUtils.CalculateFadetime(VA0x183E69360,animateRatio × fadetime)。快进(animateRatio→0)时NeedSkipAnimation(VA0x183E69680)为真,jump/shake 整体退化重新走_ExecuteCharacterMove(瞬时应用 xpos/ypos)。0x183E69C80):direction缺省"left";_GenExitPosition(VA0x183E6B670)按槽位给定位移:left 槽 left/right →(-952,0)/(1352,0),right 槽 →(-1352,0)/(952,0),middle →(-1152,0)/(1152,0),up/down →(0,±1072),非法 direction →(0,0);经AVGCharacterSlot.SetCharPos(0x183EB3290)绝对定位(水平退出同时把纵向漂移归零)。xpos/ypos经TryGetParam<int>双双存在才作绝对坐标。fadetime 缺省 1.0。0x183E6AC90→AVGCharacterSlot.CharZoom,0x183EB2B50):xpos/ypos是[0,1]区间的 pivot(缺省 0.5/0.5,作用于_foreImage.rectTransform),越界 → 返回 null,整条命令 no-op(scale 也不生效);scale 缺省 1.0,fadetime 缺省 1.0;无 NeedSkipAnimation。0x183E6A870→CharShake,0x183EB29F0):DOShakePosition(fadeTime, power, times, random, ...),随机度键名是random(int,缺省 10),power 缺省 10、times 缺省 3、fadetime 缺省 0.5;与其它分支一样经_AddFinishCommand可阻塞。0x183E6A050→CharJump,0x183EB2690):DOLocalJump(cur+(x,y), power, times, fadeTime)是单 tween,总时长 = fadeTime(times 次跳动内含其中),阻塞等完整 tween。修复内容
1. 阻塞键别名(P1)
isblock;block=恒忽略(2.7.61 语料 characteraction 行内block=4183 次 vsisblock=187 次)。toBoolean(block, toBoolean(isblock, false)),block=优先生效,数千条命令产生原生没有的停顿。isblock;block=不再参与。同步改写原来声称"native 接受两种拼写"的错误 provenance 注释。2. exit 缺省方向相反(P1)
direction缺省"left"→ 向左屏外。(0,±1072)原生值);非法值按原生(0,0)回到槽位静止锚点;出屏目标从"按宽度估算"改为_GenExitPosition原生位移表逐值照抄(l/m/r 槽位区分),水平退出同时把 actionY 归零(原生 SetCharPos 语义)。3. shake 永不阻塞(P1)
_AddFinishCommand,isblock=true时阻塞到抖动结束(时长 = 缩放后 fadeTime)。case "shake"直接 return,block被丢弃。stop=true除外)。4. zoom 的 xpos/ypos 语义(P1)
[0,1]pivot,越界 → 整条命令 no-op。xpos=-1)仍生效 scale + 偏移。charslot的 scale 路径。5. fadetime 不经 animateRatio(P2)
CalculateFadetime;快进时 jump/shake 退化为 move,move/exit/zoom 走瞬时分支。character命令相同的calculateFadeMs;缩放后时长为 0 时 jump/shake 在 runtime 侧改派发为 move(对齐 NeedSkipAnimation →_ExecuteCharacterMove)。6. exit/zoom 的 fadetime 默认(P2):按 type 取默认(
exit/zoom → 1.0,move/jump/shake → 0.5),原状统一 0.5。7. power 默认值(P2):jump/shake 默认从 0 改为原生 10(原状未写 power 的 jump 完全不弹跳;语料 761 条 jump 中 94 条未写 power)。
8. jump 总时长与阻塞边界(P2):每跳时长从
durationMs改为durationMs/times(单 tween 内含 times 次跳动,总时长 = durationMs,对齐 DOLocalJump);阻塞从"只等 move 段"改为Promise.all([move, jump])覆盖全程。9. shake 随机度参数键(P2):从
randomness(默认 90,clamp 0-100)改为原生random键(int,默认 10);pickShakeOffset 的"度数→逐 tick 触发概率"映射在注释中声明为 web 适配。10. exit 显式坐标(P2)+ times 默认(P3):exit 的
xpos/ypos双双存在时作绝对故事坐标(与character命令的 absolutePosition 约定一致),仅单个存在时忽略(原状把单独 ypos 当相对增量、丢弃 xpos);times默认从 1 改为原生 3(语料 70 条 jump 未写 times;time=拼写错误键也落到默认 3)。另:zoom 缺省scale从"保持当前"改为原生缺省 1.0,stop/start/leftend/rightend/xscale/yscale在注释中标注为 charslot 风格 web 扩展(native 面板不读)。不改动(review 确认一致或建议维持):5 分支 type 分发与未知 type 非阻塞、逐分支 slot 真值表(含 exit 兜底 middle)、move/jump 相对位移、
fadetime=0时不阻塞、exit 不清槽、zoom scale 目标值语义、name/type的大小写归一(P3,语料全小写)、ease 线性(P3 视觉细节,涉及共享 TweenRunner,不在本命令范围内动)。验证用剧情文件
生产剧情语料(2.7.61)本地路径
torappu/storage/asset/gamedata/latest/story:obt/main/level_main_09-03_beg.txt144/158/183 行(type="move"+block=true无isblock)——播放时这些位移不再把播放器卡住(与官服一致)。activities/act15d0/level_act15d0_07_beg.txt90 行[characteraction(name="left", type="exit",fadetime=0.5, block=true)]——无 direction,角色应向左出屏(旧版向右),且 block= 不生效。activities/act17side/level_act17side_01_beg.txt414/417/429 行与activities/act17side/level_act17side_st03.txt361/363/368/371 行(xpos=-1)——整条 zoom 不再执行(旧版会把 scale 一并应用);activities/act12side/level_act12side_08_end.txt264 行(xpos=0.5,ypos=0.3,scale=1.5)、activities/act22side/level_act22side_08_end.txt192 行(xpos=0.8,ypos=0.8)、activities/act20side/level_act20side_03_end.txt180 行——缩放围绕指定 pivot 进行。obt/main/level_main_09-16_end.txt168/174/175 行(未写 power 的 jump,旧版不弹跳)。obt/memory/story_asbest_1_1.txt381 行(未写 times,原生弹 3 次);obt/memory/story_billro_1_1.txt36 行(time=1拼写错误键,同样落默认 3)。obt/memory/story_bstalk_1_1.txt263 行与activities/act20side/level_act20side_02_end.txt154 行(fadetime=0,后者带isblock=true但零时长不阻塞,瞬时位移)。isblock=true、无random=、exit 无 up/down、无 xpos/ypos),前瞻对齐,由单测锁定:tests/runtime.spec.ts(「awaits the full shake duration…」位于tests/renderer.spec.ts、「reads the shake randomness from the native random key」、「defaults the exit direction to left and accepts native up/down」、「uses exit xpos/ypos as absolute coordinates when both are present」)与tests/renderer.spec.ts(「exits along the native direction table including up and down」)。测试
pnpm test:20 个文件 234 个用例全部通过(基线 222,新增/改写 characteraction 相关 12 个)。pnpm exec vue-tsc -b通过;pnpm exec eslint(改动文件)通过。STORY_CORPUS_ROOT=… pnpm test:story-log全语料 Log All 回归通过(2 用例,约 71s)。