fix(runtime): align portal and movement presentation
Port retail portal viewport projection and reveal behavior, preserve outbound combat style, drive remote and local grounded movement from authored CSequence root frames, and reuse the local prepared pose so animation hooks advance once. User-verified portal, observer movement, combat stance, and short-tap locomotion gates. Release build passed with 5,767 tests and five intentional skips. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
e95f55f25b
commit
124e046976
30 changed files with 1362 additions and 348 deletions
|
|
@ -149,6 +149,65 @@ public class PlayerMovementControllerTests
|
|||
Assert.True(result.Position.X > 96f + 2f, $"X={result.Position.X} should have moved forward");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Update_AttachedAnimationWithZeroRootDelta_DoesNotGlideOnForwardEdge()
|
||||
{
|
||||
var controller = new PlayerMovementController(MakeFlatEngine());
|
||||
var start = new Vector3(96f, 96f, 50f);
|
||||
controller.SetPosition(start, 0x0001);
|
||||
controller.Yaw = 0f;
|
||||
controller.AttachAnimationRootMotionSource(_ => Vector3.Zero);
|
||||
|
||||
MovementResult result = controller.Update(
|
||||
PhysicsBody.MinQuantum,
|
||||
new MovementInput(Forward: true));
|
||||
|
||||
Assert.Equal(start, result.Position);
|
||||
Assert.Equal(0f, controller.BodyVelocity.X);
|
||||
Assert.Equal(0f, controller.BodyVelocity.Y);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Update_AttachedAnimationRootDelta_DrivesGroundedBodyAtObjectScale()
|
||||
{
|
||||
var controller = new PlayerMovementController(MakeFlatEngine());
|
||||
var start = new Vector3(96f, 96f, 50f);
|
||||
controller.SetPosition(start, 0x0001);
|
||||
controller.Yaw = 0f;
|
||||
controller.ObjectScale = 2f;
|
||||
controller.AttachAnimationRootMotionSource(_ => new Vector3(0f, 0.1f, 0f));
|
||||
|
||||
MovementResult result = controller.Update(
|
||||
PhysicsBody.MinQuantum,
|
||||
new MovementInput(Forward: true));
|
||||
|
||||
// Local +Y is forward. Yaw 0 maps it to world +X; m_scale doubles
|
||||
// the animation-authored 0.1 m displacement to 0.2 m.
|
||||
Assert.Equal(start.X + 0.2f, result.Position.X, precision: 3);
|
||||
Assert.Equal(start.Y, result.Position.Y, precision: 3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Update_SubQuantumAnimationRootDeltas_AccumulateIntoOnePhysicsStep()
|
||||
{
|
||||
var controller = new PlayerMovementController(MakeFlatEngine());
|
||||
var start = new Vector3(96f, 96f, 50f);
|
||||
controller.SetPosition(start, 0x0001);
|
||||
controller.Yaw = 0f;
|
||||
controller.AttachAnimationRootMotionSource(_ => new Vector3(0f, 0.05f, 0f));
|
||||
|
||||
MovementResult first = controller.Update(
|
||||
PhysicsBody.MinQuantum * 0.5f,
|
||||
new MovementInput(Forward: true));
|
||||
MovementResult second = controller.Update(
|
||||
PhysicsBody.MinQuantum * 0.5f,
|
||||
new MovementInput(Forward: true));
|
||||
|
||||
Assert.Equal(start, first.Position);
|
||||
Assert.Equal(start.X + 0.1f, second.Position.X, precision: 3);
|
||||
Assert.Equal(start.Y, second.Position.Y, precision: 3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Update_SubQuantumFrame_InterpolatesRenderPositionWithoutAdvancingPhysicsPosition()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue