fix(movement): camera auto-rotates to face WASD input direction
40250 parity: CPythonPlayer::NEW_MoveToDirection's m_isCmrRot branch continuously rolls the camera toward the held movement direction every frame while a direction key is down, independent of whether a new translation target was just set. Add _camera_auto_rotate() to replicate this (forward/back = no rotation, strafe = max rate, diagonal = half rate), called unconditionally after the frozen/locked/shop/emotion gate in _process(). Godot's yaw-increase handedness is opposite the reference's D3D Roll(), so the sign is flipped as a platform adaptation; verified by convergence invariants in keyboard_motion_timeline_test.gd rather than bit-for-bit angle matching. Closes movement.keyboard.motion/camera-auto-follow-rotation. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
c93894313a
commit
7df97e01f9
@@ -240,3 +240,40 @@ Game owner 的 `reset_for_map_change()` 和 `on_phase_leave`,再安装 Select/
|
||||
导致后续重复握手错误发出 `CG_TIME_SYNC`,以及清除显式 PHASE_CLOSE owner 标记的差异;现在
|
||||
`PHASE_DEAD` 不改变阶段 owner 或 time-sync 状态。该分支不得重复修改;完整跨阶段 retry、
|
||||
服务器主动 PHASE_CLOSE、空角色 live 和 GC_WARP 失败回退包序仍需独立证据。
|
||||
|
||||
### 2026-09-22:本轮临时切换主合同到 `movement.keyboard.motion`
|
||||
|
||||
`network.login.phase_flow` 的剩余分支目前全部卡在真实 Windows 客户端/服务端主动
|
||||
`PHASE_CLOSE` 包序证据或第三方闭源安全 SDK(Matrix/Passpod/Panama/HybridCrypt/HS/XTrap),
|
||||
本地代码层面已无可继续推进的动作。按阶段 1 的可玩链路顺序(登录 → 移动 → 战斗 → 技能 →
|
||||
网络),本轮改为处理 `movement.keyboard.motion`。
|
||||
|
||||
本轮新增并闭合分支:`movement.keyboard.motion/camera-auto-follow-rotation`。
|
||||
对照 40250 `CPythonPlayer::NEW_MoveToDirection` 的 `m_isCmrRot` 相机跟随分支(每帧对按住
|
||||
的方向键,把相对相机的方位角折算到 `fRotRat∈[-90,90]` 并按 `m_fCmrRotSpd=20.0` 的速率用
|
||||
`CCamera::Roll` 持续转动相机),当前端此前完全没有实现这个副作用。已在
|
||||
`player_controller.gd` 新增 `_camera_auto_rotate()`,用同样的折叠/缩放公式驱动
|
||||
`GameCamera.yaw`;D3D `Roll` 与 Godot `yaw` 转向手性相反,增量符号作为显式记录的平台适配
|
||||
取反,用『按住方向时相机朝该方向收敛、正前后不转、从不越界』的不变式在
|
||||
`keyboard_motion_timeline_test.gd` 中核验(因为没有真实 Windows 客户端可供逐位对照)。
|
||||
详见 `audit/contracts/movement.keyboard-motion.md` 的 `Implementation fix round
|
||||
2026-09-22` 小节。不得重复修改本轮的 `_camera_auto_rotate()` 折叠公式或符号约定,除非
|
||||
出现新的 live 证据推翻当前的收敛不变式假设。
|
||||
|
||||
本轮过程中额外发现但未修复(已记录进合同 `Remaining` 与本文件供下一轮参考):
|
||||
`CActorInstance::CanAct()` 的 `Paralysis/Faint/Sleep` 三个移动门当前端完全没有接入
|
||||
(`net_play.gd::_can_process_network_state()` 只挡 `dead/stunned/knock_down`)。这三个
|
||||
状态的触发源分别在萨满技能、Python 侧角色模块和效果可见性绑定,尚未定位到当前端对应的
|
||||
服务端 affect 管线,属于比相机分支更大的独立子项,不要在没有先做好触发源映射的情况下
|
||||
仓促接线。
|
||||
|
||||
`movement.keyboard.motion` 合同仍为 `PARTIAL`:根运动/`AccumulationMovement`、
|
||||
`OnMove/OnMoving/OnWaiting/OnStop` 资源事件源、同步/受击/死亡/传送门叠加顺序、上述
|
||||
Paralysis/Faint/Sleep 移动门和真实模型姿态测试仍未闭合,下一轮可以在这些分支中任选一个
|
||||
继续(`AccumulationMovement` 根运动差异或 Paralysis/Faint/Sleep 移动门是其中两个具体、
|
||||
无需真实服务端/客户端证据即可推进的候选)。
|
||||
|
||||
`network.login.phase_flow` 的下一主候选仍保持文件前面记录的
|
||||
`network.login.phase_flow/auth-game-phase-matrix/live-package-order/server-initiated-phase-close`:
|
||||
本地结构和 owner 分支均已覆盖,只等新的真实服务端/Windows fixture;在没有新 fixture 前不要
|
||||
重复 `/logout` 探针或重复修改已闭合的 owner 分支。
|
||||
|
||||
Reference in New Issue
Block a user