fix(B.6): smooth local rotation — remove 20° snap-on-approach (not retail)
User report: 'quick snap at like 30 degrees to the last position. Not
a smooth turn. Did you verify with retail?'
Verified against retail decomp at MoveToManager::HandleTurnToHeading
(0x0052a0c0). Retail's pattern:
- Body rotates continuously via a TurnLeft/TurnRight motion cycle.
- The ONLY snap is set_heading(target, 1) after heading_greater()
detects we've passed the target (overshoot protection).
- No 'snap when close to target' tolerance band — that's purely
a sparse-update fudge in RemoteMoveToDriver (the remote-creature
path with ~1Hz UpdatePosition broadcasts).
I'd copied the snap-on-approach tolerance from RemoteMoveToDriver to
ApplyAutoWalkOverlay. Wrong: local player rotates at per-tick
resolution, no sparse-update problem to compensate for. Removed.
The MathF.Min(|delta|, maxStep) clamp naturally lands the body on
the target heading without overshoot in the final partial tick, so
no separate snap-on-overshoot branch is needed for our integrator
either.
Visible effect: 1.8m humanoid rotating ~180° at π/2 rad/s takes ~2 s
of smooth turn now, instead of ~1.3 s of turn + instant 20° snap at
the end.
This commit is contained in:
parent
cffb10ff18
commit
7158c46d46
1 changed files with 14 additions and 9 deletions
|
|
@ -490,15 +490,20 @@ public sealed class PlayerMovementController
|
|||
float delta = desiredYaw - Yaw;
|
||||
while (delta > MathF.PI) delta -= 2f * MathF.PI;
|
||||
while (delta < -MathF.PI) delta += 2f * MathF.PI;
|
||||
if (MathF.Abs(delta) <= RemoteMoveToDriver.HeadingSnapToleranceRad)
|
||||
{
|
||||
Yaw = desiredYaw;
|
||||
}
|
||||
else
|
||||
{
|
||||
float maxStep = RemoteMoveToDriver.TurnRateRadPerSec * dt;
|
||||
Yaw += MathF.Sign(delta) * MathF.Min(MathF.Abs(delta), maxStep);
|
||||
}
|
||||
|
||||
// Retail-faithful local rotation: rotate continuously at
|
||||
// TurnRate, never snap until overshoot would occur. Retail's
|
||||
// MoveToManager::HandleTurnToHeading (0x0052a0c0) only snaps
|
||||
// when heading_greater() detects we've crossed the target —
|
||||
// there's no "snap when close" tolerance band. The earlier
|
||||
// 20° snap was borrowed wrongly from RemoteMoveToDriver
|
||||
// (which is the sparse-update-fudge path for remotes).
|
||||
//
|
||||
// MathF.Min(|delta|, maxStep) naturally clamps the final
|
||||
// fractional step to exactly delta, so we land on the
|
||||
// target heading without overshoot.
|
||||
float maxStep = RemoteMoveToDriver.TurnRateRadPerSec * dt;
|
||||
Yaw += MathF.Sign(delta) * MathF.Min(MathF.Abs(delta), maxStep);
|
||||
while (Yaw > MathF.PI) Yaw -= 2f * MathF.PI;
|
||||
while (Yaw < -MathF.PI) Yaw += 2f * MathF.PI;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue