This commit is contained in:
2023-04-10 16:29:20 +03:00
parent 7228c51dd7
commit 3b4d50e75e
8 changed files with 242 additions and 109 deletions

View File

@@ -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)

View File

@@ -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");

View File

@@ -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);
} }

View 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()
{
}
}
}

View File

@@ -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>();

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;
@@ -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;