Rotation from normal ?

I want to set my root component Up vector to be equal to the normal of the floor the component is over.

My code is something like this :



FRotator UpRotator = MyRootComponent->GetUpVector().Rotation();
FRotator NormalRotator = Hit.ImpactNormal.Rotation();

FRotator DeltaRotation = NormalRotator - UpRotator;

MyRootComponent->AddLocalRotation(DeltaRotation);


This almost works. The problem I have is that the component loose its local Yaw. Here’s a gif to illustrate the problem :

The solution is probably very obvious, but I can’t figure it out.

1 Like

You might need to go into quaternions for that. You get the rotation axis (which is the normal of your current up vector and your impact normal) and the rotation angle (the angle between those two), construct a quaternion from them, multiply your actor’s rotation by that, and then set your actor to the new rotation.

Yay! It’s Working!

Thank you again Stormharrier, you rock!

Never worked with quaternions before and I’m not sure I understand 100% what I did, but here’s the code in case someone wants to take a look :



FVector UpVector = MyRootComponent()->GetUpVector();
FVector NormalVector = Hit.ImpactNormal;

FVector RotationAxis = FVector::CrossProduct(UpVector, NormalVector);
RotationAxis.Normalize();

float DotProduct = FVector::DotProduct(UpVector, NormalVector);
float RotationAngle = acosf(DotProduct);

FQuat Quat = FQuat(RotationAxis, RotationAngle);
FQuat RootQuat = MyRootComponent()->GetComponentQuat();

FQuat NewQuat = Quat * RootQuat;

MyRootComponent()->SetWorldRotation(NewQuat.Rotator());


2 Likes

Hey, just logged in to say thank you! Your code helped me a lot :slight_smile:

My Solution for FunctionLibrarys:



    FQuat RootQuat = CurrentRotation.Quaternion();
    FVector UpVector = RootQuat.GetUpVector();
    FVector RotationAxis = FVector::CrossProduct(UpVector, Normal);
    RotationAxis.Normalize();

    float DotProduct = FVector::DotProduct(UpVector, Normal);
    float RotationAngle = acosf(DotProduct);

    FQuat Quat = FQuat(RotationAxis, RotationAngle);

    FQuat NewQuat = Quat * RootQuat;

    return NewQuat.Rotator();


3 Likes

This is great, but is there a blueprint soltuion? Im starting to get really annoyed that they have not natively exposed Quats to blueprints, as I cannot figure out how to do the FQuat Function??

Bump! My Blueprint Solution was this, but it doesn’t work as expected. But try it out, maybe you see something which I don’t. Rotator To Quat is a custom function, you can find it on blueprintUE: Rotator to Quat posted by anonymous | blueprintUE | PasteBin For Unreal Engine

*Edit: This helped me a lot: Set Character rotation to ground normals posted by anonymous | blueprintUE | PasteBin For Unreal Engine

Fairly straightforward in BP. The only thing that is different is that you need to use the Rotator from Axis and Angle node to create a Rotator that can then be converted to a Quaternion.

1 Like