progress
This commit is contained in:
@@ -422,6 +422,8 @@ namespace Game
|
|||||||
consoleLines.Add(lineEntry);
|
consoleLines.Add(lineEntry);
|
||||||
OnPrint?.Invoke(text);
|
OnPrint?.Invoke(text);
|
||||||
}
|
}
|
||||||
|
if (Debugger.IsAttached)
|
||||||
|
System.Diagnostics.Debug.WriteLine(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PrintDebug(int verbosity, bool noRepeat, string text)
|
public void PrintDebug(int verbosity, bool noRepeat, string text)
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ public class Game : GameModule
|
|||||||
|
|
||||||
base.Setup(options);
|
base.Setup(options);
|
||||||
|
|
||||||
Tags["Network"] = string.Empty;
|
//Tags["Network"] = string.Empty;
|
||||||
options.PublicDependencies.Add("Networking");
|
//options.PublicDependencies.Add("Networking");
|
||||||
|
|
||||||
options.PrivateDependencies.Add("FidelityFXFSR");
|
options.PrivateDependencies.Add("FidelityFXFSR");
|
||||||
|
|
||||||
|
|||||||
@@ -53,11 +53,15 @@ namespace Game
|
|||||||
private static ulong lastReceivedServerFrame = 0;
|
private static ulong lastReceivedServerFrame = 0;
|
||||||
public static ulong ServerFrame => /*NetworkManager.server != null ? serverWorldState.frame :*/ lastReceivedServerFrame;
|
public static ulong ServerFrame => /*NetworkManager.server != null ? serverWorldState.frame :*/ lastReceivedServerFrame;
|
||||||
public static ulong ClientFrame => clientWorldState.frame;
|
public static ulong ClientFrame => clientWorldState.frame;
|
||||||
|
public static float ServerTime = 0f;
|
||||||
|
public static float ClientTime = 0f;
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
welcomed = false;
|
welcomed = false;
|
||||||
lastReceivedServerFrame = 0;
|
lastReceivedServerFrame = 0;
|
||||||
|
ServerTime = Time.GameTime;
|
||||||
|
ClientTime = 0f;
|
||||||
|
|
||||||
players = new Dictionary<uint, PlayerActor>();
|
players = new Dictionary<uint, PlayerActor>();
|
||||||
playerConnections = new Dictionary<uint, NetworkConnection>();
|
playerConnections = new Dictionary<uint, NetworkConnection>();
|
||||||
@@ -126,7 +130,10 @@ namespace Game
|
|||||||
var playerFrame = playerFrames[serverWorldState.frame % 120];
|
var playerFrame = playerFrames[serverWorldState.frame % 120];
|
||||||
|
|
||||||
playerFrame.frame = serverWorldState.frame;
|
playerFrame.frame = serverWorldState.frame;
|
||||||
playerFrame.position = playerActor.Position;
|
//playerFrame.position = playerActor.Position;
|
||||||
|
PlayerMovement playerMovement = playerActor.GetScript<PlayerMovement>();
|
||||||
|
playerMovement.input.GetState(serverWorldState.frame, out var inputState, out var actorState);
|
||||||
|
playerFrame.position = actorState.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (KeyValuePair<uint, PlayerActor> kv in players)
|
foreach (KeyValuePair<uint, PlayerActor> kv in players)
|
||||||
@@ -142,8 +149,9 @@ namespace Game
|
|||||||
// TODO: relevancy checks here etc.
|
// TODO: relevancy checks here etc.
|
||||||
|
|
||||||
PlayerMovement playerMovement = otherPlayerActor.GetScript<PlayerMovement>();
|
PlayerMovement playerMovement = otherPlayerActor.GetScript<PlayerMovement>();
|
||||||
PlayerActorState actorState = playerMovement.input.GetCurrentActorState();
|
//PlayerActorState actorState = playerMovement.input.GetCurrentActorState();
|
||||||
PlayerInputState inputState = playerMovement.input.GetCurrentInputState();
|
//PlayerInputState inputState = playerMovement.input.GetCurrentInputState();
|
||||||
|
playerMovement.input.GetState(serverWorldState.frame, out var inputState, out var actorState);
|
||||||
{
|
{
|
||||||
NetworkMessage message = NetworkManager.ServerBeginSendMessage();
|
NetworkMessage message = NetworkManager.ServerBeginSendMessage();
|
||||||
message.WriteByte((byte)GameModeMessageType.PlayerPosition);
|
message.WriteByte((byte)GameModeMessageType.PlayerPosition);
|
||||||
@@ -162,6 +170,7 @@ namespace Game
|
|||||||
message.WriteSingle(actorState.viewAngles.X);
|
message.WriteSingle(actorState.viewAngles.X);
|
||||||
message.WriteSingle(actorState.viewAngles.Y);
|
message.WriteSingle(actorState.viewAngles.Y);
|
||||||
message.WriteSingle(actorState.viewAngles.Z);
|
message.WriteSingle(actorState.viewAngles.Z);
|
||||||
|
message.WriteSingle(actorState.lastJumpTime);
|
||||||
|
|
||||||
//inputState.frame
|
//inputState.frame
|
||||||
message.WriteSingle(inputState.viewDeltaX);
|
message.WriteSingle(inputState.viewDeltaX);
|
||||||
@@ -265,6 +274,7 @@ namespace Game
|
|||||||
if (NetworkManager.IsClient || NetworkManager.IsLocalClient)
|
if (NetworkManager.IsClient || NetworkManager.IsLocalClient)
|
||||||
{
|
{
|
||||||
var serverFrame = networkEvent.Message.ReadUInt64();
|
var serverFrame = networkEvent.Message.ReadUInt64();
|
||||||
|
ClientTime = networkEvent.Message.ReadSingle();
|
||||||
int numActors = (int)networkEvent.Message.ReadUInt32();
|
int numActors = (int)networkEvent.Message.ReadUInt32();
|
||||||
for (int i = 0; i < numActors; i++)
|
for (int i = 0; i < numActors; i++)
|
||||||
{
|
{
|
||||||
@@ -353,6 +363,7 @@ namespace Game
|
|||||||
actorState.viewAngles.X = networkEvent.Message.ReadSingle();
|
actorState.viewAngles.X = networkEvent.Message.ReadSingle();
|
||||||
actorState.viewAngles.Y = networkEvent.Message.ReadSingle();
|
actorState.viewAngles.Y = networkEvent.Message.ReadSingle();
|
||||||
actorState.viewAngles.Z = networkEvent.Message.ReadSingle();
|
actorState.viewAngles.Z = networkEvent.Message.ReadSingle();
|
||||||
|
actorState.lastJumpTime = networkEvent.Message.ReadSingle();
|
||||||
|
|
||||||
inputState.frame = reportedFrame;
|
inputState.frame = reportedFrame;
|
||||||
inputState.viewDeltaX = networkEvent.Message.ReadSingle();
|
inputState.viewDeltaX = networkEvent.Message.ReadSingle();
|
||||||
@@ -365,44 +376,11 @@ namespace Game
|
|||||||
//Assert.IsTrue(reportedFrame >= lastReceivedServerFrame);
|
//Assert.IsTrue(reportedFrame >= lastReceivedServerFrame);
|
||||||
if (reportedFrame < lastReceivedServerFrame)
|
if (reportedFrame < lastReceivedServerFrame)
|
||||||
{
|
{
|
||||||
Console.Print($"packet wrong order, received {lastReceivedServerFrame}, new {reportedFrame}");
|
//Console.Print($"packet wrong order, received {lastReceivedServerFrame}, new {reportedFrame}");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NetworkManager.IsClient)
|
||||||
/*if (NetworkManager.IsLocalClient && !NetworkManager.IsServer)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else*/ if (NetworkManager.IsServer)
|
|
||||||
{
|
|
||||||
Assert.Fail();
|
|
||||||
/*PlayerFrame playerFrame = GetPlayerFrame(playerId, reportedFrame);
|
|
||||||
PlayerActor playerActor = players[playerId];
|
|
||||||
if (playerFrame == null)
|
|
||||||
Console.Print("frame is in the past, unable to verify frame");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Float3 playerFramePosition = playerFrame.position;
|
|
||||||
if ((playerFramePosition - reportedPosition).Length > 0.0001)
|
|
||||||
{
|
|
||||||
Console.Print("player drifted, len: " + (playerFramePosition - reportedPosition).Length);
|
|
||||||
|
|
||||||
{
|
|
||||||
NetworkMessage message = NetworkManager.ServerBeginSendMessage();
|
|
||||||
message.WriteByte((byte)GameModeMessageType.PlayerPosition);
|
|
||||||
|
|
||||||
message.WriteUInt64(serverWorldState.frame);
|
|
||||||
message.WriteUInt32(playerId);
|
|
||||||
message.WriteSingle(playerActor.Position.X);
|
|
||||||
message.WriteSingle(playerActor.Position.Y);
|
|
||||||
message.WriteSingle(playerActor.Position.Z);
|
|
||||||
NetworkManager.ServerEndSendMessage(ref message, playerConnections[playerId]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
else if (NetworkManager.IsClient)
|
|
||||||
{
|
{
|
||||||
lastReceivedServerFrame = reportedFrame;
|
lastReceivedServerFrame = reportedFrame;
|
||||||
//Console.Print($"we drifted, corrected. client frame: {serverWorldState.frame}, server frame: {reportedFrame}");
|
//Console.Print($"we drifted, corrected. client frame: {serverWorldState.frame}, server frame: {reportedFrame}");
|
||||||
@@ -414,7 +392,7 @@ namespace Game
|
|||||||
{
|
{
|
||||||
PlayerInput playerInput = playerActor.GetScript<PlayerMovement>().input;
|
PlayerInput playerInput = playerActor.GetScript<PlayerMovement>().input;
|
||||||
|
|
||||||
playerInput.SetState(reportedFrame, ref inputState, ref actorState);
|
playerInput.SetState(reportedFrame, inputState, actorState);
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -440,6 +418,7 @@ namespace Game
|
|||||||
NetworkMessage message = NetworkManager.ServerBeginSendMessage();
|
NetworkMessage message = NetworkManager.ServerBeginSendMessage();
|
||||||
message.WriteByte((byte)GameModeMessageType.WelcomePlayer);
|
message.WriteByte((byte)GameModeMessageType.WelcomePlayer);
|
||||||
message.WriteUInt64(serverWorldState.frame);
|
message.WriteUInt64(serverWorldState.frame);
|
||||||
|
message.WriteSingle(ServerTime);
|
||||||
message.WriteUInt32((uint)serverWorldState.actors.Count);
|
message.WriteUInt32((uint)serverWorldState.actors.Count);
|
||||||
foreach (PlayerActor playerActor in serverWorldState.actors)
|
foreach (PlayerActor playerActor in serverWorldState.actors)
|
||||||
{
|
{
|
||||||
@@ -514,7 +493,7 @@ namespace Game
|
|||||||
players.Add(playerId, null);
|
players.Add(playerId, null);
|
||||||
players[playerId] = playerActor;
|
players[playerId] = playerActor;
|
||||||
PlayerInput playerInput = playerActor.GetScript<PlayerMovement>().input;
|
PlayerInput playerInput = playerActor.GetScript<PlayerMovement>().input;
|
||||||
|
playerInput.frame = (NetworkManager.IsServer) ? serverWorldState.frame : clientWorldState.frame;
|
||||||
if (NetworkManager.IsServer)
|
if (NetworkManager.IsServer)
|
||||||
serverWorldState.actors.Add(playerActor);
|
serverWorldState.actors.Add(playerActor);
|
||||||
}
|
}
|
||||||
|
|||||||
20
Source/Game/Hud/SpeedWidget.cs
Normal file
20
Source/Game/Hud/SpeedWidget.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using FlaxEngine;
|
||||||
|
using FlaxEngine.GUI;
|
||||||
|
|
||||||
|
namespace Game
|
||||||
|
{
|
||||||
|
public class SpeedWidget : Script
|
||||||
|
{
|
||||||
|
public override void OnAwake()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnUpdate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,6 +43,9 @@ namespace Game
|
|||||||
public class PlayerActor : RigidBody//, INetworkSerializable
|
public class PlayerActor : RigidBody//, INetworkSerializable
|
||||||
{
|
{
|
||||||
private PlayerMovement playerMovement;
|
private PlayerMovement playerMovement;
|
||||||
|
public CapsuleCollider capsuleCollider;
|
||||||
|
public BoxCollider boxCollider;
|
||||||
|
public MeshCollider meshCollider;
|
||||||
|
|
||||||
//[NetworkReplicated]
|
//[NetworkReplicated]
|
||||||
public uint PlayerId = uint.MaxValue;
|
public uint PlayerId = uint.MaxValue;
|
||||||
@@ -69,6 +72,9 @@ namespace Game
|
|||||||
base.OnBeginPlay();
|
base.OnBeginPlay();
|
||||||
|
|
||||||
playerMovement = FindScript<PlayerMovement>();
|
playerMovement = FindScript<PlayerMovement>();
|
||||||
|
capsuleCollider = GetChild<CapsuleCollider>();
|
||||||
|
boxCollider = GetChild<BoxCollider>();
|
||||||
|
meshCollider = GetChild<MeshCollider>();
|
||||||
//playerRigidBody = FindActor<RigidBody>();
|
//playerRigidBody = FindActor<RigidBody>();
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace Game
|
|||||||
});
|
});
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
#if false
|
||||||
public PlayerInputState(ulong frame, float viewDeltaX, float viewDeltaY, float moveForward, float moveRight,
|
public PlayerInputState(ulong frame, float viewDeltaX, float viewDeltaY, float moveForward, float moveRight,
|
||||||
bool attacking, bool jumping)
|
bool attacking, bool jumping)
|
||||||
{
|
{
|
||||||
@@ -52,6 +53,7 @@ namespace Game
|
|||||||
this.verificationViewAngles = verificationViewAngles;
|
this.verificationViewAngles = verificationViewAngles;
|
||||||
this.verificationOrientation = verificationOrientation;
|
this.verificationOrientation = verificationOrientation;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public ulong frame;
|
public ulong frame;
|
||||||
public float viewDeltaX, viewDeltaY;
|
public float viewDeltaX, viewDeltaY;
|
||||||
@@ -73,6 +75,7 @@ namespace Game
|
|||||||
public Float3 velocity;
|
public Float3 velocity;
|
||||||
public Quaternion orientation;
|
public Quaternion orientation;
|
||||||
public Float3 viewAngles; // yaw, pitch, roll
|
public Float3 viewAngles; // yaw, pitch, roll
|
||||||
|
public float lastJumpTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
@@ -103,6 +106,8 @@ namespace Game
|
|||||||
|
|
||||||
public virtual void OnEndFrame()
|
public virtual void OnEndFrame()
|
||||||
{
|
{
|
||||||
|
Console.Print("recorded frame " + frame);
|
||||||
|
currentState.input.frame = frame;
|
||||||
states[frame % 120] = currentState;
|
states[frame % 120] = currentState;
|
||||||
|
|
||||||
/*ulong oldest = ulong.MaxValue;
|
/*ulong oldest = ulong.MaxValue;
|
||||||
@@ -132,7 +137,7 @@ namespace Game
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetState(ulong frame, ref PlayerInputState inputState, ref PlayerActorState actorState)
|
public void SetState(ulong frame, PlayerInputState inputState, PlayerActorState actorState)
|
||||||
{
|
{
|
||||||
int frameIndex = (int)frame % 120;
|
int frameIndex = (int)frame % 120;
|
||||||
states[frameIndex].input = inputState;
|
states[frameIndex].input = inputState;
|
||||||
|
|||||||
@@ -104,11 +104,11 @@ namespace Game
|
|||||||
NetworkManager.ClientEndSendMessage(ref message);
|
NetworkManager.ClientEndSendMessage(ref message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base.OnEndFrame();
|
||||||
|
|
||||||
// Reset anything accumulatable here
|
// Reset anything accumulatable here
|
||||||
currentState.input.viewDeltaX = 0;
|
currentState.input.viewDeltaX = 0;
|
||||||
currentState.input.viewDeltaY = 0;
|
currentState.input.viewDeltaY = 0;
|
||||||
|
|
||||||
base.OnEndFrame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void RecordCurrentActorState(PlayerActorState actorState)
|
public override void RecordCurrentActorState(PlayerActorState actorState)
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ namespace Game
|
|||||||
private float lastJumped = -1f;
|
private float lastJumped = -1f;
|
||||||
private float lastLanded = -1f;
|
private float lastLanded = -1f;
|
||||||
private int numJumps;
|
private int numJumps;
|
||||||
|
private float simulationTime = 0f;
|
||||||
|
|
||||||
[ReadOnly] public bool onGround;
|
[ReadOnly] public bool onGround;
|
||||||
private RigidBody rigidBody;
|
private RigidBody rigidBody;
|
||||||
@@ -159,7 +160,7 @@ namespace Game
|
|||||||
// Setup input with no controller
|
// Setup input with no controller
|
||||||
//SetInput(NetworkReplicator.GetObjectOwnerClientId(this.Parent));
|
//SetInput(NetworkReplicator.GetObjectOwnerClientId(this.Parent));
|
||||||
|
|
||||||
|
|
||||||
//rigidBody.CollisionEnter += OnCollisionEnter;
|
//rigidBody.CollisionEnter += OnCollisionEnter;
|
||||||
//rigidBody.TriggerEnter += OnTriggerEnter;
|
//rigidBody.TriggerEnter += OnTriggerEnter;
|
||||||
//rigidBody.TriggerExit += OnTriggerExit;
|
//rigidBody.TriggerExit += OnTriggerExit;
|
||||||
@@ -252,10 +253,11 @@ namespace Game
|
|||||||
|
|
||||||
public void ResetRotation(Float3 eulerAngles)
|
public void ResetRotation(Float3 eulerAngles)
|
||||||
{
|
{
|
||||||
viewAngles = eulerAngles;
|
//viewAngles = eulerAngles;
|
||||||
viewAnglesLastFrame = eulerAngles;
|
//viewAnglesLastFrame = eulerAngles;
|
||||||
|
|
||||||
SetCameraEulerAngles(new Float3(eulerAngles.Y, eulerAngles.X, eulerAngles.Z));
|
SetCameraEulerAngles(new Float3(eulerAngles.Y, eulerAngles.X, eulerAngles.Z));
|
||||||
|
viewAnglesLastFrame = viewAngles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnUpdate()
|
public override void OnUpdate()
|
||||||
@@ -279,9 +281,22 @@ namespace Game
|
|||||||
|
|
||||||
PlayerInputState inputState = input.GetCurrentInputState();
|
PlayerInputState inputState = input.GetCurrentInputState();
|
||||||
|
|
||||||
|
//if (inputState.viewDeltaX != 0 || inputState.viewDeltaY != 0)
|
||||||
|
// inputState = inputState;
|
||||||
|
|
||||||
viewAngles = viewAnglesLastFrame;
|
viewAngles = viewAnglesLastFrame;
|
||||||
ApplyInputToCamera(inputState);
|
ApplyInputToCamera(inputState);
|
||||||
|
|
||||||
|
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.RecordCurrentActorState(new PlayerActorState()
|
/*input.RecordCurrentActorState(new PlayerActorState()
|
||||||
{
|
{
|
||||||
position = Actor.Position,
|
position = Actor.Position,
|
||||||
@@ -359,43 +374,148 @@ namespace Game
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (input.Predict && GameModeManager.ClientFrame > 0 && GameModeManager.ServerFrame > 0)
|
if (Actor.Position.Length < 0.1)
|
||||||
|
jumped = jumped;
|
||||||
|
|
||||||
|
//viewAngles = viewAnglesLastFrame;
|
||||||
|
//ApplyInputToCamera(inputState);
|
||||||
|
var oldAngles = viewAngles;
|
||||||
|
//viewAngles = viewAnglesLastFrame;
|
||||||
|
bool canpredict = true;
|
||||||
|
if (true && input.Predict && GameModeManager.ClientFrame > 0 && GameModeManager.ServerFrame > 0)
|
||||||
{
|
{
|
||||||
predicting = true;
|
for (ulong currentFrame = GameModeManager.ServerFrame; currentFrame < GameModeManager.ClientFrame; currentFrame++)
|
||||||
for (ulong currentFrame = GameModeManager.ServerFrame; currentFrame < GameModeManager.ClientFrame - 1; currentFrame++)
|
|
||||||
{
|
{
|
||||||
if (!input.GetState(currentFrame, out var pastInputState, out var pastActorState))
|
if (!input.GetState(currentFrame, out var pastInputState, out var pastActorState))
|
||||||
{
|
{
|
||||||
Console.Print($"predict failure: {currentFrame}");
|
Console.Print($"not predicting");
|
||||||
|
canpredict = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentFrame == GameModeManager.ServerFrame)
|
|
||||||
{
|
|
||||||
Actor.Position = pastActorState.position;
|
|
||||||
currentVelocity = pastActorState.velocity;
|
|
||||||
rootActor.Orientation = pastActorState.orientation;
|
|
||||||
viewAngles = new Float3(pastActorState.viewAngles.Y, pastActorState.viewAngles.X, pastActorState.viewAngles.Z);
|
|
||||||
}
|
|
||||||
SimulatePlayerMovement(pastInputState);
|
|
||||||
|
|
||||||
//Console.Print($"predicted: {currentFrame}");
|
|
||||||
}
|
}
|
||||||
predicting = false;
|
|
||||||
//Console.Print($"current: {inputState.frame}");
|
if (canpredict)
|
||||||
//if (GameModeManager.ClientFrame - GameModeManager.ServerFrame > 0)
|
{
|
||||||
// Console.Print($"current diff: {GameModeManager.ClientFrame - GameModeManager.ServerFrame}");
|
//var oldPos = Actor.Position;
|
||||||
|
//var oldVel = currentVelocity;
|
||||||
|
|
||||||
|
predicting = true;
|
||||||
|
for (ulong currentFrame = GameModeManager.ServerFrame; currentFrame < GameModeManager.ClientFrame; currentFrame++)
|
||||||
|
{
|
||||||
|
if (!input.GetState(currentFrame, out var pastInputState, out var pastActorState))
|
||||||
|
{
|
||||||
|
Console.Print($"predict failure: {currentFrame}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentFrame == GameModeManager.ServerFrame)
|
||||||
|
{
|
||||||
|
Actor.Position = pastActorState.position;
|
||||||
|
currentVelocity = pastActorState.velocity;
|
||||||
|
lastJumped = pastActorState.lastJumpTime;
|
||||||
|
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);
|
||||||
|
|
||||||
|
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}");
|
||||||
|
}
|
||||||
|
|
||||||
|
predicting = false;
|
||||||
|
|
||||||
|
/*if ((Actor.Position - oldPos).Length > 0.001)
|
||||||
|
Console.Print($"mispredicted final position");
|
||||||
|
if ((currentVelocity - oldVel).Length > 0.001)
|
||||||
|
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);
|
||||||
|
|
||||||
|
SimulatePlayerMovement(inputState);
|
||||||
|
|
||||||
|
if ((viewAngles - oldAngles).Length > 0.001)
|
||||||
|
Console.Print($"mispredicted final viewangles: {viewAngles - oldAngles}");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Console.Print($"current: {inputState.frame}");
|
||||||
|
//if (GameModeManager.ClientFrame - GameModeManager.ServerFrame > 0)
|
||||||
|
// Console.Print($"current diff: {GameModeManager.ClientFrame - GameModeManager.ServerFrame}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
canpredict = false;
|
||||||
|
|
||||||
|
if (!canpredict)
|
||||||
|
{
|
||||||
|
|
||||||
|
SetCameraEulerAngles(viewAnglesLastFrame, true);
|
||||||
|
ApplyInputToCamera(inputState, true);
|
||||||
|
SimulatePlayerMovement(inputState);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatePlayerMovement(inputState);
|
if (Actor.Position.Length < 0.1)
|
||||||
|
jumped = jumped;
|
||||||
|
|
||||||
|
//if (currentVelocity.Length > 0)
|
||||||
|
// Console.Print($"velocity at frame {GameModeManager.ClientFrame}");
|
||||||
|
|
||||||
|
/*if (input.GetState(GameModeManager.ClientFrame - 1, out var pastInputState2, out var pastActorState2))
|
||||||
|
{
|
||||||
|
Actor.Position = pastActorState2.position;
|
||||||
|
currentVelocity = pastActorState2.velocity;
|
||||||
|
rootActor.Orientation = pastActorState2.orientation;
|
||||||
|
viewAngles = new Float3(pastActorState2.viewAngles.Y, pastActorState2.viewAngles.X, pastActorState2.viewAngles.Z);
|
||||||
|
//viewAngles = viewAnglesLastFrame;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Console.Print($"poop");*/
|
||||||
|
|
||||||
|
//viewAngles = oldAngles;'
|
||||||
|
//viewAngles = viewAnglesLastFrame;
|
||||||
|
//ApplyInputToCamera(inputState, true);
|
||||||
|
//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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Actor.Position.Length < 0.1)
|
||||||
|
jumped = jumped;
|
||||||
|
|
||||||
input.RecordCurrentActorState(new PlayerActorState
|
input.RecordCurrentActorState(new PlayerActorState
|
||||||
{
|
{
|
||||||
position = Actor.Position,
|
position = Actor.Position,
|
||||||
velocity = currentVelocity,
|
velocity = currentVelocity,
|
||||||
orientation = rootActor.Orientation,
|
orientation = rootActor.Orientation,
|
||||||
viewAngles = new Float3(viewAngles.Y, viewAngles.X, viewAngles.Z)
|
viewAngles = viewAngles,
|
||||||
|
lastJumpTime = lastJumped,
|
||||||
|
//viewAngles = new Float3(viewAngles.Y, viewAngles.X, viewAngles.Z)
|
||||||
});
|
});
|
||||||
input.OnEndFrame();
|
input.OnEndFrame();
|
||||||
|
|
||||||
@@ -404,26 +524,30 @@ namespace Game
|
|||||||
//currentInputFrame++;
|
//currentInputFrame++;
|
||||||
|
|
||||||
viewAnglesLastFrame = viewAngles;
|
viewAnglesLastFrame = viewAngles;
|
||||||
|
|
||||||
|
/*if (input.GetState(GameModeManager.ServerFrame, out var pastInputState2, out var pastActorState2))
|
||||||
|
{
|
||||||
|
Actor.Position = pastActorState2.position;
|
||||||
|
currentVelocity = pastActorState2.velocity;
|
||||||
|
SetCameraEulerAngles(pastActorState2.viewAngles, true);
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyInputToCamera(PlayerInputState inputState, bool wrapAround = true)
|
private void ApplyInputToCamera(PlayerInputState inputState, bool wrapAround = true)
|
||||||
{
|
{
|
||||||
// Update camera viewf
|
if (inputState.viewDeltaX == 0.0f && inputState.viewDeltaY == 0.0f)
|
||||||
float xAxis = inputState.viewDeltaX;
|
|
||||||
float yAxis = inputState.viewDeltaY;
|
|
||||||
if (xAxis == 0.0f && yAxis == 0.0f)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float viewPitch = viewAngles.X;
|
float viewPitch = Mathf.Clamp(viewAngles.Y + inputState.viewDeltaY, -90.0f, 90.0f);
|
||||||
float viewYaw = viewAngles.Y;
|
float viewYaw = viewAngles.X + inputState.viewDeltaX;
|
||||||
viewPitch = Mathf.Clamp(viewPitch + yAxis, -90.0f, 90.0f);
|
|
||||||
viewYaw += xAxis;
|
|
||||||
|
|
||||||
SetCameraEulerAngles(new Float3(viewYaw, viewPitch, viewAngles.Z), wrapAround);
|
SetCameraEulerAngles(new Float3(viewYaw, viewPitch, viewAngles.Z), wrapAround);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetCameraEulerAngles(Float3 angles, bool wrapAround = true)
|
private void SetCameraEulerAngles(Float3 angles, bool wrapAround = true)
|
||||||
{
|
{
|
||||||
|
if (viewAngles == angles)
|
||||||
|
return;
|
||||||
|
|
||||||
// Very slight drift
|
// Very slight drift
|
||||||
if (wrapAround)
|
if (wrapAround)
|
||||||
{
|
{
|
||||||
@@ -433,17 +557,18 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Root orientation must be set first
|
// Root orientation must be set first
|
||||||
var or1 = Quaternion.Euler(0, angles.X, 0);
|
rootActor.Orientation = Quaternion.Euler(0, angles.X, 0);
|
||||||
var or2 = Quaternion.Euler(angles.Y, angles.X, angles.Z);
|
if (!predicting)
|
||||||
rootActor.Orientation = or1;
|
{
|
||||||
cameraHolder.Orientation = or2;
|
cameraHolder.Orientation = Quaternion.Euler(angles.Y, angles.X, angles.Z);
|
||||||
|
}
|
||||||
//Console.Print(angles.X.ToString());
|
//Console.Print(angles.X.ToString());
|
||||||
|
|
||||||
viewAngles = new Float3(angles.Y, angles.X, angles.Z);
|
viewAngles = angles;//new Float3(angles.Y, angles.X, angles.Z);
|
||||||
|
//viewAnglesLastFrame = angles;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool SweepPlayerCollider(Actor actor, Float3 start, Vector3 end, out RayCastHit[] hits)
|
private static bool SweepPlayerCollider(PlayerActor actor, Float3 start, Vector3 end, out RayCastHit[] hits)
|
||||||
{
|
{
|
||||||
Vector3 delta = end - start;
|
Vector3 delta = end - start;
|
||||||
float distance = delta.Length;
|
float distance = delta.Length;
|
||||||
@@ -456,9 +581,9 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool collided = false;
|
bool collided = false;
|
||||||
CapsuleCollider capsuleCollider = actor.GetChild<CapsuleCollider>();
|
CapsuleCollider capsuleCollider = actor.capsuleCollider;
|
||||||
BoxCollider boxCollider = actor.GetChild<BoxCollider>();
|
BoxCollider boxCollider = actor.boxCollider;
|
||||||
MeshCollider meshCollider = actor.GetChild<MeshCollider>();
|
MeshCollider meshCollider = actor.meshCollider;
|
||||||
if (capsuleCollider && capsuleCollider.IsActive)
|
if (capsuleCollider && capsuleCollider.IsActive)
|
||||||
collided = Physics.CapsuleCastAll(start,
|
collided = Physics.CapsuleCastAll(start,
|
||||||
capsuleCollider.Radius, capsuleCollider.Height,
|
capsuleCollider.Radius, capsuleCollider.Height,
|
||||||
@@ -550,7 +675,7 @@ namespace Game
|
|||||||
/// <param name="start">Start position</param>
|
/// <param name="start">Start position</param>
|
||||||
/// <param name="end">End position</param>
|
/// <param name="end">End position</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static TraceInfo TracePlayer(Actor actor, Vector3 start, Vector3 end)
|
private static TraceInfo TracePlayer(PlayerActor actor, Vector3 start, Vector3 end)
|
||||||
{
|
{
|
||||||
TraceInfo traceInfo = new TraceInfo();
|
TraceInfo traceInfo = new TraceInfo();
|
||||||
|
|
||||||
@@ -665,7 +790,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private static SlideMoveHit StepSlideMove(Actor actor, ref Vector3 position, ref Vector3 velocity,
|
private static SlideMoveHit StepSlideMove(PlayerActor actor, ref Vector3 position, ref Vector3 velocity,
|
||||||
bool onGround)
|
bool onGround)
|
||||||
{
|
{
|
||||||
if (velocity.IsZero)
|
if (velocity.IsZero)
|
||||||
@@ -772,7 +897,7 @@ namespace Game
|
|||||||
return slideMoveHit;
|
return slideMoveHit;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SlideMoveHit SlideMove(Actor actor, ref Vector3 position, ref Vector3 velocity)
|
private static SlideMoveHit SlideMove(PlayerActor actor, ref Vector3 position, ref Vector3 velocity)
|
||||||
{
|
{
|
||||||
if (velocity.IsZero)
|
if (velocity.IsZero)
|
||||||
return SlideMoveHit.Nothing;
|
return SlideMoveHit.Nothing;
|
||||||
@@ -899,18 +1024,14 @@ namespace Game
|
|||||||
|
|
||||||
public void SimulatePlayerMovement(PlayerInputState inputState)
|
public void SimulatePlayerMovement(PlayerInputState inputState)
|
||||||
{
|
{
|
||||||
Transform rootTrans = rootActor.Transform;
|
simulationTime = GameModeManager.ClientTime + (inputState.frame * (1.0f / Time.PhysicsFPS));
|
||||||
|
|
||||||
Vector3 inputDirection =
|
Vector3 inputDirection =
|
||||||
new Float3(inputState.moveRight, 0.0f, inputState.moveForward);
|
new Float3(inputState.moveRight, 0.0f, inputState.moveForward);
|
||||||
Vector3 moveDirection = rootTrans.TransformDirection(inputDirection);
|
Vector3 moveDirection = rootActor.Transform.TransformDirection(inputDirection);
|
||||||
|
|
||||||
Vector3 position = rigidBody.Position;
|
Vector3 position = rigidBody.Position;
|
||||||
Vector3 velocity = currentVelocity; //rigidBody.LinearVelocity;
|
Vector3 velocity = currentVelocity; //rigidBody.LinearVelocity;
|
||||||
|
Vector3 wishVelocity = !inputDirection.IsZero ? moveDirection.Normalized * MoveSpeed : Vector3.Zero;
|
||||||
Vector3 wishVelocity = Float3.Zero;
|
|
||||||
if (!inputDirection.IsZero)
|
|
||||||
wishVelocity = moveDirection.Normalized * MoveSpeed;
|
|
||||||
|
|
||||||
// categorize position
|
// categorize position
|
||||||
bool lastGround = onGround;
|
bool lastGround = onGround;
|
||||||
@@ -923,7 +1044,7 @@ namespace Game
|
|||||||
|
|
||||||
if (jumped && !jumpAction)
|
if (jumped && !jumpAction)
|
||||||
jumped = false; // jump released
|
jumped = false; // jump released
|
||||||
else if (jumped && Time.GameTime - lastJumped >= autoJumpTime)
|
else if (jumped && simulationTime - lastJumped >= autoJumpTime)
|
||||||
jumped = false; // jump timeout
|
jumped = false; // jump timeout
|
||||||
|
|
||||||
// jump
|
// jump
|
||||||
@@ -931,11 +1052,11 @@ namespace Game
|
|||||||
if (OnJump(traceGround, ref position, ref velocity))
|
if (OnJump(traceGround, ref position, ref velocity))
|
||||||
{
|
{
|
||||||
jumped = true;
|
jumped = true;
|
||||||
lastJumped = Time.GameTime;
|
lastJumped = simulationTime;
|
||||||
numJumps++;
|
numJumps++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Time.GameTime - lastJumped > jumpBoostTime)
|
if (simulationTime - lastJumped > jumpBoostTime)
|
||||||
numJumps = 0;
|
numJumps = 0;
|
||||||
|
|
||||||
//if (/*onGround && */lastGround != onGround)
|
//if (/*onGround && */lastGround != onGround)
|
||||||
@@ -953,7 +1074,7 @@ namespace Game
|
|||||||
ApplyAirAcceleration(ref velocity, wishVelocity);
|
ApplyAirAcceleration(ref velocity, wishVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
StepSlideMove(Actor, ref position, ref velocity, onGround);
|
StepSlideMove(Actor as PlayerActor, ref position, ref velocity, onGround);
|
||||||
|
|
||||||
|
|
||||||
TraceInfo traceGround2 = CategorizePosition(position, ref velocity);
|
TraceInfo traceGround2 = CategorizePosition(position, ref velocity);
|
||||||
@@ -965,11 +1086,11 @@ namespace Game
|
|||||||
const float landingVelocityThreshold = 120f;
|
const float landingVelocityThreshold = 120f;
|
||||||
const float landingHardVelocityThreshold = 500f;
|
const float landingHardVelocityThreshold = 500f;
|
||||||
if (currentVelocity.Y - lastVelocity.Y > landingVelocityThreshold)
|
if (currentVelocity.Y - lastVelocity.Y > landingVelocityThreshold)
|
||||||
if (Time.GameTime - lastJumped > 0.01)
|
if (simulationTime - lastJumped > 0.01)
|
||||||
{
|
{
|
||||||
bool hardLanding = currentVelocity.Y - lastVelocity.Y > landingHardVelocityThreshold;
|
bool hardLanding = currentVelocity.Y - lastVelocity.Y > landingHardVelocityThreshold;
|
||||||
OnLanded(currentVelocity - lastVelocity, hardLanding);
|
OnLanded(currentVelocity - lastVelocity, hardLanding);
|
||||||
lastLanded = Time.GameTime;
|
lastLanded = simulationTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -978,7 +1099,7 @@ namespace Game
|
|||||||
Vector3 groundDelta = Gravity.Normalized; //Gravity.Normalized * (collisionMargin * 2);
|
Vector3 groundDelta = Gravity.Normalized; //Gravity.Normalized * (collisionMargin * 2);
|
||||||
//if (velocity.Y < 0f)
|
//if (velocity.Y < 0f)
|
||||||
// groundDelta = Gravity.Normalized * velocity.Y * Time.DeltaTime;
|
// groundDelta = Gravity.Normalized * velocity.Y * Time.DeltaTime;
|
||||||
TraceInfo traceGround = TracePlayer(Actor, position, position + groundDelta);
|
TraceInfo traceGround = TracePlayer(Actor as PlayerActor, position, position + groundDelta);
|
||||||
//Console.PrintDebug(1, true, "startSolid: " + traceGround.startSolid);
|
//Console.PrintDebug(1, true, "startSolid: " + traceGround.startSolid);
|
||||||
|
|
||||||
if (!traceGround.startSolid && traceGround.fraction < 1f &&
|
if (!traceGround.startSolid && traceGround.fraction < 1f &&
|
||||||
@@ -998,7 +1119,7 @@ namespace Game
|
|||||||
Console.Print("backoff: " + backoff);
|
Console.Print("backoff: " + backoff);
|
||||||
|
|
||||||
// retrace
|
// retrace
|
||||||
traceGround = TracePlayer(Actor, position, position + point);
|
traceGround = TracePlayer(Actor as PlayerActor, position, position + point);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!traceGround.startSolid && (traceGround.fraction >= 1f ||
|
if (!traceGround.startSolid && (traceGround.fraction >= 1f ||
|
||||||
@@ -1022,7 +1143,7 @@ namespace Game
|
|||||||
private bool OnJump(TraceInfo traceGround, ref Vector3 position, ref Vector3 velocity)
|
private bool OnJump(TraceInfo traceGround, ref Vector3 position, ref Vector3 velocity)
|
||||||
{
|
{
|
||||||
float jumpVel = jumpVelocity;
|
float jumpVel = jumpVelocity;
|
||||||
if (Time.GameTime - lastJumped < jumpBoostTime)
|
if (simulationTime - lastJumped < jumpBoostTime)
|
||||||
jumpVel += jumpBoostVelocity;
|
jumpVel += jumpBoostVelocity;
|
||||||
|
|
||||||
// Reset velocity from gravity
|
// Reset velocity from gravity
|
||||||
@@ -1052,7 +1173,7 @@ namespace Game
|
|||||||
Vector3 stairCheckVelocity = velocity.Normalized * (stepHeight / Time.DeltaTime);
|
Vector3 stairCheckVelocity = velocity.Normalized * (stepHeight / Time.DeltaTime);
|
||||||
stairCheckVelocity.Y = 0f;
|
stairCheckVelocity.Y = 0f;
|
||||||
|
|
||||||
SlideMoveHit blocked = StepSlideMove(Actor, ref stairCheckPosition, ref stairCheckVelocity, true);
|
SlideMoveHit blocked = StepSlideMove(Actor as PlayerActor, ref stairCheckPosition, ref stairCheckVelocity, true);
|
||||||
float movedUp = stairCheckPosition.Y - position.Y;
|
float movedUp = stairCheckPosition.Y - position.Y;
|
||||||
|
|
||||||
if (movedUp > 0 && blocked.HasFlag(SlideMoveHit.Step))
|
if (movedUp > 0 && blocked.HasFlag(SlideMoveHit.Step))
|
||||||
@@ -1064,7 +1185,7 @@ namespace Game
|
|||||||
|
|
||||||
if (!predicting)
|
if (!predicting)
|
||||||
// Avoid overlapping with recent landing sound
|
// Avoid overlapping with recent landing sound
|
||||||
if (Time.GameTime - lastLanded > 0.3)
|
if (simulationTime - lastLanded > 0.3)
|
||||||
PlayJumpLandSound(false, false);
|
PlayJumpLandSound(false, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user