feat(client): consumir yaw do snapshot quantizado v3 (Etapa 7)
Etapa 7 do refactor de networking server-side bumpou o protocolo para v3 e passou a enviar yaw no S_PLAYER_STATE (campo novo no payload). Cliente agora consome esse yaw via TryGetLastPlayerStateExtended do plugin ZeusNetwork (cache local com YawDeg + Flags). Antes (v2): - S_PLAYER_STATE nao tinha yaw. Comentario do codigo dizia exatamente "Yaw nao chega no opcode S_PLAYER_STATE actual; derivamos do XY da velocidade quando significativo, caso contrario mantemos rotacao do ator." Resultado: proxy parado nao girava, e proxy em movimento ficava com yaw inferido (impreciso quando vel pequena). Depois (v3): - HandlePlayerStateUpdate consulta TryGetLastPlayerStateExtended para pegar YawDeg + Flags do cache do plugin (populado pelo parser v3). - Se PSF_HasYaw esta set, usa o YawDeg autoritativo do servidor. - Caso contrario, fallback antigo (atan2 da vel ou rotacao do ator), preservando comportamento se algum dia o flag vier desligado. Validacao runtime (~5 min, 2 clients UE conectados ao server v3): - Connected sessionId=1 e =2 (handshake v3 OK). - parseRej=0 no servidor (cliente fala v3). - Proxies giram conforme yaw autoritativo (visual; nao tem metrica numerica para isso). Depende de: - ZeusNetwork plugin v3 (commit 3b97500 no repo ZeusServerEngine). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -195,15 +195,45 @@ void UZMMOWorldSubsystem::HandlePlayerStateUpdate(const int32 EntityId, const in
|
|||||||
Snapshot.LastProcessedInputSeq = InputSeq;
|
Snapshot.LastProcessedInputSeq = InputSeq;
|
||||||
Snapshot.PositionCm = PosCm;
|
Snapshot.PositionCm = PosCm;
|
||||||
Snapshot.VelocityCmS = VelCmS;
|
Snapshot.VelocityCmS = VelCmS;
|
||||||
// Yaw nao chega no opcode S_PLAYER_STATE actual; derivamos do XY da
|
|
||||||
// velocidade quando significativo, caso contrario mantemos rotacao do ator.
|
// Etapa 7 (server-side networking refactor): yaw agora chega no
|
||||||
if (!FVector(VelCmS.X, VelCmS.Y, 0.0f).IsNearlyZero(1.0f))
|
// snapshot quantizado v3. Buscamos via TryGetLastPlayerStateExtended
|
||||||
|
// (cache local do plugin). Se PSF_HasYaw nao estiver set ou se o cache
|
||||||
|
// nao tiver entrada, caimos no fallback antigo (derivar do XY da
|
||||||
|
// velocidade ou manter rotacao do ator).
|
||||||
|
bool bYawFromSnapshot = false;
|
||||||
|
if (UZeusNetworkSubsystem* ZeusNet = ResolveZeusNetworkSubsystem())
|
||||||
{
|
{
|
||||||
Snapshot.YawDeg = FMath::RadiansToDegrees(FMath::Atan2(VelCmS.Y, VelCmS.X));
|
int32 CachedInputSeq = 0;
|
||||||
|
FVector CachedPos = FVector::ZeroVector;
|
||||||
|
FVector CachedVel = FVector::ZeroVector;
|
||||||
|
float CachedYawDeg = 0.f;
|
||||||
|
int32 CachedFlags = 0;
|
||||||
|
int64 CachedServerTimeMs = 0;
|
||||||
|
if (ZeusNet->TryGetLastPlayerStateExtended(
|
||||||
|
EntityId, CachedInputSeq, CachedPos, CachedVel,
|
||||||
|
CachedYawDeg, CachedFlags, CachedServerTimeMs))
|
||||||
|
{
|
||||||
|
constexpr int32 PSF_HasYaw = 1 << 5;
|
||||||
|
if ((CachedFlags & PSF_HasYaw) != 0)
|
||||||
|
{
|
||||||
|
Snapshot.YawDeg = CachedYawDeg;
|
||||||
|
bYawFromSnapshot = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
if (!bYawFromSnapshot)
|
||||||
{
|
{
|
||||||
Snapshot.YawDeg = Actor->GetActorRotation().Yaw;
|
// Fallback: deriva yaw do XY da velocidade quando significativo;
|
||||||
|
// caso contrario mantem rotacao do ator (comportamento pre-Etapa 7).
|
||||||
|
if (!FVector(VelCmS.X, VelCmS.Y, 0.0f).IsNearlyZero(1.0f))
|
||||||
|
{
|
||||||
|
Snapshot.YawDeg = FMath::RadiansToDegrees(FMath::Atan2(VelCmS.Y, VelCmS.X));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Snapshot.YawDeg = Actor->GetActorRotation().Yaw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Snapshot.bGrounded = bGrounded;
|
Snapshot.bGrounded = bGrounded;
|
||||||
Snapshot.ServerTimeMs = ServerTimeMs;
|
Snapshot.ServerTimeMs = ServerTimeMs;
|
||||||
|
|||||||
Reference in New Issue
Block a user