process TODO.md step2

This commit is contained in:
SepComet
2026-03-28 15:02:40 +08:00
parent a0a8c0a89d
commit 4a152e765b
17 changed files with 450 additions and 42 deletions
+99 -23
View File
@@ -4,6 +4,54 @@ using Network.NetworkApplication;
using UnityEngine;
using Vector3 = UnityEngine.Vector3;
public static class ClientGameplayInputFlow
{
public static bool HasPlanarInput(Vector3 input)
{
return new Vector2(input.x, input.z).sqrMagnitude > 0f;
}
public static bool TryCreateMoveInput(string playerId, long tick, Vector3 input, bool stopMessagePending, out MoveInput message)
{
if (!HasPlanarInput(input) && !stopMessagePending)
{
message = null;
return false;
}
message = new MoveInput
{
PlayerId = playerId,
Tick = tick,
MoveX = input.x,
MoveY = input.z
};
return true;
}
public static ShootInput CreateShootInput(string playerId, long tick, Vector3 aimDirection, string targetId = "")
{
var planarDirection = new Vector3(aimDirection.x, 0f, aimDirection.z);
if (planarDirection.sqrMagnitude <= 0f)
{
planarDirection = Vector3.forward;
}
else
{
planarDirection.Normalize();
}
return new ShootInput
{
PlayerId = playerId,
Tick = tick,
DirX = planarDirection.x,
DirY = planarDirection.z,
TargetId = targetId ?? string.Empty
};
}
}
public class MovementComponent : MonoBehaviour
{
[SerializeField] private float _sendInterval = 0.05f;
@@ -26,7 +74,10 @@ public class MovementComponent : MonoBehaviour
private Vector3 _currentPos;
private float _lerpTime;
[SerializeField] private float _lerpRate = 0.1f;
private MoveInput _cachedInput;
private Vector3 _cachedMoveInput;
private Vector3 _lastAimDirection = Vector3.forward;
private bool _wasMovingLastFrame;
private bool _stopMessagePending;
public void Init(bool isControlled, Player master, int speed = 0, long serverTick = 0)
{
@@ -44,13 +95,33 @@ public class MovementComponent : MonoBehaviour
{
if (_isControlled)
{
_cachedInput = CaptureInput();
_cachedMoveInput = CaptureMovement();
var hasMovement = ClientGameplayInputFlow.HasPlanarInput(_cachedMoveInput);
if (hasMovement)
{
_lastAimDirection = _cachedMoveInput;
_stopMessagePending = false;
}
else if (_wasMovingLastFrame)
{
_stopMessagePending = true;
}
_wasMovingLastFrame = hasMovement;
var shootInput = CaptureShootInput();
if (shootInput != null)
{
NetworkManager.Instance.SendShootInput(shootInput);
}
if (Time.time - _lastSendTime > _sendInterval)
{
if (_cachedInput != null)
if (ClientGameplayInputFlow.TryCreateMoveInput(_master.PlayerId, Tick, _cachedMoveInput, _stopMessagePending, out var moveInput))
{
NetworkManager.Instance.SendMoveInput(_cachedInput);
NetworkManager.Instance.SendMoveInput(moveInput);
_predictionBuffer.Record(moveInput);
_stopMessagePending = false;
}
_lastSendTime = Time.time;
@@ -72,11 +143,7 @@ public class MovementComponent : MonoBehaviour
_hasServerState = false;
}
Simulate(_cachedInput);
if (_cachedInput != null)
{
_predictionBuffer.Record(_cachedInput);
}
Simulate(_cachedMoveInput);
}
else
{
@@ -98,27 +165,36 @@ public class MovementComponent : MonoBehaviour
ReplayPendingInputs(replayInputs);
}
private MoveInput CaptureInput()
private Vector3 CaptureMovement()
{
var input = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
if (input == Vector3.zero)
return new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical"));
}
private ShootInput CaptureShootInput()
{
if (!Input.GetMouseButtonDown(0))
{
return null;
}
return new MoveInput
{
PlayerId = _master.PlayerId,
Tick = Tick,
MoveX = input.x,
MoveY = input.z
};
return ClientGameplayInputFlow.CreateShootInput(_master.PlayerId, Tick, ResolveAimDirection());
}
private void Simulate(MoveInput input)
private Vector3 ResolveAimDirection()
{
var dir = input == null ? Vector3.zero : new Vector3(input.MoveX, 0f, input.MoveY);
_rigid.velocity = _speed * dir;
if (ClientGameplayInputFlow.HasPlanarInput(_lastAimDirection))
{
return _lastAimDirection;
}
var forward = _master != null ? _master.transform.forward : transform.forward;
var planarForward = new Vector3(forward.x, 0f, forward.z);
return ClientGameplayInputFlow.HasPlanarInput(planarForward) ? planarForward : Vector3.forward;
}
private void Simulate(Vector3 input)
{
_rigid.velocity = _speed * input;
if (_isControlled)
{
MainUI.Instance.OnClientPosChanged(_rigid.position);
@@ -182,4 +258,4 @@ public class MovementComponent : MonoBehaviour
MainUI.Instance.OnClientPosChanged(_rigid.position);
}
}
}
}
+16
View File
@@ -0,0 +1,16 @@
{
"name": "NetworkFramework",
"rootNamespace": "",
"references": [
"GUID:d972d56d6b084684b5b0666f4856da75"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 25ab7ef51eeef1e4ea6e24413cbabdff
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+17 -17
View File
@@ -13,16 +13,17 @@ public class NetworkManager : MonoBehaviour
private const int DefaultReliablePort = 8080;
private const int DefaultSyncPort = 8081;
public static NetworkManager Instance;
private SharedNetworkRuntime _networkRuntime;
private IPEndPoint _serverPoint;
private uint _sequence = 0;
private Task _networkDrainTask = Task.CompletedTask;
[SerializeField] private GameObject _wrongWindow;
[SerializeField] private bool _enableNetworkDiagnosticsOverlay = true;
[SerializeField] private string _serverIp = DefaultServerIp;
[SerializeField] private int _reliablePort = DefaultReliablePort;
[SerializeField] private int _syncPort = DefaultSyncPort;
public static NetworkManager Instance;
private SharedNetworkRuntime _networkRuntime;
private IPEndPoint _serverPoint;
private uint _sequence = 0;
private Task _networkDrainTask = Task.CompletedTask;
private void Awake()
{
@@ -197,24 +198,23 @@ public class NetworkManager : MonoBehaviour
Debug.Log($"[NetworkManager] Session {lifecycleEvent.PreviousState} -> {lifecycleEvent.CurrentState} ({lifecycleEvent.Kind}) {lifecycleEvent.Reason}");
}
public void SendMoveInput(string playerId, Vector3 input)
{
var message = new MoveInput
{
PlayerId = playerId,
MoveX = input.x,
MoveY = input.z
};
_networkRuntime.MessageManager.SendMessage(message, MessageType.MoveInput);
Debug.Log($"PlayerMoveSeq: {_sequence++}");
}
public void SendMoveInput(MoveInput message)
{
_networkRuntime.MessageManager.SendMessage(message, MessageType.MoveInput);
Debug.Log($"PlayerMoveSeq: {_sequence++}");
}
public void SendShootInput(string playerId, Vector3 direction, long tick = 0, string targetId = "")
{
SendShootInput(ClientGameplayInputFlow.CreateShootInput(playerId, tick, direction, targetId));
}
public void SendShootInput(ShootInput message)
{
_networkRuntime.MessageManager.SendMessage(message, MessageType.ShootInput);
Debug.Log($"PlayerShootSeq: {_sequence++}");
}
public void SendLoginRequest(string playerId, int speed)
{
var request = new LoginRequest()