리얼 개발

[UE5] Vector 클래스 분석 본문

Unreal Engine5

[UE5] Vector 클래스 분석

econo-my 2024. 9. 4. 15:02

FVector

FVector 는 언리얼 엔진의 Vector 단위인 UE::Math::TVector<double> 를 대신하는 매크로이다.

 

이는 MathFwd.h 파일에 선언되어 있다.

 

 

실질적인 기능들이 정의되어 있는 Vector.h 파일을 살펴보자.

template<typename T>
struct TVector

TVector는 템플릿 구조체로 선언되어 있다. 우리가 엔진에서 사용하는 FVector는 TVector 구조체의 double형만을 나타내는 구조체이다.

 

/** A zero vector (0,0,0) */
CORE_API static const TVector<T> ZeroVector;

/** One vector (1,1,1) */
CORE_API static const TVector<T> OneVector;

/** Unreal up vector (0,0,1) */
CORE_API static const TVector<T> UpVector;

/** Unreal down vector (0,0,-1) */
CORE_API static const TVector<T> DownVector;

/** Unreal forward vector (1,0,0) */
CORE_API static const TVector<T> ForwardVector;

/** Unreal backward vector (-1,0,0) */
CORE_API static const TVector<T> BackwardVector;

/** Unreal right vector (0,1,0) */
CORE_API static const TVector<T> RightVector;

/** Unreal left vector (0,-1,0) */
CORE_API static const TVector<T> LeftVector;

/** Unit X axis vector (1,0,0) */
CORE_API static const TVector<T> XAxisVector;

/** Unit Y axis vector (0,1,0) */
CORE_API static const TVector<T> YAxisVector;

/** Unit Z axis vector (0,0,1) */
CORE_API static const TVector<T> ZAxisVector;

/** @return Zero Vector (0,0,0) */
static inline TVector<T> Zero() { return ZeroVector; }

/** @return One Vector (1,1,1) */
static inline TVector<T> One() { return OneVector; }

/** @return Unit X Vector (1,0,0)  */
static inline TVector<T> UnitX() { return XAxisVector; }

/** @return Unit Y Vector (0,1,0)  */
static inline TVector<T> UnitY() { return YAxisVector; }

/** @return Unit Z Vector (0,0,1)  */
static inline TVector<T> UnitZ() { return ZAxisVector; }

단위벡터 멤버와 가져오는 함수들이다.

 

FORCEINLINE TVector<T> operator^(const TVector<T>& V) const;
FORCEINLINE TVector<T> Cross(const TVector<T>& V2) const;
FORCEINLINE static TVector<T> CrossProduct(const TVector<T>& A, const TVector<T>& B);

벡터 외적 함수들이다. 외적 기호로 ^를 사용하는데 깜찍한 것 같다.

 

FORCEINLINE T operator|(const TVector<T>& V) const;
FORCEINLINE T Dot(const TVector<T>& V) const;
FORCEINLINE static T DotProduct(const TVector<T>& A, const TVector<T>& B);

벡터 내적 함수들이다. 내적 기호로는 | 를 사용한다. 함수들마다 주석이 상세히 달려있어 이해하기 편한감이 있다.

이것 외에도 연산자 오버로딩으로 +, -, *, / (가감승제) 기능과 == (비교연산) 이 모두 구현되어 있다.

 

코드를 보다 멈칫한 부분이 있었는데 바로 벡터 정규화 함수였다.

bool Normalize(T Tolerance=UE_SMALL_NUMBER);

 

return 값이 필요할까? 생각했는데 정의를 보니 왜 그런지 알 것 같았다.

template<typename T>
FORCEINLINE bool TVector<T>::Normalize(T Tolerance)
{
    const T SquareSum = X*X + Y*Y + Z*Z;
    if(SquareSum > Tolerance)
    {
        const T Scale = FMath::InvSqrt(SquareSum);
        X *= Scale; Y *= Scale; Z *= Scale;
        return true;
    }
    return false;
}

먼저 벡터의 길이가 너무 작지 않은지 판단한다. Tolerance는 UE_SMALL_NUMBER 매크로로 정의된 아주 작은 기본 인자이다. 그래서 정규화가 가능하다고 판단되면 진행하고 true 값을 리턴하며 불가능할시 false값을 리턴한다. 또한 객체의 멤버 변수의 값을 변경하기에 다른 객체에 복사하여 사용하지 않아도 된다.

 

그 아래 새로운 TVector 객체를 만들어 리턴하는 정규화 함수도 있었다.

TVector<T> GetSafeNormal(T Tolerance=UE_SMALL_NUMBER, const TVector<T>& ResultIfZero = ZeroVector) const;

 

 

TRotator<T> ToOrientationRotator() const;

사실 이 함수가 어떤 역할인지 알아보려다가 이렇게 Vector 클래스의 소스 코드를 탐방하게 됐다. 해당 함수는 벡터가 가리키는 방향에 해당하는 TRotator 값을 반환한다. 회전 값 중 Yaw, Pitch 값을 수정하고 Roll 값은 벡터가 가리키는 방향만으로는 결정할 수 없기에 0으로 설정된다. 이와 똑같은 기능을 하는 함수인 Rotation() 함수가 있다.

 

static FORCEINLINE T Dist(const TVector<T> &V1, const TVector<T> &V2);
static FORCEINLINE T Distance(const TVector<T> &V1, const TVector<T> &V2) { return Dist(V1, V2); }

두 벡터 사이의 거리를 구해주는 함수도 자주 사용했었다.

 

template<typename T>
FORCEINLINE T TVector<T>::DistSquared(const TVector<T>& V1, const TVector<T>& V2)
{
    return FMath::Square(V2.X-V1.X) + FMath::Square(V2.Y-V1.Y) + FMath::Square(V2.Z-V1.Z);
}

정의는 이렇게 심플하게 되어있다.

 

언리얼로 개발을 진행할 때 언리얼 API들을 많이 사용하게 되는데, 자주 사용하는 클래스를 뒤져보며 선언, 정의, 구현 방법 등을 살펴보는 것도 많은 공부가 되는 것 같다. 이것만으로 언리얼이 제공하는 Vector 에 대해 다 알 순 없지만 꾸준히 하다보면 실력은 늘 것이다.

 

'Unreal Engine5' 카테고리의 다른 글

[UE5] 언리얼 빌드 시스템  (1) 2024.09.12
[UE5] 무기 선택 창으로 무기 교체하기  (0) 2024.09.11
[UE5] 보간 함수를 이용한 회전  (1) 2024.09.02
[UE5] 용어 정리  (4) 2024.09.02
[UE5] 적 AI 공격 구현하기  (0) 2024.07.29