So I got slightly distracted when creating my puzzle, and ended up spending a few days playing with box brushes and making a few modifications to my platforms…
As can be seen, I altered my platforms to allow them to move between more than 2 points, stored in an array of FVectors. I also added to possibility to have an initial delay before the platform moves. This was to allow for me to have 3 platforms travelling along the same circular route, without having to manually place each one a third of the way around the route, which could have required a whole bunch of extra calculations and setup.
I need to tweak my platform timings slightly so that they line up better, and I also need to tweak my character movement component jumping variables to make the whole thing a bit more challenging, but I’ll probably leave that for a later date cos I’ve got to be getting on with the rest of the course .
BeginPlay code
void AMovingPlatform::BeginPlay()
{
// Call the base class
Super::BeginPlay();
if (HasAuthority())
{
existsOnServer = true;
SetReplicates(true);
SetReplicateMovement(true);
}
StartLocation = GetActorLocation();
/*TargetLocation = GetTransform().TransformPosition(RelativeTargetLocation);
TargetDistance = RelativeTargetLocation.Size();*/
if (RelativeWaypointLocations.Num() > 0)
{
WaypointLocations.Add(StartLocation);
for (const FVector RelativeWypntLoc : RelativeWaypointLocations)
{
FVector WypntLoc = GetTransform().TransformPosition(RelativeWypntLoc);
WaypointLocations.Add(WypntLoc);
}
for (int32 i = 0; i < WaypointLocations.Num(); i++)
{
if (i == (WaypointLocations.Num() - 1))
{
LegDistances.Add((WaypointLocations[0] - WaypointLocations[i]).Size());
}
else
{
LegDistances.Add((WaypointLocations[i + 1] - WaypointLocations[i]).Size());
}
}
PointA = WaypointLocations[PointA_Index];
PointB = WaypointLocations[PointB_Index];
LegDistance = LegDistances[PointA_Index];
}
if (PauseMovement)
{
FTimerDelegate MvmtDelayTimerDelegate;
bool MvmtDelayTimerBool = false;
MvmtDelayTimerDelegate.BindUFunction(this, FName("SetPauseMovement"), MvmtDelayTimerBool);
GetWorldTimerManager().SetTimer(MvmtDelayTimerHandle, MvmtDelayTimerDelegate, DelayDuration, false);
}
}
Tick code
void AMovingPlatform::Tick(float DeltaTime)
{
// Call the base class
Super::Tick(DeltaTime);
if (existsOnServer)
{
if (WaypointLocations.Num() > 1 && !PauseMovement)
{
FVector Location = GetActorLocation();
float DistanceFromStart = (Location - PointA).Size();;
if (DistanceFromStart >= LegDistance)
{
PointA_Index++;
PointB_Index = PointA_Index + 1;
// UE_LOG(LogTemp, Display, TEXT("PointA_Index= %d . PointB_Index = %d"), PointA_Index, PointB_Index);
if (PointA_Index == WaypointLocations.Num() - 1)
{
PointB_Index = 0;
}
else if (PointA_Index > WaypointLocations.Num() - 1)
{
PointA_Index = 0;
PointB_Index = PointA_Index + 1;
}
PointA = WaypointLocations[PointA_Index];
PointB = WaypointLocations[PointB_Index];
LegDistance = LegDistances[PointA_Index];
UE_LOG(LogTemp, Display, TEXT("PointA= %s . PointB = %s"), *PointA.ToString(), *PointB.ToString());
}
FVector Direction = (PointB - PointA).GetSafeNormal();
FVector Velocity = Speed * Direction;
Location += Velocity * DeltaTime;
SetActorLocation(Location);
}
}
}