목록Game Dev/Unreal C++ : Study (37)
KoreanFoodie's Study
언리얼 렌더링 최적화 : Visibility 와 오클루전 컬링(Occlusion Culling) 핵심 : 1. 렌더링에는 컬링(Culling) 이라는 개념이 있다. 이 개념은, 카메라의 시점에서 보이지 않는 녀석들을 굳이 렌더링 할 필요 없이 걷어내는(Culling) 기능이라고 생각하면 된다. 액터의 Visibility 는 Bounds Scale 을 설정해 해당 액터를 카메라에 보여줄 범위를 설정할 수 있다. 2. 컬링 방법(Culling Method) 에는 크게 4 종류가 있다 : Distance, View Frustum, Precomputed Visibility, Dynamic Occulusion. 3. Culling 과 관련된 정보들은 'stat initviews' 명령어로 확인할 수 있는데, 이 ..
TTypeCompatibleBytes 타입 핵심 : 1. TTypeCompatibleBytes 은 기본 타입이 아닌 데이터 배열로, 컴파일 타임 alignment 가 가능하다. 2. Alignment 가 되는 기본 단위는 템플릿 매개변수로 전달된 타입으로부터 계산된 사이즈로 정의된다. 3. GetTypedPtr 로 해당 Element 를 사용할 수 있다. TypeCompatibleBytes.h 에 정의된 구현을 보면, /** An untyped array of data with compile-time alignment and size derived from another type. */ template struct TTypeCompatibleBytes : public TAlignedBytes< sizeo..
언리얼 스마트 포인터 구현 세부사항과 팁 핵심 : 1. 스마트 포인터를 사용할지 고려할 때는 항상 퍼포먼스에 대해 생각해야 한다. 스마트 포인터는 자원 관리에는 적합하지만 일부 스마트 포인터 타입은 C++ 기본 포인터보다 더 느리기 때문이다. 2. TSharedPtr 는 비침범형(non-intrusive) 로, 오브젝트가 스마트 포인터의 소유 하에 있는지 알 수 없다. 오브젝트를 TSharedRef 또는 TSharedPtr 로 접근하면, 오브젝트 클래스를 TSharedFromThis 에서 파생시켜야 한다. 3. 스마트 포인터는 일반적으로 싱글 스레드에서 안전하게 사용할 수 있다. 멀티 스레드에서 사용해야 한다면, 스레드 세이프 버전을 사용하자. 스마트 포인터 구현 세부사항 언리얼 스마트 포인터 라이브러리..
TOptional 핵심 : 1. TOptional 은 인자로 들어간 녀석이 생성되었는지 아닌지 여부를 간단하게 확인할 수 있는 Wrapper 클래스이다. 2. Optional.h 에 보면 Value 와 bIsSet 이 있는데, Value 가 실제 넘기는 데이터이고, bIsSet 이 해당 데이터의 생성자가 호출되었는지 여부를 판단하는 녀석이다. IsSet, Emplace, GetValue 등을 사용하면 해당 클래스를 유용하게 활용할 수 있다. 3. TOptional 을 사용하는 장점 중 하나는, 특정 변수가 초기화되었는지를 판단하기 위해 'Magic Number' 를 쓸 필요가 없어진다는 것이다! TOptional 구조체 일단, Optional.h 에 정의된 TOptional 구조체의 대략적인 구조를 보자..
언리얼의 Cast 동작 원리 핵심 1. Cast 는 UObject 에 쓰여야 한다. Cast 는 static_cast 와는 달리 타입 안정성을 지닌다(nullptr 를 리턴). 2. Cast 의 런타임 비용은 에디터 환경에서는 O(O(Depth(InheritanceTree))) 이고, 에디터가 아닐 때는 O(1) 이다. 3. Cast 는 dynamic_cast 를 사용하지 않는다. dynamic_cast 대신 Cast 를 사용하라! 실제로 언리얼의 Cast 는 다음과 같이 구현되어 있다 : // Dynamically cast an object type-safely. template FORCEINLINE To* Cast(From* Src) { return TCastImpl::DoCast(Src); } 내부..
위젯 리플렉터 언리얼의 위젯 리플렉터 기능을 이용하면, 현재 플레이하고 있는 창에서 어떤 위젯이 어떤 블루프린트를 사용하고 있는지, visibility 상태는 어떠한지 등을 한눈에 파악할 수 있다(위젯 리플렉터 : 창 > 개발자 툴 > 위젯 리플렉터). 더 자세한 사항은 이득우님 블로그의 에디터 확장 기초 글을 참고하자. 위의 히트 테스트 가능 위젯을 누르면, 다음과 같이 플레이 화면과 위젯 리플렉터 창이 바뀌는 것을 확인할 수 있다(이미지는 공식 문서에서 가져옴) 해당 위젯의 계층 구조를 파악할 수 있으며, 실시간으로 위젯을 끄고 킬 수도 있어 위젯 관련 디버깅에 매우 유용한 기능이다!
Actor 와 ActorComponent 유니티에서는 게임 오브젝트 아래에 게임 오브젝트를 넣는 식으로 Hierarchy 를 만들어낼 수 있다. 하지만 언리얼은 그런 식으로 동작하지 않는다. 유니티에서는 항공기가 있다고 했을 때, 프리팹에 각종 게임 오브젝트를 하위에 넣어 조합하는 방식으로 해당 오브젝트를 제작할 수 있다. 그런데 언리얼에서 Actor 는 Bucket 같은 개념으로, 다양한 액터 컴포넌트를 담고 있다. 즉, 언리얼은 Bucket 안에 다른 Bucket 을 넣는 방식으로 오브젝트를 생성하지 않는다. 액터 컴포넌트는 재사용가능한 기능을 정의하는 컴포넌트에 대한 베이스 클래스로 충돌, 메시, 월드 이동, 소리 재생, 빛과 명암 등의 다양한 기능을 지원한다. 언리얼에서는 트랜스폼을 가진 액터 컴..
언리얼 코딩 표준 명명규칙 : 파스칼케이스, 접두사(U - UObject 상속 /A - AActor 상속 /S - SWidget 상속 / C - 에픽의 개념이 유사 / b - 부울 변수 / F - 그 외 대부분) 포터블 C++ 코드 : bool(크기 추정 금지, BOOL 은 컴파일 안됨), TCHAR, uint8, int8, uint(16, 32, 64 버전) , float, double, PTRINT(포인터를 가질 수 있는 정수, 크기 추정 금지) 표준 라이브러리 사용 : 표준 컨테이너와 스트링은 interop 코드를 제외하고 사용하지 말아야 함 코멘트 : 코드는 구현을 설명하고, 코멘트는 그 의도를 설명한다. 최신 C++ 언어 문법 : static_assert 사용, override 및 final 사..
언리얼 가비지 컬렉터(GC) 심화 정리 언리얼 엔진은 Reference Graph 를 만들어 오브젝트들의 사용 여부를 구분한다. 이 그래프 루트에는 "Root Set" 이라고 지정된 오브젝트 셋이 있으며, "Root Set" 에 포함된 객체들은 GC 대상에서 제외된다(Mark & Sweep 방식으로 추적). 세 가지 규칙 : UPROPERTY 선언 : 클래스 내부 멤버 변수가 클래스의 객체의 수명과 운명을 함께할 경우 선언 멤버가 가리키는 포인터 : 엔진이 인식하거나 관리하지 않는 메모리 영역을 가리키도록 만들면 안됨 TArray 를 활용 : UObject 또는 자식들에 대한 포인터를 안전하게 담을 수 있는 유일한 컨테이너 기타 인터페이스 예시 : // Object 를 살아있게 만드는 3가지 방법; //..
언리얼 엔진의 개념과 동작 원리 복습 이득우님의 블로그를 보며, 배운 내용을 간단히 정리해보려 한다! 언리얼을 처음 시작한다면, 이득우님이 쓰신 책인 "이득우의 언리얼 C++ 개임 개발의 정석" 을 꼭 읽어보는 것을 추천한다! 이 블로그에도 강좌 내용을 정리해 놓았지만, 실제로 읽어보는 것을 적극 추천한다. 8. 액터의 제작 액터는 월드에 배치될 수 있는, 월드 트랜스폼이 있는 언리얼 오브젝트라고 할 수 있다. 게임 컨텐츠의 설계는 액터에서부터 시작한다고 할 수 있다. 액터를 세팅할 때는 아래와 같이 애셋을 불러와 적합한 메시에 적용하면 된다. 자세한 구현은 이 글을 참고하자. static ConstructorHelpers::FObjectFinder SK_BlackKnight(TEXT("SkeletalM..