'Simple' Puzzle

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 :sweat_smile: .

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);
		}
	}
	
}
1 Like

I like refactoring to bring everything back in when there’s multiple blocks as it feels good.

You can for example do…

if (!existsOnServer) return; 

if (WaypointLocations.Num() > 1 && !PauseMovement) {...}

instead to avoid pushing everything to the right another block. They would then both follow the same line down instead of having that second one indented further.

You might be able to with others, I’m not even going to spend one second thinking about the next one that I added in above for example. You can’t do it for everything, but where it makes a lot of sense you can.

I also left off the {}'s as that’s my preference for certain things like this. You must use {}'s for multiple lines of code.

Just a thought. It looks good though :wink:

I did a refactor straight after posting, and converted most of the code in BeginPlay into a SetUpWaypoints() function, and most of the code in Tick into a Move() function.

I hadn’t thought of using a return when checking existisOnServer though, that seems quite useful for making it nicer to read. Thanks!

Privacy & Terms