Caution: Line Trace does not collide with sky sphere; UGameplayStatics::SuggestProjectileVelocity will always return true

The line trace used the in lecture, even with a 100,000 Km range will return a hit location of (0.f,0.f,0.f) when aimng at the sky . This will cause UGameplayStatics::SuggestProjectileVelocity to always return true, and confuse the fk* out of you.

The source of the bug i believe is here

 if (GetWorld()->LineTraceSingleByChannel(
	 HitResult,
	 StartLocation,
	 EndLocation,
	 ECollisionChannel::ECC_Visibility))
 {
	 outHitLocation = HitResult.Location;

For some reason visibility doesn’t return the sky sphere, so the only way you can tell if SuggestProjectileVelocity is working correctly when expected to fail is by setting a very low projectile speed that cannot hit the range of the edge of your map.
To make things more confusing, behind the scenes in the lecture he must have changed his launch projectile speed to something very low (previously it was about 3,000 m/s), but you do not observe this until you watch to very end of the video where you see his output results reflecting that of low velocity. (except for the sky where in our version it doesnt work)

I suggest changing your code logs to reflect this:

	bool bHaveAimSolution = UGameplayStatics::SuggestProjectileVelocity
		(
		this,
		outLaunchVelocity,
		StartLocation,
		AimLocation,
		LaunchSpeed,
		false,
		0.f,
		0,
		ESuggestProjVelocityTraceOption::DoNotTrace,
		FCollisionResponseParams::DefaultResponseParam,
		ActorList,
		true);

	if (bHaveAimSolution && AimLocation != FVector(0.f)) {
		FVector SuggestedDirection = outLaunchVelocity.GetSafeNormal();
		MoveBarrelTowards(SuggestedDirection);
		auto time = GetWorld()->GetTimeSeconds();
		UE_LOG(LogTemp, Warning, TEXT("%s %f Aim solution found for world location %s. Suggested Direction: %s .  Suggested Veolocity: %s"), *GetOwner()->GetName(), time, *AimLocation.ToString(),*SuggestedDirection.ToString(), *outLaunchVelocity.ToString())
	}
	else if (AimLocation == FVector(0.f)) {
		UE_LOG(LogTemp, Warning, TEXT("%s %f Did not input an end location greater then 0.f,0.f,0.f"), *GetOwner()->GetName(), GetWorld()->GetTimeSeconds())
	}
	else {
		UE_LOG(LogTemp, Warning, TEXT("%s %f No valid suggested velocity found"), *GetOwner()->GetName(), GetWorld()->GetTimeSeconds())
	}

This way you can tell if the aim location you send in is location (0,0,0), which is always true when you aim at the sky. This will prevent incorrect validation of something like, ‘bIsReachable’, in the future.

There is another strange difference from the current unreal code and the lecture’s If you notice I filled in all the variables for SuggestProjectileVelocity. In the video he says you do not need to set many of these; but if you try not setting ANY of them your program will return errors. If anyone knows why my compiler is telling me these default values must be filled in, please let me know, or if you get the same problem.

If I recall correctly this is to do with the way Ben has his GetSightRayHitLocation function as it will always return true. Eventually this is fixed later on so it looks like this

if (GetLookDirection(ScreenLocation, LookDirection))
{
	// Line-trace along that LookDirection, and see what we hit (up to max range)
	return GetLookVectorHitLocation(LookDirection, HitLocation);
}
return false;

hey that fixed it thanks, but i dont get why does SuggestProjectileVelocity return false for him in this lecture if his code should be working like mine?

did i somehow miss him do the fix you posted or maybe, did he do this fix without telling us bout it yet?

Actually technically this doesnt fix it because it just prevents SuggestProjectileVelocity from even being called at all, instead of calling it with end location 0,0,0.

It should be called on the sky sphere hit location. So this prevents the problem, but does not fix the problem.

OH WAIT i just realized, the sky sphere location must have a position of 0,0,0. But still it doesnt make sense that it works for Ben in the video

The solution is actually to lower the tanks line trace range to something that cannot hit the sky sphere, or else it will return position (0.f,0.f,0.f), which is the likely position of your sky sphere

Actually, the solution WOULD be to set the tank’s line trace range to less(so it doesnt return the sky sphere at position 0,0,0), but then this would either leave you with an uninitialized HitResult vector, or leave you setting the HitResult to 0.f to prevent this. This should still return an empty vector, along with returning false.

The PROBLEM is that the code at this stage is faulty, but as of now it seems that:

^Doing this prevents the stack of events that causes the check from even being called at all.
The problem with this is that Ben has never instructed us to do this, unless I somehow missed it, and makes it a mystery why Ben’s code in the video works when ours doesnt.

^So that is the temporary solution until someone figures out why it works in Bens video code but not ours.

I’m confused by what you’re saying. It doesn’t get a hit result for the sky sphere, if GetLookVectorHitLocation is false then we set the HitLocation to (0,0,0)

FHitResult HitResult;
auto StartLocation = PlayerCameraManager->GetCameraLocation();
auto EndLocation = StartLocation + (LookDirection * LineTraceRange);
if (GetWorld()->LineTraceSingleByChannel(
		HitResult,
		StartLocation,
		EndLocation,
		ECollisionChannel::ECC_Camera)
	)
{
	HitLocation = HitResult.Location;
	return true;
}
HitLocation = FVector(0);
return false; // Line trace didn't succeed

Privacy & Terms