Download

Determine if player is facing object - Undesired results!

I’m terrible at 3D Math, so I’m having trouble wrapping my head around how I need to do this properly.

I have a 3rd Person game, and I just want the player to be facing the general direction of an object before they can interact with it. Problem is, the math that I’m finding to do this is assuming more of a 1st person perspective.


bool ABLTPlayerPawn::IsValidUsable(AActor* UsableItem)
{
	//Doesn't use UsableInterface
	if (!UsableItem->GetClass()->ImplementsInterface(UBLTUsableInterface::StaticClass())) 
		return false;
	//Too far away
	if (FMath::Abs((GetActorLocation() - UsableItem->GetActorLocation()).Size()) > 120)
		return false;

	FVector ForwardVector = GetActorForwardVector();
	FVector ObjectLoc = (UsableItem->GetActorLocation() - GetActorLocation());
	//FVector ObjectLoc = (GetActorLocation() - UsableItem->GetActorLocation());

	float DotProduct = FVector::DotProduct(ForwardVector, ObjectLoc.SafeNormal());
	
	
	UE_LOG(LogBLT, All, TEXT("%f"),DotProduct);

	//Item returns false
	if(!IBLTUsableInterface::Execute_IsUsable(UsableItem))
		return false;

	return true;
}

DotProduct01.jpg

Simple code that I believe is behaving correctly (but not really sure) to determine if the player is facing the object. Problem is, since it’s using a 3 Vector and the object is on the floor, the results never really add up the right way. Standing infront of the box gives off results of 0.265, which from what I understand I should be at 1 if I’m facing the object.

I have to raise the box to be around center of the capsule (player location) to get my results to be closer to 1.

a8b9ecbe5037a0b0271f962446685f696a6dd1f9.jpeg

This isn’t really desired behavior because I don’t want the pawn to really have to be facing down to look at it, nor do I want the player camera to have to look at the object. I just want the player to be facing properly in the YAW rotation axis for more of a general direction sort of style.

Any help would be appreciated!




// Change:
float DotProduct = FVector::DotProduct(ForwardVector, ObjectLoc.SafeNormal());

// To:
float DotProduct = FVector::DotProduct(ForwardVector.GetSafeNormal2D(), ObjectLoc.GetSafeNormal2D());



So here is how DotProduct works.
Consider that picture not in scale.
46292415a40e8270ca84333ca13277721ef70373.jpeg

So maybe you want zero out Z component of vector ObjectLoc like so:



...
FVector ObjectLoc = (UsableItem->GetActorLocation() - GetActorLocation());
ObjectLoc.Z = 0;
float DotProduct = FVector::DotProduct(ForwardVector, ObjectLoc.SafeNormal());
...


Keep in mind that this code works unless ForwardVector lays in XY plane.

I took this approach, and it worked wonders. Thanks!

Also thanks to RxDesu for the visualization, that helped a lot.