fix(input): Phase K live-test fixes pt3 — fly→chase round-trip, Shift coexists, run-speed for backward + strafe
Four issues from the K-fix2 launch (2026-04-26 user report): 1. Can't return from free-fly to player view. CameraController.ToggleFly only swaps Fly↔Orbit, so a user who flew out of player mode landed in orbit (Holtburg) on toggle-back instead of the chase camera. Added ToggleFlyOrChase() helper that prefers Fly→Chase / Chase→Fly when _playerMode is true and a chase camera is available; falls back to the original Fly↔Orbit toggle for offline / pre-login flows. Wired into all three free-fly entry points: keyboard shortcut (Ctrl+Shift+F), Camera menu item, and DebugPanel button. 2. Shift while moving STOPS instead of dropping to walk. Root cause: InputDispatcher.IsChordHeld required _keyboard.CurrentModifiers to match chord.Modifiers EXACTLY. So with W bound as (W, None), holding W and then pressing Shift made CurrentModifiers=Shift mismatch chord (None) → IsActionHeld(MovementForward) returned false → Forward flag dropped → player stopped. Fixed by relaxing IsChordHeld: when chord.Modifiers is None, Shift is allowed to coexist (it's the retail walk-modifier). Other modifiers (Ctrl, Alt, Win) still mismatch strictly so Ctrl+W stays a distinct chord from W. +2 tests pinning the new permissive-Shift / strict-Ctrl semantics. 3. Backwards too slow when running. forwardCmdSpeed for the WalkBackward branch was hardcoded to 1.0; localY was hardcoded to -(WalkAnimSpeed * 0.65). Neither honored input.Run. With Run=true (default), backward now scales by runRate (~2.4×) so X = "run backwards" matches the forward run pace × the 0.65 backward animation cycle ratio. 4. Strafe too slow when running. localX for SideStepLeft / SideStepRight was hardcoded to ±SidestepAnimSpeed regardless of Run. Same fix: when Run is held, scale by runRate so strafe at default speed matches the run-forward pace. Tests: 1220 → 1222 (the two new IsChordHeld tests). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6481169cb9
commit
785dd92378
4 changed files with 130 additions and 28 deletions
|
|
@ -272,8 +272,16 @@ public sealed class PlayerMovementController
|
|||
}
|
||||
else if (input.Backward)
|
||||
{
|
||||
forwardCmd = MotionCommand.WalkBackward;
|
||||
forwardCmdSpeed = 1.0f;
|
||||
forwardCmd = MotionCommand.WalkBackward;
|
||||
// K-fix3 (2026-04-26): backward also honors Run. Without
|
||||
// this, holding X with Run=true (default) still produced
|
||||
// walk-tier backward speed because forwardCmdSpeed was
|
||||
// hardcoded to 1.0. Now scale by runRate the same way
|
||||
// RunForward does.
|
||||
if (input.Run && _weenie.InqRunRate(out float runRateBack))
|
||||
forwardCmdSpeed = runRateBack;
|
||||
else
|
||||
forwardCmdSpeed = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -307,16 +315,30 @@ public sealed class PlayerMovementController
|
|||
float localY = 0f;
|
||||
float localX = 0f;
|
||||
|
||||
// K-fix3 (2026-04-26): unified run-multiplier for backward
|
||||
// + strafe. Forward already scales correctly because it uses
|
||||
// stateVel.Y (which the motion state machine fed runRate
|
||||
// into via DoMotion). Backward + strafe bypass the state
|
||||
// machine and hardcoded speed; previously they capped at
|
||||
// walk speed regardless of Run, which made the ~2.4×
|
||||
// forward-vs-back/strafe ratio feel wrong. Now both scale
|
||||
// with the same runRate the forward branch uses.
|
||||
float runMul = 1.0f;
|
||||
if (input.Run && _weenie.InqRunRate(out float vrr))
|
||||
runMul = vrr;
|
||||
|
||||
if (input.Forward)
|
||||
localY = stateVel.Y;
|
||||
else if (input.Backward)
|
||||
localY = -(MotionInterpreter.WalkAnimSpeed * 0.65f);
|
||||
localY = -(MotionInterpreter.WalkAnimSpeed * 0.65f * runMul);
|
||||
|
||||
// Full-speed strafe to match retail sidestep pace.
|
||||
// Strafe scales with the same runMul so sidestep matches
|
||||
// the forward pace at run speed (retail uses speed=1.0 for
|
||||
// SideStep + the same hold-key-driven run/walk multiplier).
|
||||
if (input.StrafeRight)
|
||||
localX = MotionInterpreter.SidestepAnimSpeed;
|
||||
localX = MotionInterpreter.SidestepAnimSpeed * runMul;
|
||||
else if (input.StrafeLeft)
|
||||
localX = -MotionInterpreter.SidestepAnimSpeed;
|
||||
localX = -MotionInterpreter.SidestepAnimSpeed * runMul;
|
||||
|
||||
_body.set_local_velocity(new Vector3(localX, localY, savedWorldVz));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue