netcode good condition
This commit is contained in:
@@ -86,17 +86,17 @@ namespace Game
|
||||
//public int currentInputFrame;
|
||||
//private int currentInputFrame2;
|
||||
|
||||
private Float3 currentVelocity;
|
||||
public Float3 currentVelocity;
|
||||
public PlayerInput input;
|
||||
|
||||
//private bool physicsInteractions = false;
|
||||
|
||||
private bool jumped;
|
||||
public bool jumped;
|
||||
|
||||
//private int lastInputFrame;
|
||||
private float lastJumped = -1f;
|
||||
public float lastJumped = -1f;
|
||||
private float lastLanded = -1f;
|
||||
private int numJumps;
|
||||
public int numJumps;
|
||||
private float simulationTime = 0f;
|
||||
|
||||
[ReadOnly] public bool onGround;
|
||||
@@ -104,8 +104,7 @@ namespace Game
|
||||
private Actor cameraHolder;
|
||||
|
||||
private PlayerActor playerActor;
|
||||
private Actor rootActor;
|
||||
private float startupTime;
|
||||
public Actor rootActor;
|
||||
|
||||
public Float3 viewAngles;
|
||||
private Float3 viewAnglesLastFrame;
|
||||
@@ -164,8 +163,6 @@ namespace Game
|
||||
//rigidBody.CollisionEnter += OnCollisionEnter;
|
||||
//rigidBody.TriggerEnter += OnTriggerEnter;
|
||||
//rigidBody.TriggerExit += OnTriggerExit;
|
||||
|
||||
startupTime = Time.TimeSinceStartup;
|
||||
}
|
||||
|
||||
public void SetInput(uint playerId)
|
||||
@@ -279,23 +276,31 @@ namespace Game
|
||||
viewRoll = actorState.viewRoll;
|
||||
}*/
|
||||
|
||||
PlayerInputState inputState = input.GetCurrentInputState();
|
||||
|
||||
//if (inputState.viewDeltaX != 0 || inputState.viewDeltaY != 0)
|
||||
// inputState = inputState;
|
||||
|
||||
viewAngles = viewAnglesLastFrame;
|
||||
ApplyInputToCamera(inputState);
|
||||
|
||||
input.RecordCurrentActorState(new PlayerActorState
|
||||
if (input is not PlayerInputNetwork)
|
||||
{
|
||||
position = Actor.Position,
|
||||
velocity = currentVelocity,
|
||||
orientation = rootActor.Orientation,
|
||||
viewAngles = viewAngles,
|
||||
lastJumpTime = lastJumped,
|
||||
//viewAngles = new Float3(viewAngles.Y, viewAngles.X, viewAngles.Z)
|
||||
});
|
||||
|
||||
PlayerInputState inputState = input.GetCurrentInputState();
|
||||
|
||||
//if (inputState.viewDeltaX != 0 || inputState.viewDeltaY != 0)
|
||||
// inputState = inputState;
|
||||
|
||||
|
||||
ApplyInputToCamera(inputState);
|
||||
|
||||
input.RecordCurrentActorState(new PlayerActorState
|
||||
{
|
||||
position = Actor.Position,
|
||||
velocity = currentVelocity,
|
||||
orientation = rootActor.Orientation,
|
||||
viewAngles = viewAngles,
|
||||
lastJumpTime = lastJumped,
|
||||
numJumps = numJumps,
|
||||
jumped = jumped,
|
||||
//viewAngles = new Float3(viewAngles.Y, viewAngles.X, viewAngles.Z)
|
||||
});
|
||||
}
|
||||
|
||||
/*input.RecordCurrentActorState(new PlayerActorState()
|
||||
{
|
||||
@@ -372,6 +377,106 @@ namespace Game
|
||||
}*/
|
||||
}
|
||||
}
|
||||
else if (input is PlayerInputNetwork)
|
||||
{
|
||||
#if false
|
||||
bool canpredict = true;
|
||||
if (false && input.Predict && GameModeManager.ClientFrame > 0 && GameModeManager.ServerFrame > 0)
|
||||
{
|
||||
ulong maxFrame = /*NetworkManager.IsServer ? GameModeManager.playerLastReceivedFrames[PlayerId] :*/ GameModeManager.ClientFrame;
|
||||
ulong currentFrame = GameModeManager.ServerFrame;
|
||||
for (; currentFrame <= maxFrame; currentFrame++)
|
||||
{
|
||||
if (!input.GetState(currentFrame, out var pastInputState, out var pastActorState))
|
||||
{
|
||||
//Console.Print($"not predicting");
|
||||
//canpredict = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ulong lastFrame = currentFrame;
|
||||
if (input is PlayerInputNetwork)
|
||||
{
|
||||
//canpredict = true;
|
||||
//lastFrame = GameModeManager.ServerFrame+1;
|
||||
}
|
||||
|
||||
predicting = true;
|
||||
currentFrame = GameModeManager.ServerFrame;
|
||||
for (; currentFrame < lastFrame; currentFrame++)
|
||||
{
|
||||
if (!input.GetState(currentFrame, out var pastInputState, out var pastActorState))
|
||||
{
|
||||
Console.Print($"unexpected predict failure: {currentFrame}");
|
||||
break;
|
||||
}
|
||||
|
||||
if (currentFrame == inputState.frame)
|
||||
jumped = jumped;
|
||||
|
||||
if (currentFrame == GameModeManager.ServerFrame)
|
||||
{
|
||||
Actor.Position = pastActorState.position;
|
||||
currentVelocity = pastActorState.velocity;
|
||||
lastJumped = pastActorState.lastJumpTime;
|
||||
numJumps = pastActorState.numJumps;
|
||||
jumped = pastActorState.jumped;
|
||||
SetCameraEulerAngles(pastActorState.viewAngles, true);
|
||||
|
||||
if (Actor.Position.Length < 0.1)
|
||||
jumped = jumped;
|
||||
|
||||
continue;
|
||||
//rootActor.Orientation = pastActorState.orientation;
|
||||
//viewAngles = pastActorState.viewAngles;
|
||||
//viewAngles = new Float3(pastActorState.viewAngles.Y, pastActorState.viewAngles.X, pastActorState.viewAngles.Z);
|
||||
}
|
||||
else
|
||||
ApplyInputToCamera(pastInputState, true);
|
||||
//SetCameraEulerAngles(pastActorState.viewAngles, true);
|
||||
|
||||
//if (currentVelocity.Length > 0)
|
||||
// currentVelocity = currentVelocity;
|
||||
|
||||
//else
|
||||
// ApplyInputToCamera(pastInputState, true);
|
||||
SimulatePlayerMovement(pastInputState);
|
||||
|
||||
break;
|
||||
|
||||
/*if ((Actor.Position - pastActorState.position).Length > 0.001)
|
||||
Console.Print($"mispredicted position");
|
||||
if ((currentVelocity - pastActorState.velocity).Length > 0.001)
|
||||
Console.Print($"mispredicted velocity");
|
||||
if ((viewAngles - pastActorState.viewAngles).Length > 0.001)
|
||||
Console.Print($"mispredicted viewangles: {viewAngles - oldAngles}");*/
|
||||
|
||||
//Console.Print($"predicted: {currentFrame}");
|
||||
}
|
||||
|
||||
/*if (input is PlayerInputNetwork)
|
||||
{
|
||||
currentFrame = lastFrame - 1;
|
||||
if (input.GetState(currentFrame, out var lastInputState, out var lastActorState))
|
||||
{
|
||||
for (; currentFrame < GameModeManager.ClientFrame; currentFrame++)
|
||||
{
|
||||
ApplyInputToCamera(lastInputState, true);
|
||||
SimulatePlayerMovement(lastInputState);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
predicting = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//ApplyInputToCamera(inputState, true);
|
||||
//SimulatePlayerMovement(inputState);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Actor.Position.Length < 0.1)
|
||||
@@ -379,41 +484,59 @@ namespace Game
|
||||
|
||||
//viewAngles = viewAnglesLastFrame;
|
||||
//ApplyInputToCamera(inputState);
|
||||
var oldAngles = viewAngles;
|
||||
|
||||
//viewAngles = viewAnglesLastFrame;
|
||||
bool canpredict = true;
|
||||
if (true && input.Predict && GameModeManager.ClientFrame > 0 && GameModeManager.ServerFrame > 0)
|
||||
{
|
||||
for (ulong currentFrame = GameModeManager.ServerFrame; currentFrame < GameModeManager.ClientFrame; currentFrame++)
|
||||
ulong currentFrame = GameModeManager.ServerFrame;
|
||||
for (; currentFrame < GameModeManager.ClientFrame; currentFrame++)
|
||||
{
|
||||
if (!input.GetState(currentFrame, out var pastInputState, out var pastActorState))
|
||||
{
|
||||
Console.Print($"not predicting");
|
||||
//Console.Print($"not predicting");
|
||||
canpredict = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ulong lastFrame = currentFrame;
|
||||
|
||||
|
||||
if (canpredict)
|
||||
{
|
||||
//var oldPos = Actor.Position;
|
||||
//var oldVel = currentVelocity;
|
||||
{
|
||||
var oldAngles = viewAngles;
|
||||
var oldPos = Actor.Position;
|
||||
var oldVel = currentVelocity;
|
||||
|
||||
|
||||
|
||||
predicting = true;
|
||||
for (ulong currentFrame = GameModeManager.ServerFrame; currentFrame < GameModeManager.ClientFrame; currentFrame++)
|
||||
currentFrame = GameModeManager.ServerFrame;
|
||||
for (; currentFrame < lastFrame; currentFrame++)
|
||||
{
|
||||
if (!input.GetState(currentFrame, out var pastInputState, out var pastActorState))
|
||||
{
|
||||
Console.Print($"predict failure: {currentFrame}");
|
||||
Console.Print($"unexpected predict failure: {currentFrame}");
|
||||
break;
|
||||
}
|
||||
|
||||
if (currentFrame == inputState.frame)
|
||||
jumped = jumped;
|
||||
|
||||
if (currentFrame == GameModeManager.ServerFrame)
|
||||
{
|
||||
Actor.Position = pastActorState.position;
|
||||
currentVelocity = pastActorState.velocity;
|
||||
lastJumped = pastActorState.lastJumpTime;
|
||||
numJumps = pastActorState.numJumps;
|
||||
jumped = pastActorState.jumped;
|
||||
SetCameraEulerAngles(pastActorState.viewAngles, true);
|
||||
//cameraHolder.Orientation = Quaternion.Euler(pastActorState.viewAngles.Y, pastActorState.viewAngles.X, pastActorState.viewAngles.Z);
|
||||
//ApplyInputToCamera(pastInputState, true);
|
||||
|
||||
//if (pastActorState.viewAngles != new Float3(90f, 0f, 0f))
|
||||
// Console.Print($"moved server frame: {currentFrame}, {pastActorState.viewAngles}");
|
||||
|
||||
if (Actor.Position.Length < 0.1)
|
||||
jumped = jumped;
|
||||
@@ -434,35 +557,45 @@ namespace Game
|
||||
// ApplyInputToCamera(pastInputState, true);
|
||||
SimulatePlayerMovement(pastInputState);
|
||||
|
||||
if ((Actor.Position - pastActorState.position).Length > 0.001)
|
||||
/*if ((Actor.Position - pastActorState.position).Length > 0.001)
|
||||
Console.Print($"mispredicted position");
|
||||
if ((currentVelocity - pastActorState.velocity).Length > 0.001)
|
||||
Console.Print($"mispredicted velocity");
|
||||
if ((viewAngles - pastActorState.viewAngles).Length > 0.001)
|
||||
Console.Print($"mispredicted viewangles: {viewAngles - oldAngles}");
|
||||
Console.Print($"mispredicted viewangles: {viewAngles - oldAngles}");*/
|
||||
|
||||
//Console.Print($"predicted: {currentFrame}");
|
||||
}
|
||||
|
||||
predicting = false;
|
||||
|
||||
/*if ((Actor.Position - oldPos).Length > 0.001)
|
||||
if ((Actor.Position - oldPos).Length > 0.001)
|
||||
Console.Print($"mispredicted final position");
|
||||
if ((currentVelocity - oldVel).Length > 0.001)
|
||||
Console.Print($"mispredicted final velocity");*/
|
||||
Console.Print($"mispredicted final velocity");
|
||||
|
||||
ApplyInputToCamera(inputState, true);
|
||||
|
||||
// Ensure orientation is always up-to-date after predicting
|
||||
//rootActor.Orientation = Quaternion.Euler(0, viewAngles.X, 0);
|
||||
cameraHolder.Orientation = Quaternion.Euler(viewAngles.Y, viewAngles.X, viewAngles.Z);
|
||||
//if (input is not PlayerInputNetwork)
|
||||
{
|
||||
/*if ((Actor.Position - oldPos).Length > 0.001)
|
||||
Console.Print($"mispredicted final position");
|
||||
if ((currentVelocity - oldVel).Length > 0.001)
|
||||
Console.Print($"mispredicted final velocity");*/
|
||||
|
||||
SimulatePlayerMovement(inputState);
|
||||
ApplyInputToCamera(inputState, true);
|
||||
|
||||
// Ensure orientation is always up-to-date after predicting
|
||||
//rootActor.Orientation = Quaternion.Euler(0, viewAngles.X, 0);
|
||||
cameraHolder.Orientation = Quaternion.Euler(viewAngles.Y, viewAngles.X, viewAngles.Z);
|
||||
|
||||
SimulatePlayerMovement(inputState);
|
||||
}
|
||||
|
||||
if ((viewAngles - oldAngles).Length > 0.001)
|
||||
Console.Print($"mispredicted final viewangles: {viewAngles - oldAngles}");
|
||||
Console.Print($"mispredicted final viewangles: {viewAngles} <- {oldAngles}");
|
||||
|
||||
|
||||
//if (viewAngles != new Float3(90f, 0f, 0f))
|
||||
// Console.Print($"moved client frame: {GameModeManager.ClientFrame}, {viewAngles}");
|
||||
|
||||
//Console.Print($"current: {inputState.frame}");
|
||||
//if (GameModeManager.ClientFrame - GameModeManager.ServerFrame > 0)
|
||||
@@ -474,7 +607,6 @@ namespace Game
|
||||
|
||||
if (!canpredict)
|
||||
{
|
||||
|
||||
SetCameraEulerAngles(viewAnglesLastFrame, true);
|
||||
ApplyInputToCamera(inputState, true);
|
||||
SimulatePlayerMovement(inputState);
|
||||
@@ -503,21 +635,30 @@ namespace Game
|
||||
//SetCameraEulerAngles(new Float3(pastActorState.viewAngles.Y, pastActorState.viewAngles.X, pastActorState.viewAngles.Z), true);
|
||||
//SetCameraEulerAngles(new Float3(viewAnglesLastFrame.Y, viewAnglesLastFrame.X, viewAnglesLastFrame.Z), true);
|
||||
//SimulatePlayerMovement(inputState);
|
||||
|
||||
input.RecordCurrentActorState(new PlayerActorState
|
||||
{
|
||||
position = Actor.Position,
|
||||
velocity = currentVelocity,
|
||||
orientation = rootActor.Orientation,
|
||||
viewAngles = viewAngles,
|
||||
lastJumpTime = lastJumped,
|
||||
numJumps = numJumps,
|
||||
jumped = jumped,
|
||||
//viewAngles = new Float3(viewAngles.Y, viewAngles.X, viewAngles.Z)
|
||||
});
|
||||
|
||||
//Console.Print($"recording frame {input.frame}, client: {GameModeManager.ClientFrame}, server: {GameModeManager.ServerFrame}");
|
||||
input.OnEndFrame();
|
||||
}
|
||||
|
||||
if (Actor.Position.Length < 0.1)
|
||||
jumped = jumped;
|
||||
|
||||
input.RecordCurrentActorState(new PlayerActorState
|
||||
{
|
||||
position = Actor.Position,
|
||||
velocity = currentVelocity,
|
||||
orientation = rootActor.Orientation,
|
||||
viewAngles = viewAngles,
|
||||
lastJumpTime = lastJumped,
|
||||
//viewAngles = new Float3(viewAngles.Y, viewAngles.X, viewAngles.Z)
|
||||
});
|
||||
input.OnEndFrame();
|
||||
if (input is PlayerInputNetwork)
|
||||
jumped = jumped;
|
||||
|
||||
|
||||
|
||||
|
||||
//lastInputFrame = currentInputFrame;
|
||||
@@ -533,7 +674,7 @@ namespace Game
|
||||
}*/
|
||||
}
|
||||
|
||||
private void ApplyInputToCamera(PlayerInputState inputState, bool wrapAround = true)
|
||||
public void ApplyInputToCamera(PlayerInputState inputState, bool wrapAround = true)
|
||||
{
|
||||
if (inputState.viewDeltaX == 0.0f && inputState.viewDeltaY == 0.0f)
|
||||
return;
|
||||
@@ -543,7 +684,7 @@ namespace Game
|
||||
SetCameraEulerAngles(new Float3(viewYaw, viewPitch, viewAngles.Z), wrapAround);
|
||||
}
|
||||
|
||||
private void SetCameraEulerAngles(Float3 angles, bool wrapAround = true)
|
||||
public void SetCameraEulerAngles(Float3 angles, bool wrapAround = true)
|
||||
{
|
||||
if (viewAngles == angles)
|
||||
return;
|
||||
@@ -785,7 +926,40 @@ namespace Game
|
||||
}
|
||||
else if (boxCollider && boxCollider.IsActive)
|
||||
{
|
||||
DebugDraw.DrawWireBox(boxCollider.OrientedBox.GetBoundingBox(), Color.GreenYellow * 0.8f);
|
||||
var clientBbox = boxCollider.OrientedBox.GetBoundingBox();
|
||||
|
||||
if (false)
|
||||
{
|
||||
if (GameModeManager.ServerFrame > 0 && GameModeManager.ClientFrame > 0)
|
||||
for (ulong frame = GameModeManager.ServerFrame; frame < GameModeManager.ClientFrame; frame++)
|
||||
{
|
||||
if (!input.GetState(frame, out var pastInputState, out var pastActorState))
|
||||
continue;
|
||||
|
||||
var bbox = clientBbox;
|
||||
bbox.Center = pastActorState.position;
|
||||
|
||||
Float4 color1 = new Float4(Color.Red.R, Color.Red.G, Color.Red.B, Color.Red.A);
|
||||
Float4 color2 = new Float4(Color.Blue.R, Color.Blue.G, Color.Blue.B, Color.Blue.A);
|
||||
Float4 color3 = Float4.Lerp(color1, color2, (float)(frame - GameModeManager.ServerFrame) / (float)(GameModeManager.ClientFrame - GameModeManager.ServerFrame));
|
||||
Color color = new Color(color3.X, color3.Y, color3.Z, color3.W);
|
||||
DebugDraw.DrawBox(bbox, color * 1f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var serverBbox = boxCollider.OrientedBox.GetBoundingBox();
|
||||
if (input.GetState(GameModeManager.ServerFrame, out var serverInputState, out var serverActorState))
|
||||
serverBbox.Center = serverActorState.position;
|
||||
|
||||
if (serverBbox.Center == clientBbox.Center)
|
||||
DebugDraw.DrawBox(clientBbox, Color.Magenta * 0.6f);
|
||||
else
|
||||
{
|
||||
DebugDraw.DrawBox(serverBbox, Color.Red * 0.6f);
|
||||
DebugDraw.DrawBox(clientBbox, Color.Blue * 0.6f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1051,6 +1225,7 @@ namespace Game
|
||||
if (onGround && jumpAction && !jumped)
|
||||
if (OnJump(traceGround, ref position, ref velocity))
|
||||
{
|
||||
//Console.Print($"{inputState.frame} jumped " + ", predicting: " + predicting + ", vel: " + velocity.Y);
|
||||
jumped = true;
|
||||
lastJumped = simulationTime;
|
||||
numJumps++;
|
||||
|
||||
Reference in New Issue
Block a user