diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 6a23dcd..ec9913a 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -7,7 +7,9 @@ "Bash(dotnet build:*)", "Bash(dotnet test:*)", "Bash(dotnet Temp/Bin/Debug/Network.EditMode.Tests/Network.EditMode.Tests.dll)", - "Bash(openspec list:*)" + "Bash(openspec list:*)", + "Bash(git add:*)", + "Bash(git commit:*)" ] }, "outputStyle": "default" diff --git a/Assets/Prefabs/Player.prefab b/Assets/Prefabs/Player.prefab index ce3d1b9..3e9e355 100644 --- a/Assets/Prefabs/Player.prefab +++ b/Assets/Prefabs/Player.prefab @@ -283,6 +283,7 @@ GameObject: - component: {fileID: 6308356813655391140} - component: {fileID: 6308356813655391139} - component: {fileID: 6308356813655391138} + - component: {fileID: 2373500463057886562} m_Layer: 0 m_Name: Main Camera m_TagString: MainCamera @@ -364,6 +365,50 @@ AudioListener: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 6308356813655391137} m_Enabled: 1 +--- !u!114 &2373500463057886562 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6308356813655391137} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_RenderShadows: 1 + m_RequiresDepthTextureOption: 2 + m_RequiresOpaqueTextureOption: 2 + m_CameraType: 0 + m_Cameras: [] + m_RendererIndex: -1 + m_VolumeLayerMask: + serializedVersion: 2 + m_Bits: 1 + m_VolumeTrigger: {fileID: 0} + m_VolumeFrameworkUpdateModeOption: 2 + m_RenderPostProcessing: 0 + m_Antialiasing: 0 + m_AntialiasingQuality: 2 + m_StopNaN: 0 + m_Dithering: 0 + m_ClearDepth: 1 + m_AllowXRRendering: 1 + m_AllowHDROutput: 1 + m_UseScreenCoordOverride: 0 + m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0} + m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0} + m_RequiresDepthTexture: 0 + m_RequiresColorTexture: 0 + m_Version: 2 + m_TaaSettings: + m_Quality: 3 + m_FrameInfluence: 0.1 + m_JitterScale: 1 + m_MipBias: 0 + m_VarianceClampScale: 0.9 + m_ContrastAdaptiveSharpening: 0 --- !u!1 &6308356814245253661 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/ClientAuthoritativePlayerState.cs b/Assets/Scripts/ClientAuthoritativePlayerState.cs index e28d82f..886b3f0 100644 --- a/Assets/Scripts/ClientAuthoritativePlayerState.cs +++ b/Assets/Scripts/ClientAuthoritativePlayerState.cs @@ -121,7 +121,7 @@ public sealed class ClientAuthoritativePlayerStateSnapshot public int Hp { get; } - public Quaternion RotationQuaternion => Quaternion.Euler(0f, NormalizeDegrees(90f - Rotation), 0f); + public Quaternion RotationQuaternion => Quaternion.Euler(0f, NormalizeDegrees(Rotation), 0f); private static float NormalizeDegrees(float degrees) { diff --git a/Assets/Scripts/ClientGameplayInputFlow.cs b/Assets/Scripts/ClientGameplayInputFlow.cs index c41e6d3..b1da15b 100644 --- a/Assets/Scripts/ClientGameplayInputFlow.cs +++ b/Assets/Scripts/ClientGameplayInputFlow.cs @@ -23,7 +23,7 @@ public static class ClientGameplayInputFlow { PlayerId = playerId, Tick = tick, - TurnInput = -input.x, + TurnInput = input.x, ThrottleInput = input.z }; return true; diff --git a/Assets/Scripts/MovementComponent.cs b/Assets/Scripts/MovementComponent.cs index 1f097b4..b21a47f 100644 --- a/Assets/Scripts/MovementComponent.cs +++ b/Assets/Scripts/MovementComponent.cs @@ -222,7 +222,7 @@ public class MovementComponent : MonoBehaviour { Debug.Log( $"[Simulate] frame={Time.frameCount} input=({input.x:F2},{input.z:F2}) accum={_simulationAccumulator:F4}"); - ApplyTankMovement(-input.x, input.z, kServerSimulationStepSeconds); + ApplyTankMovement(input.x, input.z, kServerSimulationStepSeconds); //ApplyTankMovement(-input.x, input.z, kServerSimulationStepSeconds); diff --git a/Assets/Scripts/Network/NetworkHost/ServerAuthoritativeMovementCoordinator.cs b/Assets/Scripts/Network/NetworkHost/ServerAuthoritativeMovementCoordinator.cs index 3154bf3..484ed73 100644 --- a/Assets/Scripts/Network/NetworkHost/ServerAuthoritativeMovementCoordinator.cs +++ b/Assets/Scripts/Network/NetworkHost/ServerAuthoritativeMovementCoordinator.cs @@ -174,6 +174,11 @@ namespace Network.NetworkHost IntegrateState(state, configuration.SimulationInterval); } + foreach (var state in statesByPeer.Values) + { + state.HasInputThisFrame = false; + } + accumulatedBroadcastTime += configuration.SimulationInterval; while (accumulatedBroadcastTime >= configuration.BroadcastInterval) { @@ -362,6 +367,7 @@ namespace Network.NetworkHost state.LastAcceptedMoveTick = input.Tick; state.InputX = ClampInput(input.TurnInput); state.InputY = ClampInput(input.ThrottleInput); + state.HasInputThisFrame = true; if (state.InputY == 0f) { @@ -390,6 +396,16 @@ namespace Network.NetworkHost return; } + if (!state.HasInputThisFrame) + { + state.InputX = 0f; + state.InputY = 0f; + state.VelocityX = 0f; + state.VelocityY = 0f; + state.VelocityZ = 0f; + return; + } + var turnInput = ClampInput(state.InputX); var throttleInput = ClampInput(state.InputY); if (turnInput != 0f) diff --git a/Assets/Scripts/Network/NetworkHost/ServerAuthoritativeMovementState.cs b/Assets/Scripts/Network/NetworkHost/ServerAuthoritativeMovementState.cs index dc932f1..29d9b27 100644 --- a/Assets/Scripts/Network/NetworkHost/ServerAuthoritativeMovementState.cs +++ b/Assets/Scripts/Network/NetworkHost/ServerAuthoritativeMovementState.cs @@ -46,6 +46,8 @@ namespace Network.NetworkHost public float InputY { get; internal set; } + public bool HasInputThisFrame { get; internal set; } + public float Speed { get; internal set; } } }