Surface Orientation
Right now the Character's Move() function uses the character's forward and right directions based off camera orientation. However when climbing we instead need to move relative to the surface.

In order to move relative to the surface we'll need to know the surface normal, which luckily we've already calculated so all we need is an accessor
.h
// ZCCharacterMovementComponent.h
public:
//...
UFUNCTION(BlueprintPure)
FVector GetClimbSurfaceNormal() const { return CurrentClimbingNormal; }
The reason it's useful to know the surface normal is because given that, and one other vector we can find the surface plane which will tell us which direction is up

Quick refresher on the cross product, but given two perpendicular vectors you can cross them to find the third which represents a plane orthogonal to the normal.
We know the surface normal (blue) and we want to know the up direction of the plane (green). So we just need a perpendicular vector (red).
Luckily we can use the character's Right for that remembering that Unreal uses the Left Hand Rule

Therefore doing Character's Right (red) X Surface Normal (blue) will give us the Up vector (green)

Then after that for the Right direction, we now know the Surface Normal, and the Surface Up so crossing them will give us the Surface Right
.cpp
// ZCClimbingCharacter.cpp
void AZCClimbingCharacter::Move(const FInputActionValue& Value)
{
// input is a Vector2D
FVector2D MovementVector = Value.Get<FVector2D>();
if (Controller != nullptr)
{
// Our climbing code
if (MovementComponent && MovementComponent->IsClimbing())
{
FVector SurfaceUpDirection = FVector::CrossProduct(GetActorRightVector(), MovementComponent->GetClimbSurfaceNormal());
FVector SurfaceRightDirection = FVector::CrossProduct(MovementComponent->GetClimbSurfaceNormal(), GetActorUpVector());
AddMovementInput(SurfaceUpDirection, MovementVector.Y);
AddMovementInput(SurfaceRightDirection, MovementVector.X);
}
else
{
// existing logic
// ...
}
}
}
Last updated