_playerinput refactor wip

This commit is contained in:
2025-03-19 23:00:03 +02:00
parent e564cf36a8
commit 294138eac4
6 changed files with 251 additions and 114 deletions

View File

@@ -41,10 +41,12 @@ public class WorldStateManager
}
}
private class PlayerFrame
public class PlayerFrame
{
public ulong frame;
public Float3 position;
public PlayerInputState2 inputState;
public PlayerMovementState movementState;
}
private Dictionary<uint, PlayerActor> players;
@@ -62,6 +64,7 @@ public class WorldStateManager
private ulong lastReceivedServerFrame = 0;
public ulong ServerFrame => /*NetworkManager.server != null ? serverWorldState.frame :*/ lastReceivedServerFrame;
public ulong ClientFrame => clientWorldState.frame;
public ulong Frame => IsServer ? serverWorldState.frame : clientWorldState.frame;
public float ServerTime = 0f;
public float ClientTime = 0f;
@@ -193,18 +196,42 @@ public class WorldStateManager
}
}
private PlayerFrame GetPlayerFrame(uint playerIndex, ulong playerFrameIndex)
public PlayerFrame GetPlayerFrame(uint playerIndex, ulong frame)
{
WorldState worldState = NetworkManager.server != null ? serverWorldState : clientWorldState;
PlayerFrame[] playerFrames = worldState.playerFrameHistory[playerIndex];
PlayerFrame playerFrame = playerFrames[playerFrameIndex % 120];
PlayerFrame playerFrame = playerFrames[frame % 120];
if (playerFrame.frame != playerFrameIndex)
if (playerFrame.frame != frame)
return null;
return playerFrame;
}
public bool HasPlayerFrame(uint playerIndex, ulong frame)
{
return GetPlayerFrame(playerIndex, frame) != null;
}
public bool GetPlayerInputState(uint playerIndex, ulong frame, out PlayerInputState2 inputState)
{
PlayerFrame frameInfo = GetPlayerFrame(playerIndex, frame);
inputState = frameInfo?.inputState ?? default;
return frameInfo != null;
}
public void RecordPlayerInput(uint playerIndex, ulong frame, PlayerInputState2 inputState, PlayerMovementState movementState)
{
WorldState worldState = NetworkManager.server != null ? serverWorldState : clientWorldState;
PlayerFrame[] playerFrames = worldState.playerFrameHistory[playerIndex];
PlayerFrame playerFrame = playerFrames[frame % 120];
playerFrame.frame = frame;
playerFrame.inputState = inputState;
playerFrame.movementState = movementState;
Console.Print($"recorded frame {frame}, client: {IsClient || IsLocalClient}");
}
public void OnLevelLoaded(Scene scene, Guid assetGuid)
{
serverWorldState.frame = 0;
@@ -243,8 +270,8 @@ public class WorldStateManager
playerFrame.frame = serverWorldState.frame;
//playerFrame.position = playerActor.Position;
PlayerMovement playerMovement = playerActor.GetScript<PlayerMovement>();
playerMovement.input.GetState(serverWorldState.frame, out var inputState, out var actorState);
playerFrame.position = actorState.position;
//playerMovement.Input.GetState(serverWorldState.frame, out var inputState, out var actorState);
playerFrame.position = playerMovement.movementState.position;
}
foreach (KeyValuePair<uint, PlayerActor> kv in players)
@@ -264,9 +291,12 @@ public class WorldStateManager
//PlayerActorState actorState = playerMovement.input.GetCurrentActorState();
//PlayerInputState inputState = playerMovement.input.GetCurrentInputState();
var playerFrame = playerLastFrame[playerId];
if (!playerMovement.input.GetState(playerFrame, out var inputState, out var actorState))
var frameInfo = GetPlayerFrame(playerId, playerFrame);
//if (!playerMovement.Input.GetState(playerFrame, out var inputState, out var actorState))
if (frameInfo == null)
{
//Console.Print("send input failure to client");
Console.Print("send input failure to client");
continue;
}
{
@@ -274,30 +304,30 @@ public class WorldStateManager
message.WriteByte((byte)GameModeMessageType.PlayerPosition);
message.WriteUInt64(playerFrame);
message.WriteUInt32(kv2.Key);
message.WriteSingle(actorState.position.X);
message.WriteSingle(actorState.position.Y);
message.WriteSingle(actorState.position.Z);
message.WriteSingle(actorState.velocity.X);
message.WriteSingle(actorState.velocity.Y);
message.WriteSingle(actorState.velocity.Z);
message.WriteSingle(actorState.orientation.X);
message.WriteSingle(actorState.orientation.Y);
message.WriteSingle(actorState.orientation.Z);
message.WriteSingle(actorState.orientation.W);
message.WriteSingle(actorState.viewAngles.X);
message.WriteSingle(actorState.viewAngles.Y);
message.WriteSingle(actorState.viewAngles.Z);
message.WriteSingle(actorState.lastJumpTime);
message.WriteInt32(actorState.numJumps);
message.WriteBoolean(actorState.jumped);
message.WriteSingle(frameInfo.movementState.position.X);
message.WriteSingle(frameInfo.movementState.position.Y);
message.WriteSingle(frameInfo.movementState.position.Z);
message.WriteSingle(frameInfo.movementState.currentVelocity.X);
message.WriteSingle(frameInfo.movementState.currentVelocity.Y);
message.WriteSingle(frameInfo.movementState.currentVelocity.Z);
//message.WriteSingle(frameInfo.movementState.orientation.X);
//message.WriteSingle(frameInfo.movementState.orientation.Y);
//message.WriteSingle(frameInfo.movementState.orientation.Z);
//message.WriteSingle(frameInfo.movementState.orientation.W);
message.WriteSingle(frameInfo.movementState.viewAngles.X);
message.WriteSingle(frameInfo.movementState.viewAngles.Y);
message.WriteSingle(frameInfo.movementState.viewAngles.Z);
message.WriteSingle(frameInfo.movementState.lastJumped);
message.WriteInt32(frameInfo.movementState.numJumps);
message.WriteBoolean(frameInfo.movementState.jumped);
//inputState.frame
message.WriteSingle(inputState.viewDeltaX);
message.WriteSingle(inputState.viewDeltaY);
message.WriteSingle(inputState.moveForward);
message.WriteSingle(inputState.moveRight);
message.WriteBoolean(inputState.attacking);
message.WriteBoolean(inputState.jumping);
message.WriteSingle(frameInfo.inputState.ViewDelta.X);
message.WriteSingle(frameInfo.inputState.ViewDelta.Y);
message.WriteSingle(frameInfo.inputState.MoveForward);
message.WriteSingle(frameInfo.inputState.MoveRight);
message.WriteBoolean(frameInfo.inputState.Attack);
message.WriteBoolean(frameInfo.inputState.Jump);
NetworkManager.ServerEndSendMessage(ref message, playerConnections[otherPlayerId]);
}
@@ -453,7 +483,7 @@ public class WorldStateManager
new Float3(networkEvent.Message.ReadSingle(), networkEvent.Message.ReadSingle(), networkEvent.Message.ReadSingle()));
//if (NetworkManager.IsClient)
players[playerId].GetScript<PlayerMovement>().input.frame = ClientFrame;
players[playerId].GetScript<PlayerMovement>().Input.SetFrame(ClientFrame);
break;
}
case GameModeMessageType.PlayerInput:
@@ -478,7 +508,7 @@ public class WorldStateManager
case GameModeMessageType.PlayerPosition:
{
//uint playerId = networkEvent.Sender.ConnectionId;
PlayerInputState inputState = default; //?
PlayerInputState2 inputState; //?
PlayerActorState actorState;
ulong reportedFrame = networkEvent.Message.ReadUInt64();
@@ -489,10 +519,10 @@ public class WorldStateManager
actorState.velocity.X = networkEvent.Message.ReadSingle();
actorState.velocity.Y = networkEvent.Message.ReadSingle();
actorState.velocity.Z = networkEvent.Message.ReadSingle();
actorState.orientation.X = networkEvent.Message.ReadSingle();
/*actorState.orientation.X = networkEvent.Message.ReadSingle();
actorState.orientation.Y = networkEvent.Message.ReadSingle();
actorState.orientation.Z = networkEvent.Message.ReadSingle();
actorState.orientation.W = networkEvent.Message.ReadSingle();
actorState.orientation.W = networkEvent.Message.ReadSingle();*/
actorState.viewAngles.X = networkEvent.Message.ReadSingle();
actorState.viewAngles.Y = networkEvent.Message.ReadSingle();
actorState.viewAngles.Z = networkEvent.Message.ReadSingle();
@@ -500,13 +530,13 @@ public class WorldStateManager
actorState.numJumps = networkEvent.Message.ReadInt32();
actorState.jumped = networkEvent.Message.ReadBoolean();
inputState.frame = reportedFrame;
inputState.viewDeltaX = networkEvent.Message.ReadSingle();
inputState.viewDeltaY = networkEvent.Message.ReadSingle();
inputState.moveForward = networkEvent.Message.ReadSingle();
inputState.moveRight = networkEvent.Message.ReadSingle();
inputState.attacking = networkEvent.Message.ReadBoolean();
inputState.jumping = networkEvent.Message.ReadBoolean();
//inputState.frame = reportedFrame;
inputState.ViewDelta.X = networkEvent.Message.ReadSingle();
inputState.ViewDelta.Y = networkEvent.Message.ReadSingle();
inputState.MoveForward = networkEvent.Message.ReadSingle();
inputState.MoveRight = networkEvent.Message.ReadSingle();
inputState.Attack = networkEvent.Message.ReadBoolean();
inputState.Jump = networkEvent.Message.ReadBoolean();
//if (actorState.viewAngles != new Float3(90f, 0f, 0f))
// Console.Print($"{reportedFrame} has viewangles: {actorState.viewAngles}");
@@ -530,14 +560,14 @@ public class WorldStateManager
if (playerActor != null)
{
PlayerInput playerInput = playerActor.GetScript<PlayerMovement>().input;
IPlayerInput playerInput = playerActor.GetScript<PlayerMovement>().Input;
if (IsLocalClient && reportedPlayerId == NetworkManager.LocalPlayerClientId)
{ }
else
playerInput.SetState(reportedFrame, inputState, actorState);
playerInput.SetFrame(reportedFrame);//playerInput.SetState(reportedFrame, inputState, actorState);
if (!IsLocalClient && playerInput is PlayerInputNetwork)
if (!IsLocalClient && playerInput is PlayerInputNetwork2)
{
playerActor.Position = actorState.position;
playerActor.GetScript<PlayerMovement>().movementState.currentVelocity = actorState.velocity;
@@ -577,7 +607,7 @@ public class WorldStateManager
playerInfo.playerId = playerActor.GetScript<PlayerMovement>().PlayerId;
playerInfo.playerPosition = playerActor.Position;
playerActor.GetScript<PlayerMovement>().input.SetState(serverWorldState.frame, new PlayerInputState(), new PlayerActorState()
/*playerActor.GetScript<PlayerMovement>().Input.SetState(serverWorldState.frame, new PlayerInputState(), new PlayerActorState()
{
position = playerActor.Position,
velocity = playerActor.GetScript<PlayerMovement>().movementState.currentVelocity,
@@ -587,7 +617,7 @@ public class WorldStateManager
numJumps = playerActor.GetScript<PlayerMovement>().movementState.numJumps,
jumped = playerActor.GetScript<PlayerMovement>().movementState.jumped,
//onGround = playerActor.GetScript<PlayerMovement>().movementState.onGround,
});
});*/
}
NetworkMessage message = NetworkManager.ServerBeginSendMessage();
welcomeMessage.Write(ref message);
@@ -659,8 +689,8 @@ public class WorldStateManager
if (!players.ContainsKey(playerId))
players.Add(playerId, null);
players[playerId] = playerActor;
PlayerInput playerInput = playerActor.GetScript<PlayerMovement>().input;
playerInput.frame = IsServer ? serverWorldState.frame : ClientFrame;
IPlayerInput playerInput = playerActor.GetScript<PlayerMovement>().Input;
playerInput.SetFrame(IsServer ? serverWorldState.frame : ClientFrame);
if (IsServer)
{
serverWorldState.actors.Add(playerActor);
@@ -686,7 +716,7 @@ public class WorldStateManager
PlayerActor playerActor = players[playerId];
PlayerMovement playerMovement = playerActor.GetScript<PlayerMovement>();
playerActor.UpdateNetworkInput(inputState);
//playerActor.UpdateNetworkInput(inputState);
ulong startFrame = playerLastFrame[playerId];
@@ -697,21 +727,26 @@ public class WorldStateManager
// simulate at least one or more frame when receiving input frames from player. missing frames use inputs from previous frames
var simframs = 0;
ulong frame = startFrame+1;
PlayerInputState prevInputState;
playerMovement.input.GetState(frame - 1, out prevInputState, out var _);
PlayerFrame prevFrame = GetPlayerFrame(playerId, frame - 1);
PlayerInputState2 prevInputState = prevFrame?.inputState ?? default;
//playerMovement.Input.GetState(frame - 1, out prevInputState, out var _);
for (; frame <= inputState.frame; frame++)
{
if (!playerMovement.input.GetState(frame, out var lastInputState, out var lastActorState))
PlayerFrame frameInfo = GetPlayerFrame(playerId, frame);
PlayerInputState2 lastInputState = frameInfo?.inputState ?? prevInputState;
//if (!playerMovement.Input.GetState(frame, out var lastInputState, out var lastActorState))
/*if (frameInfo == null)
{
// dropped frame, use previous input
lastInputState = prevInputState;
lastInputState.frame = frame;
}
}*/
playerMovement.ApplyInputToCamera(lastInputState, true);
playerMovement.SimulatePlayerMovement(lastInputState);
playerMovement.SimulatePlayerMovement(lastInputState, frame);
playerMovement.input.SetState(frame, lastInputState, new PlayerActorState()
RecordPlayerInput(playerId, Frame, lastInputState, playerMovement.movementState);
/*playerMovement.Input.SetState(frame, lastInputState, new PlayerActorState()
{
position = playerActor.Position,
velocity = playerMovement.movementState.currentVelocity,
@@ -721,7 +756,7 @@ public class WorldStateManager
numJumps = playerMovement.movementState.numJumps,
jumped = playerMovement.movementState.jumped,
//onGround = playerMovement.movementState.onGround,
});
});*/
simframs++;
prevInputState = lastInputState;