fix(app+core): Phase B.2 — increase step height + resolve initial Z from terrain
Two fixes for the "position never changes when walking" bug: 1. StepUpHeight was 1.0 units — too tight. The player started at Z=92.2 (ACE relocation from previous session) but terrain Z was ~94, so every movement attempt had a Z delta of 1.8 which exceeded the limit. Increased to 5.0 (forgiving for MVP; AC default for humans is ~2 from Setup.StepUpHeight). 2. Initial position now resolves through PhysicsEngine with a huge step height (100) to snap to the correct terrain Z regardless of where the server-sent Z currently is. With indoor transitions disabled, this always produces the outdoor terrain height. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3b2f56c531
commit
b341193cfe
2 changed files with 16 additions and 10 deletions
|
|
@ -44,7 +44,14 @@ public sealed class PlayerMovementController
|
|||
public float RunSpeed { get; set; } = 7f;
|
||||
public float TurnSpeed { get; set; } = 1.5f;
|
||||
public float MouseTurnSensitivity { get; set; } = 0.003f;
|
||||
public float StepUpHeight { get; set; } = 1.0f;
|
||||
/// <summary>
|
||||
/// Maximum Z increase per movement step before the move is rejected.
|
||||
/// AC's default StepUpHeight for human characters is ~2 units (from
|
||||
/// Setup.StepUpHeight). Using 5 for the MVP to be forgiving — prevents
|
||||
/// walking up vertical walls but allows stairs, ramps, and terrain
|
||||
/// slopes that the heightmap interpolation can produce.
|
||||
/// </summary>
|
||||
public float StepUpHeight { get; set; } = 5.0f;
|
||||
|
||||
public float Yaw { get; set; }
|
||||
public Vector3 Position { get; private set; }
|
||||
|
|
|
|||
|
|
@ -203,15 +203,14 @@ public sealed class GameWindow : IDisposable
|
|||
float plocalX = playerEntity.Position.X - (plbX - _liveCenterX) * 192f;
|
||||
float plocalY = playerEntity.Position.Y - (plbY - _liveCenterY) * 192f;
|
||||
uint pinitCellId = ((uint)plbX << 24) | ((uint)plbY << 16) | 0x0001u;
|
||||
// Use the server-sent position directly — the server already
|
||||
// gave us a valid position at CreateObject time. Running it
|
||||
// through PhysicsEngine.Resolve was mapping the player into
|
||||
// an indoor cell (e.g., the foundry at Z=66) when they're
|
||||
// actually standing on outdoor terrain at Z=93+. The physics
|
||||
// engine's cell-containment check is too aggressive for the
|
||||
// initial placement. Once the player starts moving, Resolve
|
||||
// will keep them on the correct surface.
|
||||
_playerController.SetPosition(playerEntity.Position, pinitCellId & 0xFFFFu);
|
||||
// Resolve the initial position through the physics engine to
|
||||
// get the correct terrain Z. The server-sent Z may be stale
|
||||
// from a previous ACE relocation. With indoor transitions
|
||||
// disabled, Resolve will always snap to outdoor terrain Z.
|
||||
var initResult = _physicsEngine.Resolve(
|
||||
playerEntity.Position, pinitCellId & 0xFFFFu,
|
||||
System.Numerics.Vector3.Zero, 100f); // huge step height for initial snap
|
||||
_playerController.SetPosition(initResult.Position, initResult.CellId);
|
||||
// Derive initial yaw from the entity's server-sent rotation
|
||||
// rather than hardcoding. Extract yaw from the quaternion.
|
||||
var q = playerEntity.Rotation;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue