[UE5] Climb 강의 문제해결
2024. 2. 26. 23:26ㆍ강의/UE5 Climbing System
Ledge


- Ledge를 판별할 때 빗면이 있을 경우 부자연스럽게 Climbing 상태가 종료되는 상황이 있었습니다.
- Normal과 Up Vector 의 각도가 캐릭터가 걸을 수 있는 각도 이하일때만 Climb 상태에서 Walk 상태로 변환하게 처리했습니다. (이 각도는 직접 실험을 통해 측정: 40도)
Ceiling


- 위와 같이 벽과 천장 사이를 이동할 때 머리가 반대방향으로 이동하는 문제가 있었습니다.
- 이 부분이 부자연스럽게 보였기에 문제점이 무엇인지 찾아보았습니다.
- 이유는 바로 MakeFromX 때문이었습니다.
FRotationMatrix::MakeFromX(-CurrentClimbableSurfaceNormal)
- 강의에서는 Normal 을 MakeFromX에 넣어 RotationMatrix를 만들었습니다.
- MakeFromX의 구현은 다음과 같습니다.
template<typename T>
TMatrix<T> TRotationMatrix<T>::MakeFromX(TVector<T> const& XAxis)
{
TVector<T> const NewX = XAxis.GetSafeNormal();
// try to use up if possible
TVector<T> const UpVector = (FMath::Abs(NewX.Z) < (1.f - UE_KINDA_SMALL_NUMBER)) ? TVector<T>(0, 0, 1.f) : TVector<T>(1.f, 0, 0);
const TVector<T> NewY = (UpVector ^ NewX).GetSafeNormal();
const TVector<T> NewZ = NewX ^ NewY;
return TMatrix<T>(NewX, NewY, NewZ, TVector<T>::ZeroVector);
}
- UpVector가 고정되어 있는 것을 확인할 수 있습니다.
FVector UpVector = (FMath::Abs(-CurrentClimbableSurfaceNormal.Z) < (1.f - UE_KINDA_SMALL_NUMBER)) ? FVector(0, 0, 1.f) : FVector(1.f, 0, 0);
const float Angle = FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(FVector::UpVector, -CurrentClimbableSurfaceNormal)));
if(Angle < 20.0f)
{
UpVector = UpdatedComponent->GetUpVector();
}
FMatrix RotationMatrix = FRotationMatrix::MakeFromXZ(-CurrentClimbableSurfaceNormal, UpVector);
- 그래서, 저는 위처럼 내적으로 천장인지 판별한 후,
- 천장이면 캐릭터의 UpVector를 가져와 MakeFromXZ 함수에 넣었습니다.
(만약, UpVector를 항상 캐릭터의 Up방향으로 설정하면, 벽-> 천장-> 반대쪽 벽 으로 이동할 때 머리가 아래부분으로 향하게 되어, 천장일때만 적용하였습니다.)

- 결과는 위와 같습니다.