Hi,
Well that made me review my math a bit, here is the code I used in C++ to make this work :
void ATestActor::StickOnGround()
{
//Grab a ref to the world here
UWorld* world = UJotunnMain::Instance->GetWorld();
FHitResult hitResultTrace;
FCollisionQueryParams queryParams;
FCollisionObjectQueryParams objQueryParams;
queryParams.AddIgnoredActor(this);
FVector under;
FVector newUp;
FVector newForward;
FVector newRight;
//Trace to get the floor normal under your actor
if (world->LineTraceSingle(hitResultTrace, GetActorLocation() + FVector::UpVector*400.0f, GetActorLocation() - FVector::UpVector*2000.0f, queryParams, objQueryParams))
{
under = hitResultTrace.ImpactPoint;
newUp = hitResultTrace.ImpactNormal;
}
//Some math to get the new Axis
FVector currentRightVect = GetActorRightVector();
newForward = FVector::CrossProduct(currentRightVect, newUp);
newRight = FVector::CrossProduct(newUp, newForward);
//Build the new transform!
FTransform newTransform(newForward, newRight, newUp, under);
SetActorTransform(newTransform);
}
I guess you could replicate that in BP and you will be good to go. Basically, the trick I used was to recreate your actor transform. Since you know the new Up vector (The hit Normal of the floor, you only need to find out the new Forward Vector, and Rigth Vector)
To get those, you can do a Cross Product of your new Up with the current Right to get the new forward.
Once you have the new forward, you can use it to get the new Right.
//Some math to get the new Axis
FVector currentRightVect = GetActorRightVector();
newForward = FVector::CrossProduct(currentRightVect, newUp);
newRight = FVector::CrossProduct(newUp, newForward);
Then, simply construct the new Transform with that info :
//Build the new transform!
FTransform newTransform(newForward, newRight, newUp, under);
SetActorTransform(newTransform);
In BP, you can use the Make Rotation From Axes and Make Transform node to do that. Cross Product node to do the cross products of course.
Important : The cross product order is important.
Hope that helps!