netcode progress, improved handling of missing frames
This commit is contained in:
@@ -74,6 +74,7 @@ public struct PlayerMovementState
|
||||
public int numJumps;
|
||||
public bool jumped;
|
||||
public bool onGround;
|
||||
public ulong frame;
|
||||
|
||||
|
||||
public PlayerMovementState()
|
||||
@@ -250,9 +251,20 @@ public class PlayerMovement : Script
|
||||
viewAnglesLastFrame = viewAngles;
|
||||
}
|
||||
|
||||
private static int framedropped = 0;
|
||||
public override void OnUpdate()
|
||||
{
|
||||
Console.Print("playerMovement OnUpdate");
|
||||
if (World.IsServer && Mathf.Abs(Time.DeltaTime - (1.0f / Time.UpdateFPS)) > (1.0f / Time.UpdateFPS) * 0.999f)
|
||||
{
|
||||
Console.Print($"drop: {Time.DeltaTime*1000.0f}ms");
|
||||
framedropped = 3;
|
||||
}
|
||||
else if (World.IsServer && framedropped > 0)
|
||||
{
|
||||
Console.Print("dropping...");
|
||||
framedropped--;
|
||||
}
|
||||
//Console.Print($"{(World.IsClient ? "[cl] " : "[sv] ") + World.Frame.ToString()} playerMovement OnUpdate");
|
||||
//input.OnUpdate();
|
||||
|
||||
|
||||
@@ -315,7 +327,7 @@ public class PlayerMovement : Script
|
||||
|
||||
public override void OnFixedUpdate()
|
||||
{
|
||||
Console.Print("playerMovement OnFixedUpdate");
|
||||
//Console.Print($"{(World.IsClient ? "[cl] " : "[sv] ") + World.Frame.ToString()} playerMovement OnFixedUpdate");
|
||||
float timeDeltaDiff = Time.DeltaTime - 1.0f / Time.PhysicsFPS;
|
||||
if (Time.PhysicsFPS > 0 && Math.Abs(timeDeltaDiff) > 0.0001f)
|
||||
Console.Print("Time.DeltaTime is not stable: " + timeDeltaDiff);
|
||||
@@ -413,13 +425,93 @@ public class PlayerMovement : Script
|
||||
}
|
||||
}
|
||||
|
||||
if (!predict)
|
||||
if (World.IsServer)
|
||||
{
|
||||
ulong currentFrame = World.GetLastProcessedFrame(PlayerId);
|
||||
{
|
||||
// Rewind to last confirmed state
|
||||
var frameInfo = World.GetPlayerFrame(PlayerId, currentFrame);
|
||||
if (frameInfo != null && frameInfo.movementState.frame == currentFrame)
|
||||
{
|
||||
// Reset all state to latest confirmed state from server
|
||||
movementState.position = frameInfo.movementState.position;
|
||||
movementState.currentVelocity = frameInfo.movementState.currentVelocity;
|
||||
movementState.lastJumped = frameInfo.movementState.lastJumped;
|
||||
movementState.numJumps = frameInfo.movementState.numJumps;
|
||||
movementState.jumped = frameInfo.movementState.jumped;
|
||||
Actor.Position = movementState.position;
|
||||
SetCameraEulerAngles(frameInfo.movementState.viewAngles, true);
|
||||
//ApplyInputToCamera(frameInfo.inputState, true);
|
||||
}
|
||||
else if (frameInfo == null)
|
||||
{
|
||||
// First frame, update the known state
|
||||
movementState.viewAngles = viewAngles;
|
||||
World.UpdatePlayerState(PlayerId, currentFrame, movementState);
|
||||
}
|
||||
currentFrame++;
|
||||
}
|
||||
|
||||
//Console.Print("before:" + viewAngles.ToString());
|
||||
|
||||
ulong lastFrame = World.GetLastReceivedFrame(PlayerId);
|
||||
PlayerFrame lastFrameInfo = null;
|
||||
for (; currentFrame < lastFrame+1; currentFrame++)
|
||||
{
|
||||
var frameInfo = World.GetPlayerFrame(PlayerId, currentFrame);
|
||||
if (frameInfo == null || frameInfo.inputState.Frame != currentFrame)
|
||||
//if (!Input.GetState(currentFrame, out var pastInputState, out var pastActorState))
|
||||
{
|
||||
Console.Print($"frame {currentFrame} missing");
|
||||
frameInfo = lastFrameInfo; // Use last known input
|
||||
|
||||
if (frameInfo == null)
|
||||
{
|
||||
// FIXME
|
||||
frameInfo = new PlayerFrame()
|
||||
{
|
||||
inputState =
|
||||
{
|
||||
Frame = currentFrame,
|
||||
},
|
||||
movementState = movementState,
|
||||
};
|
||||
frameInfo.movementState.frame = currentFrame;
|
||||
}
|
||||
//continue;
|
||||
//Console.Print($"not predicting");
|
||||
//predict = false;
|
||||
//break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Input.SetFrame(currentFrame);
|
||||
Input.UpdateState();
|
||||
|
||||
ApplyInputToCamera(frameInfo.inputState, true);
|
||||
lastFrameInfo = frameInfo;
|
||||
}
|
||||
SimulatePlayerMovement(frameInfo.inputState, currentFrame);
|
||||
movementState.viewAngles = viewAngles;
|
||||
|
||||
//Console.Print("tick: " + viewAngles.ToString());
|
||||
|
||||
//if (frameInfo.movementState.frame != currentFrame)
|
||||
World.UpdatePlayerState(PlayerId, currentFrame, movementState);
|
||||
//else
|
||||
// currentFrame = currentFrame;
|
||||
}
|
||||
}
|
||||
else if (!predict)
|
||||
{
|
||||
SetCameraEulerAngles(viewAnglesLastFrame, true);
|
||||
ApplyInputToCamera(inputState, true);
|
||||
SimulatePlayerMovement(inputState, World.Frame); // MAYBE?
|
||||
}
|
||||
|
||||
//if (!movementState.currentVelocity.IsZero)
|
||||
// Console.Print($"{(World.IsClient ? "client" : "server")} {World.Frame} vel: {movementState.currentVelocity}, pos: {movementState.position}");
|
||||
|
||||
viewAnglesLastFrame = viewAngles;
|
||||
|
||||
#if false
|
||||
|
||||
Reference in New Issue
Block a user