优化输入回放逻辑 + 调整项目结构

This commit is contained in:
SepComet
2026-04-08 13:08:36 +08:00
parent 75289b5690
commit 098a1dd68c
16 changed files with 369 additions and 186 deletions
@@ -223,14 +223,23 @@ namespace Tests.EditMode.Network
TurnInput = 0f,
ThrottleInput = 1f
});
predictionBuffer.AccumulateLatest(0.1f);
predictionBuffer.Record(new MoveInput
{
PlayerId = "player-1",
Tick = 2,
TurnInput = 0f,
ThrottleInput = 1f
});
predictionBuffer.MarkInputSimulated(1, 0.05f);
predictionBuffer.MarkInputSimulated(2, 0.05f);
resolver.OnAuthoritativeState(new ClientAuthoritativePlayerStateSnapshot(
GameplayFlowTestSupport.CreatePlayerState("player-1", 1, Vector3.zero, acknowledgedMoveTick: 0)));
Assert.That(GetPrivateVector3(resolver, "_predictedPosition").z, Is.EqualTo(1f).Within(0.0001f));
Assert.That(predictionBuffer.PendingInputs.Count, Is.EqualTo(1));
Assert.That(predictionBuffer.PendingInputs.Count, Is.EqualTo(2));
Assert.That(predictionBuffer.PendingInputs[0].Input.Tick, Is.EqualTo(1));
Assert.That(predictionBuffer.PendingInputs[1].Input.Tick, Is.EqualTo(2));
}
finally
{
@@ -89,6 +89,7 @@ namespace Tests.EditMode.Network
buffer.Record(new MoveInput { PlayerId = "player-1", Tick = 10, ThrottleInput = 1f });
buffer.Record(new MoveInput { PlayerId = "player-1", Tick = 11, ThrottleInput = 1f });
buffer.Record(new MoveInput { PlayerId = "player-1", Tick = 12, ThrottleInput = 1f });
buffer.MarkInputSimulated(12, 0.05f);
var accepted = buffer.TryApplyAuthoritativeState(
new PlayerState { PlayerId = "player-1", Tick = 11, AcknowledgedMoveTick = 11 },
@@ -100,10 +101,25 @@ namespace Tests.EditMode.Network
Assert.That(buffer.LastAcknowledgedMoveTick, Is.EqualTo(11));
Assert.That(replayInputs.Count, Is.EqualTo(1));
Assert.That(replayInputs[0].Input.Tick, Is.EqualTo(12));
Assert.That(replayInputs[0].SimulatedDurationSeconds, Is.EqualTo(0f));
Assert.That(replayInputs[0].SimulatedDurationSeconds, Is.EqualTo(0.05f).Within(0.0001f));
Assert.That(buffer.PendingInputs.Count, Is.EqualTo(1));
}
[Test]
public void ClientPredictionBuffer_TryGetNextUnsimulatedInput_UsesOldestPendingMoveInput()
{
var buffer = new ClientPredictionBuffer();
buffer.Record(new MoveInput { PlayerId = "player-1", Tick = 10, ThrottleInput = 1f });
buffer.Record(new MoveInput { PlayerId = "player-1", Tick = 11, ThrottleInput = -1f });
buffer.MarkInputSimulated(10, 0.05f);
var found = buffer.TryGetNextUnsimulatedInput(out var nextInput);
Assert.That(found, Is.True);
Assert.That(nextInput.Input.Tick, Is.EqualTo(11));
Assert.That(nextInput.SimulatedDurationSeconds, Is.EqualTo(0f));
}
[Test]
public void ClientPredictionBuffer_StaleAuthoritativeState_IsIgnored()
{
@@ -802,10 +818,16 @@ namespace Tests.EditMode.Network
rotation = Quaternion.identity;
for (var i = 0; i < steps; i++)
{
TankMovementKinematics.ApplyStep(10, turnInput, throttleInput, stepDuration, ref position, ref rotation);
TankMovementKinematics.ApplyStep(10, ToSimulationTurnInput(turnInput), throttleInput, stepDuration,
ref position, ref rotation);
}
}
private static float ToSimulationTurnInput(float networkTurnInput)
{
return -networkTurnInput;
}
private static void ResetMovementState(Rigidbody rigidbody, Vector3 position, Quaternion rotation)
{
rigidbody.position = position;