Problem with translate Blueprint into C++

I’m trying to translate Blueprint function into C++.

My Blueorint Function:



C++ code:

void ARPG_TutorialCharacter::VaultC()
{
	for (int i = 0; i <= 2; i++) {
		FVector TraceStart = GetActorLocation();
		TraceStart.Z += i * 30;

		FVector TraceEnd = UKismetMathLibrary::GetForwardVector(GetActorRotation());
		TraceEnd *= 180.0;
		TArray<AActor*, FDefaultAllocator> IgnoredActors;
		FHitResult TraceResults;

		bool OutHit = UKismetSystemLibrary::SphereTraceSingle(this, TraceStart, TraceEnd + TraceStart, 5.0, ETraceTypeQuery::TraceTypeQuery1, false, IgnoredActors, EDrawDebugTrace::ForDuration, TraceResults, true);
		if (OutHit) {
			for (int j = 0; j <= 5; j++) {
				FVector SubTraceStart = TraceResults.Location + FVector(0.0, 0.0, 100.0);
				
				FVector SubTraceEnd = UKismetMathLibrary::GetForwardVector(GetActorRotation());
				SubTraceEnd *= j * 50;

				if (UKismetSystemLibrary::SphereTraceSingle(this, SubTraceStart + SubTraceEnd, SubTraceStart + SubTraceEnd - FVector(0.0,0.0,100.0), 10.0, ETraceTypeQuery::TraceTypeQuery1, false, IgnoredActors, EDrawDebugTrace::ForDuration, TraceResults, true)) {
					if (j == 0) {

					}
				}
			
			}
			
			break;
		}

	}
}

Problem is on lines

for (int j = 0; j <= 5; j++) {
	FVector SubTraceStart = TraceResults.Location + FVector(0.0, 0.0, 100.0);
	
	FVector SubTraceEnd = UKismetMathLibrary::GetForwardVector(GetActorRotation());
	SubTraceEnd *= j * 50;

	if (UKismetSystemLibrary::SphereTraceSingle(this, SubTraceStart + SubTraceEnd, SubTraceStart + SubTraceEnd - FVector(0.0,0.0,100.0), 10.0, ETraceTypeQuery::TraceTypeQuery1, false, IgnoredActors, EDrawDebugTrace::ForDuration, TraceResults, true)) {
		if (j == 0) {

		}
	}

}

Spheres are created in incorrect positions. It seems to me that the problem is with the calculations

not sure why you are calling UKismetMathLibrary::GetForwardVector()
the actor already has GetActorForwardVector()
you generate a TArray<AActor*> (default allocator is almost always assumed based on default Value) but then never add anything to it so why create it if it is going to be empty? you can put in nullptr to the argument if you are not going to add anything into it.
in both of your trace setups you start doing math, but then stop mid way, and do the math inline in the function call. in C++ both are “acceptable” but please pick one or the other. (for space savings inline the math, for readability do the math outside especially if these are local/temp variables anyways that are going in and out of scope with every loop iteration)
you also do an inline call to the SphereTrace in the if in one but then not the other, again pick one (the bool is created regardless, but unless you need it for use somewhere outside the if don’t worry about allocating it)
for your second for loop relative to your blueprint, wouldn’t the break signify the second loop would never happen because the first loop was broken out of, while in your C++ the break happens after the second loop has completed. these are 2 different flow directions.

what do you mean by “incorrect position” ? is it too high, too low, too close, too far, somewhere completely unexpected?

1 Like

this do nothing

maybe your “break” is in the wrong place

The reason of this issue is when I call UKismetSystemLibrary::SphereTraceSingle inside second loop it was passed TraceResults in OutHit argument, so location was changed. I created a new variable and passed it to this function

Here is code that works:

void ARPG_TutorialCharacter::VaultC()
{
	FHitResult TraceResults;
	TArray<AActor*, FDefaultAllocator> IgnoredActors;

	for (int i = 0; i <= 2; i++) {
		FVector TraceStart = GetActorLocation();
		TraceStart.Z += i * 30;

		FVector TraceEnd = GetActorForwardVector();
		TraceEnd *= 180.0;
		
		if (UKismetSystemLibrary::SphereTraceSingle(this, TraceStart, TraceEnd + TraceStart, 5.0, ETraceTypeQuery::TraceTypeQuery1, false, IgnoredActors, EDrawDebugTrace::ForDuration, TraceResults, true)) {

			break;
		}
	}

	FHitResult SubTraceResults;
	for (int j = 0; j <= 5; j++) {
		FVector SubTraceStart = TraceResults.Location + FVector(0.0, 0.0, 100.0);
		//GEngine->AddOnScreenDebugMessage(-1, 15.0, FColor::Black, FString::Printf(TEXT("X = %d"), TraceResults.Location.X));
		//GEngine->AddOnScreenDebugMessage(-1, 15.0, FColor::Black, FString::Printf(TEXT("Y = %d"), TraceResults.Location.Y));
		//GEngine->AddOnScreenDebugMessage(-1, 15.0, FColor::Black, FString::Printf(TEXT("Z = %d"), TraceResults.Location.Z));

		
		FVector SubTraceEnd = GetActorForwardVector();
		SubTraceEnd *= (j * 50);


		if (UKismetSystemLibrary::SphereTraceSingle(this, SubTraceStart + SubTraceEnd, SubTraceStart + SubTraceEnd - FVector(0.0, 0.0, 100.0), 10.0, ETraceTypeQuery::TraceTypeQuery1, false, IgnoredActors, EDrawDebugTrace::ForDuration, SubTraceResults, true)) {
			if (j == 0) {

			}
		}

	}
}

Now you can remove all this…

that and nothing is the same

Example:

if(condition)
{
     //do something
}

well, you are doing nothing there