Thanks for the quick reply. It gets initially set in the Server_SendMove_Implementation method, which is the only other place it is present, that I haven’t shown above. This sends a FGoKartMove Move to the server reliably and with validation. The Server_SendMove_Validate method simply returns true at this point.
void AGoKart::Server_SendMove_Implementation(FGoKartMove Move)
ServerState.LastMove = Move;
ServerState.Transform = GetActorTransform();
ServerState.Velocity = Velocity;
Here is the whole header file too. The main declarations of interest are the two structs FGoKartMove and FGoKartState (which holds the state of the struct FGoKartMove in LastMove), as well as the array of FGoKartMoves UnacknowledgedMoves. Also the FGoKartState ServerState, which is replicated using the OnRep_ServerState method which is shown in the first post.
// Fill out your copyright notice in the Description page of Project Settings.
class KRAZYKARTS_API AGoKart : public APawn
// Sets default values for this pawn's properties
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// The mass of the car (kg)
float Mass = 1000;
// The force applied to the car when the throttle is fully down (Newton (N))
float MaxDrivingForce = 10000;
// Higher means more drag (kg/m)
float DragCoefficient = 16;
// Higher means more rolling resistance
float RollingResistanceCoefficient = 0.015;
// Minimum radius of the car turning circle at full lock (m)
float MinTurningRadius = 10;
void MoveForward(float Value);
void MoveRight(float Value);
UFUNCTION(Server, Reliable, WithValidation) // Server RPC function which is Reliable (always execute)
void Server_SendMove(FGoKartMove Move);
FGoKartMove CreateMove(float DeltaTime);
void SimulateMove(const FGoKartMove Move);
void ClearAcknowledgedMoves(FGoKartMove LastMove);
void UpdateLocationFromVelocity(float DeltaTime);
void ApplyRotation(float DeltaTime, float SteeringThrowInput);
The other method of interest is ClearAcknowledgedMoves which takes a FGoKartState LastMove and then checks all the unacknowledged moves. If the unacknowledged Move’s Time field has a higher time than the LastMove’s Time field, this means it hasn’t been processed by the server yet. Therefore adding the Move to the NewMoves array of FGoKartMoves. After all the Moves have been processed in the UnacknowledgedMoves array, this array is set to the contents of the NewMoves array.
P.S. I’ve done a check of the ServerState LastMove’s Time field before it gets passed to the ClearAcknowledgedMoves method, and it’s 0 as well. So not to do with any incorrect passing to the method in OnRep_ServerState.
P.P.S. Checked the ServerState LastMove’s Time field in Server_SendMove_Implementation and its giving actual values. So must be somewhere after this it is getting not passed correctly.
TLDR: The ServerState is getting sent to the server correctly, but isn’t correct (Time field missing) when replicated.