private void OnServerTileReached(Vector3Int newPos) { if (!isPushing && pushRequestQueue.Count == 0) { return; } // Logger.LogTraceFormat( "{0}: {1} is reached ON SERVER", Category.PushPull, gameObject.name, pos ); isPushing = false; if (pushTarget != TransformState.HiddenPos && pushTarget != newPos && !MatrixManager.IsFloatingAt(gameObject, newPos)) { //unexpected pos reported by server tile (common in space, space ) pushRequestQueue.Clear(); } CheckQueue(); }
///Lerping; simulating space walk by server's orders or initiate/stop them on client ///Using predictedState for your own player and playerState for others private void CheckMovementClient() { PlayerState state = isLocalPlayer ? predictedState : playerState; if (!ClientPositionReady) { //PlayerLerp Vector3 targetPos = MatrixManager.WorldToLocal(state.WorldPosition, MatrixManager.Get(matrix)); transform.localPosition = Vector3.MoveTowards(transform.localPosition, targetPos, playerMove.speed * Time.deltaTime); //failsafe if (playerState.NoLerp || Vector3.Distance(transform.localPosition, targetPos) > 30) { transform.localPosition = targetPos; } } playerState.NoLerp = false; bool isFloating = MatrixManager.IsFloatingAt(Vector3Int.RoundToInt(state.WorldPosition)); //Space walk checks if (isPseudoFloatingClient && !isFloating) { // Debug.Log( "Stopped clientside floating to avoid going through walls" ); //stop floating on client (if server isn't responding in time) to avoid players going through walls predictedState.Impulse = Vector2.zero; //Stopping spacewalk increases move number predictedState.MoveNumber++; //Zeroing lastDirection after hitting an obstacle LastDirection = Vector2.zero; if (!isFloatingClient && playerState.MoveNumber < predictedState.MoveNumber) { Debug.Log($"Finished unapproved flight, blocking. predictedState:\n{predictedState}"); //Client figured out that he just finished spacewalking //and server is yet to approve the fact that it even started. StartCoroutine(BlockMovement()); } } if (isFloating) { if (state.Impulse == Vector2.zero && LastDirection != Vector2.zero) { if (pendingActions == null || pendingActions.Count == 0) { // Debug.LogWarning( "Just saved your ass; not initiating predictive spacewalk without queued actions" ); LastDirection = Vector2.zero; return; } //client initiated space dive. state.Impulse = LastDirection; if (isLocalPlayer) { predictedState.Impulse = state.Impulse; } else { playerState.Impulse = state.Impulse; } Debug.Log($"Client init floating with impulse {LastDirection}. FC={isFloatingClient},PFC={isPseudoFloatingClient}"); } //Perpetual floating sim if (ClientPositionReady) { //Extending prediction by one tile if player's transform reaches previously set goal Vector3Int newGoal = Vector3Int.RoundToInt(state.Position + (Vector3)state.Impulse); if (!isLocalPlayer) { playerState.Position = newGoal; } predictedState.Position = newGoal; } } }