VectorPlaneProject on Normal result is off

Hello!

I am trying to do something that should be relatively simple. I have a vector that I want to project onto a plane.
I have the plane normal N that I get as result of a linetrace to the ground. I would expect that projecting my vector onto the plane defined by N, I’d get a vector that is parallel to the ground. But the result is off by quite a bit (see image).

320107-screenshot-2020-10-26-at-101625.png

Here’s the code I am using:

    FHitResult Hit(1.f);
    FCollisionQueryParams CollisionParams;
        
    // Linetrace to the ground (in this case from an Actor's Location)
    bool bHit = GetWorld()->LineTraceSingleByChannel(Hit, GetActorLocation(), GetActorLocation() - FVector(0, 0, 200), ECC_Visibility, CollisionParams);
        
    // The vector V I want to project
    FVector V = GetCharacterOwner()->GetActorForwardVector();
        
    if (bHit) {
            FVector Normal = Hit.Normal.GetSafeNormal();
            FVector Projection = FVector::VectorPlaneProject(SlidingAcceleration, Normal2D);
        }

EDIT: “SlidingAcceleration” in the code snippet above should be “V”. I am trying to find a way to edit the question but can’t find one.

“SlidingAcceleration” should be “V” in the snippet above. I’d love to fix that but I cannot find a way to do so

Hi sorry for necroing an old thread but I ran across this while trying to fix my own issue, and ended up sanity checking the FVector::VectorPlaneProject().

For me, your case works just fine. I did notice that in your code you pass the VectorPlaneProject() an argument named Normal2D instead of the Normal you just defined above the line. Maybe that was your issue?

Below you can see my near identical code which produces expected results:

FHitResult Hit(1.f);
FCollisionQueryParams CollisionParams;

// Linetrace to the ground (in this case from an Actor's Location)
const bool bHit = GetWorld()->LineTraceSingleByChannel(Hit, GetCharacterOwner()->GetActorLocation(), GetCharacterOwner()->GetActorLocation() - FVector(0, 0, 200.0f), ECC_Visibility, CollisionParams);

if (bHit) 
{
	// The vector V I want to project
	FVector V = GetCharacterOwner()->GetActorForwardVector();

	FVector HitNormal = Hit.Normal;

	FVector Projection = FVector::VectorPlaneProject(V, HitNormal);

	DrawDebugSphere(GetWorld(), Hit.ImpactPoint, 6.06, 6, FColor::Red, false);
	DrawDebugDirectionalArrow(GetWorld(), Hit.ImpactPoint, Hit.ImpactPoint + HitNormal * 50.0f, 50.0f, FColor::Green, false, -1.0f, 0, 2.0f);

	DrawDebugDirectionalArrow(GetWorld(), Hit.ImpactPoint, Hit.ImpactPoint + V * 50.0f, 50.0f, FColor::Cyan, false, -1.0f, 0, 2.0f);
	DrawDebugDirectionalArrow(GetWorld(), Hit.ImpactPoint, Hit.ImpactPoint + Projection * 50.0f, 50.0f, FColor::Blue, false, -1.0f, 0, 2.0f);
}

and here’s how it looks in-game with the debug lines drawn. I used the colours from your screenshot so cyan is the Actor’s forward direction and blue is the projected vector on the angled plane.

Alright back to figuring out my own issue :smiley: