修改操作方式为 坦克式运动

This commit is contained in:
SepComet
2026-04-03 15:03:42 +08:00
parent f6ca6fa6e4
commit 0aab757091
43 changed files with 1284 additions and 342 deletions
@@ -49,6 +49,11 @@ namespace Tests.EditMode.Network
clientRuntime.StartAsync().GetAwaiter().GetResult();
using var serverRuntime = ServerRuntimeEntryPoint.StartAsync(configuration).GetAwaiter().GetResult();
serverRuntime.Host.NotifyLoginStarted(ClientPeer);
serverRuntime.Host.NotifyLoginSucceeded(ClientPeer, "player-a");
serverRuntime.Host.NotifyLoginStarted(RemotePeer);
serverRuntime.Host.NotifyLoginSucceeded(RemotePeer, "player-b");
serverTransports[9001].EmitReceive(
GameplayFlowTestSupport.BuildEnvelope(
MessageType.MoveInput,
@@ -56,8 +61,8 @@ namespace Tests.EditMode.Network
{
PlayerId = "player-b",
Tick = 1,
MoveX = 0f,
MoveY = 0f
TurnInput = 0f,
ThrottleInput = 0f
}),
RemotePeer);
serverRuntime.DrainPendingMessagesAsync().GetAwaiter().GetResult();
@@ -69,8 +74,8 @@ namespace Tests.EditMode.Network
{
PlayerId = "player-a",
Tick = 1,
MoveX = 1f,
MoveY = 0f
TurnInput = 0f,
ThrottleInput = 1f
},
MessageType.MoveInput);
ClientGameplayInputFlow.SendShootInput(
@@ -162,9 +167,9 @@ namespace Tests.EditMode.Network
RemotePeer);
serverRuntime.Host.NotifyLoginStarted(ClientPeer);
serverRuntime.Host.NotifyLoginSucceeded(ClientPeer);
serverRuntime.Host.NotifyLoginSucceeded(ClientPeer, "player-a");
serverRuntime.Host.NotifyLoginStarted(RemotePeer);
serverRuntime.Host.NotifyLoginSucceeded(RemotePeer);
serverRuntime.Host.NotifyLoginSucceeded(RemotePeer, "player-b");
serverRuntime.UpdateAuthoritativeMovement(TimeSpan.FromMilliseconds(50));
TransferBroadcastMessages(serverTransports[9001], clientSyncTransport, ServerSender);
@@ -186,8 +191,8 @@ namespace Tests.EditMode.Network
{
PlayerId = "player-b",
Tick = 1,
MoveX = 1f,
MoveY = 0f
TurnInput = 0f,
ThrottleInput = 1f
}),
RemotePeer);
serverRuntime.DrainPendingMessagesAsync().GetAwaiter().GetResult();
@@ -68,8 +68,8 @@ namespace Tests.EditMode.Network
{
PlayerId = "player-1",
Tick = 12,
MoveX = 1,
MoveY = -1
TurnInput = 1,
ThrottleInput = -1
};
manager.SendMessage(message, MessageType.MoveInput);
@@ -82,8 +82,8 @@ namespace Tests.EditMode.Network
Assert.That(envelope.Type, Is.EqualTo((int)MessageType.MoveInput));
Assert.That(parsed.PlayerId, Is.EqualTo("player-1"));
Assert.That(parsed.Tick, Is.EqualTo(12));
Assert.That(parsed.MoveX, Is.EqualTo(1));
Assert.That(parsed.MoveY, Is.EqualTo(-1));
Assert.That(parsed.TurnInput, Is.EqualTo(1));
Assert.That(parsed.ThrottleInput, Is.EqualTo(-1));
}
[Test]
@@ -100,8 +100,8 @@ namespace Tests.EditMode.Network
{
PlayerId = "player-1",
Tick = 13,
MoveX = 0f,
MoveY = 0f
TurnInput = 0f,
ThrottleInput = 0f
};
manager.SendMessage(message, MessageType.MoveInput);
@@ -114,8 +114,8 @@ namespace Tests.EditMode.Network
Assert.That(envelope.Type, Is.EqualTo((int)MessageType.MoveInput));
Assert.That(parsed.PlayerId, Is.EqualTo("player-1"));
Assert.That(parsed.Tick, Is.EqualTo(13));
Assert.That(parsed.MoveX, Is.EqualTo(0f));
Assert.That(parsed.MoveY, Is.EqualTo(0f));
Assert.That(parsed.TurnInput, Is.EqualTo(0f));
Assert.That(parsed.ThrottleInput, Is.EqualTo(0f));
}
[Test]
@@ -350,12 +350,12 @@ namespace Tests.EditMode.Network
});
transport.EmitReceive(
BuildEnvelope(MessageType.MoveInput, new MoveInput { PlayerId = "player-1", Tick = 8, MoveX = 1 }),
BuildEnvelope(MessageType.MoveInput, new MoveInput { PlayerId = "player-1", Tick = 8, ThrottleInput = 1 }),
Sender);
manager.DrainPendingMessagesAsync().GetAwaiter().GetResult();
transport.EmitReceive(
BuildEnvelope(MessageType.MoveInput, new MoveInput { PlayerId = "player-1", Tick = 6, MoveX = -1 }),
BuildEnvelope(MessageType.MoveInput, new MoveInput { PlayerId = "player-1", Tick = 6, ThrottleInput = -1 }),
Sender);
manager.DrainPendingMessagesAsync().GetAwaiter().GetResult();
@@ -39,8 +39,8 @@ namespace Tests.EditMode.Network
using var runtime = ServerRuntimeEntryPoint.StartAsync(configuration).GetAwaiter().GetResult();
PrimePlayer(createdTransports[9000], PeerA, "player-a", 1);
PrimePlayer(createdTransports[9000], PeerB, "player-b", 1);
PrimePlayer(runtime, PeerA, "player-a");
PrimePlayer(runtime, PeerB, "player-b");
runtime.DrainPendingMessagesAsync().GetAwaiter().GetResult();
createdTransports[9000].EmitReceive(BuildEnvelope(MessageType.ShootInput, new ShootInput
@@ -111,8 +111,8 @@ namespace Tests.EditMode.Network
using var runtime = ServerRuntimeEntryPoint.StartAsync(configuration).GetAwaiter().GetResult();
PrimePlayer(createdTransports[9001], PeerA, "player-a", 1);
PrimePlayer(createdTransports[9001], PeerB, "player-b", 1);
PrimePlayer(runtime, PeerA, "player-a");
PrimePlayer(runtime, PeerB, "player-b");
runtime.DrainPendingMessagesAsync().GetAwaiter().GetResult();
createdTransports[9000].EmitReceive(BuildEnvelope(MessageType.ShootInput, new ShootInput
@@ -166,8 +166,8 @@ namespace Tests.EditMode.Network
using var runtime = ServerRuntimeEntryPoint.StartAsync(configuration).GetAwaiter().GetResult();
PrimePlayer(createdTransports[9000], PeerA, "player-a", 1);
PrimePlayer(createdTransports[9000], PeerB, "player-b", 1);
PrimePlayer(runtime, PeerA, "player-a");
PrimePlayer(runtime, PeerB, "player-b");
runtime.DrainPendingMessagesAsync().GetAwaiter().GetResult();
createdTransports[9000].EmitReceive(BuildEnvelope(MessageType.ShootInput, new ShootInput
@@ -192,15 +192,10 @@ namespace Tests.EditMode.Network
Assert.That(runtime.AuthoritativeCombatStates.Count, Is.EqualTo(0));
}
private static void PrimePlayer(FakeTransport transport, IPEndPoint peer, string playerId, long tick)
private static void PrimePlayer(ServerRuntimeHandle runtime, IPEndPoint peer, string playerId)
{
transport.EmitReceive(BuildEnvelope(MessageType.MoveInput, new MoveInput
{
PlayerId = playerId,
Tick = tick,
MoveX = 0f,
MoveY = 0f
}), peer);
runtime.Host.NotifyLoginStarted(peer);
runtime.Host.NotifyLoginSucceeded(peer, playerId);
}
private static FakeTransport CreateTransport(IDictionary<int, FakeTransport> createdTransports, int port)
@@ -33,26 +33,31 @@ namespace Tests.EditMode.Network
using var runtime = ServerRuntimeEntryPoint.StartAsync(configuration).GetAwaiter().GetResult();
runtime.Host.NotifyLoginStarted(PeerA);
runtime.Host.NotifyLoginSucceeded(PeerA, "player-a");
runtime.Host.NotifyLoginStarted(PeerB);
runtime.Host.NotifyLoginSucceeded(PeerB, "player-b");
createdTransports[9000].EmitReceive(BuildEnvelope(MessageType.MoveInput, new MoveInput
{
PlayerId = "player-a",
Tick = 10,
MoveX = 1f,
MoveY = 0f
TurnInput = 0f,
ThrottleInput = 1f
}), PeerA);
createdTransports[9000].EmitReceive(BuildEnvelope(MessageType.MoveInput, new MoveInput
{
PlayerId = "player-a",
Tick = 8,
MoveX = 0f,
MoveY = 1f
TurnInput = 1f,
ThrottleInput = 0f
}), PeerA);
createdTransports[9000].EmitReceive(BuildEnvelope(MessageType.MoveInput, new MoveInput
{
PlayerId = "player-b",
Tick = 3,
MoveX = 0f,
MoveY = 1f
TurnInput = 0f,
ThrottleInput = -1f
}), PeerB);
runtime.DrainPendingMessagesAsync().GetAwaiter().GetResult();
@@ -66,8 +71,8 @@ namespace Tests.EditMode.Network
Assert.That(stateA.PositionZ, Is.EqualTo(0f).Within(0.0001f));
Assert.That(stateB.PlayerId, Is.EqualTo("player-b"));
Assert.That(stateB.LastAcceptedMoveTick, Is.EqualTo(3));
Assert.That(stateB.PositionX, Is.EqualTo(0f).Within(0.0001f));
Assert.That(stateB.PositionZ, Is.EqualTo(0.2f).Within(0.0001f));
Assert.That(stateB.PositionX, Is.EqualTo(-0.2f).Within(0.0001f));
Assert.That(stateB.PositionZ, Is.EqualTo(0f).Within(0.0001f));
Assert.That(createdTransports[9000].BroadcastMessages.Count, Is.EqualTo(2));
}
@@ -89,12 +94,15 @@ namespace Tests.EditMode.Network
using var runtime = ServerRuntimeEntryPoint.StartAsync(configuration).GetAwaiter().GetResult();
runtime.Host.NotifyLoginStarted(PeerA);
runtime.Host.NotifyLoginSucceeded(PeerA, "player-a");
createdTransports[9001].EmitReceive(BuildEnvelope(MessageType.MoveInput, new MoveInput
{
PlayerId = "player-a",
Tick = 1,
MoveX = 1f,
MoveY = 0f
TurnInput = 0f,
ThrottleInput = 1f
}), PeerA);
runtime.DrainPendingMessagesAsync().GetAwaiter().GetResult();
@@ -118,8 +126,8 @@ namespace Tests.EditMode.Network
{
PlayerId = "player-a",
Tick = 2,
MoveX = 0f,
MoveY = 0f
TurnInput = 0f,
ThrottleInput = 0f
}), PeerA);
runtime.DrainPendingMessagesAsync().GetAwaiter().GetResult();
@@ -164,7 +172,7 @@ namespace Tests.EditMode.Network
}), PeerA);
runtime.Host.NotifyLoginStarted(PeerA);
runtime.Host.NotifyLoginSucceeded(PeerA);
runtime.Host.NotifyLoginSucceeded(PeerA, "player-a");
runtime.UpdateAuthoritativeMovement(TimeSpan.FromMilliseconds(50));
Assert.That(runtime.TryGetAuthoritativeMovementState(PeerA, out var state), Is.True);
@@ -202,12 +210,15 @@ namespace Tests.EditMode.Network
using var runtime = ServerRuntimeEntryPoint.StartAsync(configuration).GetAwaiter().GetResult();
runtime.Host.NotifyLoginStarted(PeerA);
runtime.Host.NotifyLoginSucceeded(PeerA, "player-a");
createdTransports[9000].EmitReceive(BuildEnvelope(MessageType.MoveInput, new MoveInput
{
PlayerId = "player-a",
Tick = 5,
MoveX = 0f,
MoveY = -1f
TurnInput = 0f,
ThrottleInput = -1f
}), PeerA);
runtime.DrainPendingMessagesAsync().GetAwaiter().GetResult();
@@ -217,9 +228,9 @@ namespace Tests.EditMode.Network
var broadcast = ParsePlayerState(createdTransports[9000].BroadcastMessages[0]);
Assert.That(broadcast.Tick, Is.EqualTo(1));
Assert.That(broadcast.Position.X, Is.EqualTo(0f).Within(0.0001f));
Assert.That(broadcast.Position.Z, Is.EqualTo(-0.3f).Within(0.0001f));
Assert.That(broadcast.Velocity.Z, Is.EqualTo(-6f).Within(0.0001f));
Assert.That(broadcast.Position.X, Is.EqualTo(-0.3f).Within(0.0001f));
Assert.That(broadcast.Position.Z, Is.EqualTo(0f).Within(0.0001f));
Assert.That(broadcast.Velocity.X, Is.EqualTo(-6f).Within(0.0001f));
}
private static FakeTransport CreateTransport(IDictionary<int, FakeTransport> createdTransports, int port)
@@ -196,6 +196,10 @@ namespace Tests.EditMode.Network
host.StartAsync().GetAwaiter().GetResult();
transport.EmitReceive(CreateEnvelope(MessageType.Heartbeat), peerA);
transport.EmitReceive(CreateEnvelope(MessageType.Heartbeat), peerB);
host.NotifyLoginStarted(peerA);
host.NotifyLoginSucceeded(peerA, "player-a");
host.NotifyLoginStarted(peerB);
host.NotifyLoginSucceeded(peerB, "player-b");
var removed = host.RemoveSession(peerA, "peer closed");
@@ -203,7 +207,7 @@ namespace Tests.EditMode.Network
Assert.That(host.ManagedSessions.Count, Is.EqualTo(1));
Assert.That(host.TryGetSession(peerA, out _), Is.False);
Assert.That(host.TryGetSession(peerB, out var sessionB), Is.True);
Assert.That(sessionB.SessionManager.State, Is.EqualTo(ConnectionState.TransportConnected));
Assert.That(sessionB.SessionManager.State, Is.EqualTo(ConnectionState.LoggedIn));
}
[Test]
@@ -110,8 +110,8 @@ namespace Tests.EditMode.Network
{
PlayerId = "shared-player",
Tick = 33,
MoveX = 1f,
MoveY = -1f
TurnInput = 1f,
ThrottleInput = -1f
};
runtime.MessageManager.SendMessage(message, MessageType.MoveInput);
@@ -161,7 +161,7 @@ namespace Tests.EditMode.Network
{
PlayerId = "shared-player",
Tick = 77,
MoveX = 1f
ThrottleInput = 1f
};
runtime.MessageManager.SendMessage(moveInput, MessageType.MoveInput);
@@ -191,7 +191,7 @@ namespace Tests.EditMode.Network
{
PlayerId = "server-player",
Tick = 88,
MoveY = 1f
ThrottleInput = 1f
};
host.MessageManager.SendMessage(moveInput, MessageType.MoveInput);
@@ -215,7 +215,7 @@ namespace Tests.EditMode.Network
{
PlayerId = "fallback-player",
Tick = 99,
MoveX = -1f
TurnInput = -1f
};
host.MessageManager.SendMessage(moveInput, MessageType.MoveInput);
@@ -33,8 +33,8 @@ namespace Tests.EditMode.Network
Assert.That(stopInput, Is.Not.Null);
Assert.That(stopInput.PlayerId, Is.EqualTo("player-1"));
Assert.That(stopInput.Tick, Is.EqualTo(8));
Assert.That(stopInput.MoveX, Is.EqualTo(0f));
Assert.That(stopInput.MoveY, Is.EqualTo(0f));
Assert.That(stopInput.TurnInput, Is.EqualTo(0f));
Assert.That(stopInput.ThrottleInput, Is.EqualTo(0f));
Assert.That(continuedIdle, Is.False);
Assert.That(idleInput, Is.Null);
}
@@ -85,9 +85,9 @@ namespace Tests.EditMode.Network
public void ClientPredictionBuffer_AuthoritativeState_PrunesAcknowledgedMoveInputs()
{
var buffer = new ClientPredictionBuffer();
buffer.Record(new MoveInput { PlayerId = "player-1", Tick = 10, MoveX = 1f });
buffer.Record(new MoveInput { PlayerId = "player-1", Tick = 11, MoveX = 1f });
buffer.Record(new MoveInput { PlayerId = "player-1", Tick = 12, MoveX = 1f });
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 });
var accepted = buffer.TryApplyAuthoritativeState(
new PlayerState { PlayerId = "player-1", Tick = 11 },
@@ -104,7 +104,7 @@ namespace Tests.EditMode.Network
public void ClientPredictionBuffer_StaleAuthoritativeState_IsIgnored()
{
var buffer = new ClientPredictionBuffer();
buffer.Record(new MoveInput { PlayerId = "player-1", Tick = 10, MoveX = 1f });
buffer.Record(new MoveInput { PlayerId = "player-1", Tick = 10, ThrottleInput = 1f });
buffer.TryApplyAuthoritativeState(new PlayerState { PlayerId = "player-1", Tick = 10 }, out _);
var accepted = buffer.TryApplyAuthoritativeState(
@@ -139,7 +139,7 @@ namespace Tests.EditMode.Network
Assert.That(snapshot.Position, Is.EqualTo(new Vector3(5f, 0f, -3f)));
Assert.That(snapshot.Velocity, Is.EqualTo(new Vector3(1.5f, 0f, 0.25f)));
Assert.That(snapshot.Rotation, Is.EqualTo(90f));
Assert.That(snapshot.RotationQuaternion.eulerAngles.y, Is.EqualTo(90f).Within(0.01f));
Assert.That(snapshot.RotationQuaternion.eulerAngles.y, Is.EqualTo(0f).Within(0.01f));
Assert.That(snapshot.Hp, Is.EqualTo(73));
}
@@ -413,13 +413,13 @@ namespace Tests.EditMode.Network
});
transport.EmitReceive(
BuildEnvelope(MessageType.MoveInput, new MoveInput { PlayerId = "player-a", Tick = 5, MoveX = 1f }),
BuildEnvelope(MessageType.MoveInput, new MoveInput { PlayerId = "player-a", Tick = 5, ThrottleInput = 1f }),
peerA);
transport.EmitReceive(
BuildEnvelope(MessageType.MoveInput, new MoveInput { PlayerId = "player-a", Tick = 4, MoveX = -1f }),
BuildEnvelope(MessageType.MoveInput, new MoveInput { PlayerId = "player-a", Tick = 4, ThrottleInput = -1f }),
peerA);
transport.EmitReceive(
BuildEnvelope(MessageType.MoveInput, new MoveInput { PlayerId = "player-b", Tick = 4, MoveY = 1f }),
BuildEnvelope(MessageType.MoveInput, new MoveInput { PlayerId = "player-b", Tick = 4, TurnInput = 1f }),
peerB);
Assert.That(handledTicksByPeer[peerA.ToString()], Is.EqualTo(new long[] { 5 }));