Hi, great tutorials so far.
I would like to share some small performance improvements to the solution provided.

There is no need to recalculate JourneyLength on every tick. It is always the same value so we can create a member variable to store it.

Actually, we don’t even need to calculate the distance between the two locations using the Size function. We can use the DistSquared function from FVector which is faster as it does not calculate a square root and we just need to compare distances, so we are good.

There is no need either to obtain the Direction vector on every tick. We can store it at BeginPlay and invert it every time we reach the target location.
void AMovingPlatform::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
if (HasAuthority())
{
FVector CurrentLocation = GetActorLocation();
// Check if we have reached the target.
if (FVector::DistSquared(GlobalStartLocation, CurrentLocation) >= SquareDistance)
{
// Swap the target and start locations.
Swap(GlobalStartLocation, GlobalTargetLocation);
// Invert the movement direction.
MovementDirection *= 1;
}
else
{
// Keep moving towards the target.
SetActorLocation(CurrentLocation + (MovementDirection * Speed * DeltaSeconds));
}
}
}
void AMovingPlatform::BeginPlay()
{
Super::BeginPlay();
if (HasAuthority())
{
SetReplicates(true);
SetReplicateMovement(true);
GlobalStartLocation = GetActorLocation();
// We need to transform the LOCAL TargetLocation to Global space.
GlobalTargetLocation = GetTransform().TransformPosition(TargetLocation);
MovementDirection = (GlobalTargetLocation  GlobalStartLocation).GetSafeNormal();
SquareDistance = FVector::DistSquared(GlobalTargetLocation, GlobalStartLocation);
}
}
It would be also possible to calculate the time that will take to reach the target position at the BeginPlay and work with that… Can anyone think about any cons about that last approach?
Thanks!