How can I align an actor to a normal only on the local x and y?

I am currently trying to make a puzzle game using gravity, similar to the planets in Super Mario Galaxy, except the player’s gravity is dictated by the arbitrary face of the object it is currently standing on or runs into. Determining the gravity’s direction was easy as I am just using a box trace to get the normal of the object and then use the negative as the gravity. The issue is trying to rotate the player only on the local x and y since I want the player to be facing roughly in the same direction when the gravity changes. I.e. if the player runs face first into a vertical wall that is 90 degrees from the ground they’re currently standing on, they should only pitch up 90 degrees and be now facing upwards but if the player runs into a 90 degree wall from their right side, they should roll 90 degrees to the left, and so on.

So far I have tried make rot from z of the normal, which aligns the player to the normal, but rotates the player to the same rotation regardless of how you approach the wall. I have tried dividing the dot product of the normal and the up/right vector of the player with the product of their lengths to manually find the pitch and roll, but it results in seemingly random rotations that sometimes are what I am going for but I am unsure what I am doing wrong with that.

It’s late and I’m about to go to bed so I haven’t checked this but if I’m interpreting your question correctly, I think you want something like this, where NewGroundNormal is the normal vector of the ‘wall’ or other surface you’re rotating onto, and RotationToApply is the rotation to apply to the current character rotation (not the new rotation of the character).

	FVector NewGroundNormal;
	AActor* PlayerActor;
	FTransform PlayerTransform = PlayerActor->GetActorTransform();
	FVector PlayerUp = PlayerTransform.GetUnitAxis(EAxis::Z);
	FQuat RotationToApply = FQuat::FindBetweenNormals(PlayerUp, NewGroundNormal);

FindBetweenNormals assumes both vectors are normalised, otherwise you can just use FindBetweenVectors.

lmk if it doesn’t work or if it’s not what you’re after.

1 Like

Hey thank you very much for the reply! This is exactly what I was looking for!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.