게임엔진

    [Unreal] Programming Subsystem (프로그래밍 서브시스템)

    1. 서브시스템 여기서 GameInstance 서브시스템을 커스터마이징했을때, 커스터마이징한 서브시스템의 수명은 class UMyGameSubsystem : public UGameInstanceSubsystem 위 예제 코드처럼 베이스 클래스에서 파생된 클래스를 생성하면 다음 스텝으로 수명이 관리된다. UGameInstance 생성 이후, UMyGameSubsystem 인스턴스 역시 생성한다. UGameInstance 초기화시, UMyGameSubsystem 인스턴스에서 Initialize()가 호출된다. UGameInstance 종료시, UMyGameSubsystem 인스턴스에서 Deinitialize()가 호출된다. Deinitialize()가 호출된 시점에서 UMyGameSubsystem 인스턴스에..

    [Unreal] Level Blueprint 를 C++로 접근하기

    기본적으로 Level Blueprint는 ALevelScriptActor, 즉 Actor 형식이다. 이를 상속받아 새로운 Level Actor를 생성한다. 자신의 LevelScriptActor에서 추가한 함수가, Level Blueprint에서도 보일 수 있게 수정할 수 있다. 다음은 Actor들의 Reference를 받아 Destroy 시키는 DestroyActors 함수이다. 자신의 LevelScriptActor에서 작성한 함수가 Level Blueprint에서 보이려면 UFUNCTION과 Specifier 작성 필수이다. 눈에 띄는건 DestroyActors의 UPARAM(ref) 이라는 매크로인데, 이는 함수가 받는 인자가 Blueprint 상에서는 왼쪽 에서 와야 한다는 뜻이다. ( -> 즉 U..

    [Unreal] 언리얼 비동기 애셋 로딩 (Asynchronous Loading)

    FSoftObjectPath 와 TSoftObjectPtr 모든 사용할 때마다 로드하는 것이 아니라, 애셋을 전부 로딩하지 않으면서 로딩하고 싶은 애셋을 미리 준비시켜 놓고 싶다면 어떨까? 그럴 경우, FSoftObjectPath 와 TSofrObjectPtr 를 이용하면 된다. FSoftObjectPath 는 실제로 애셋의 경로를 FName 으로 저장하고 있는 구조체이며, TSoftObjectPtr 는 FSoftObjectPath 를 wrapping 한 TWeakObjectPtr 이다. TSoftObjectPtr.Get( ) 으로 참조된 애셋을 가져올 수 있으며, FSoftObjectPath 로 애셋을 로딩할 수 있다. The Asset Registry and Object Libraries 애셋 레지스..

    [Unreal] Reflection (리플렉션)

    언리얼은 UHT(Unreal Header Tool) 을 이용해 클래스 계층 구조, 멤버 변수/함수 등의 정보를 UClass 에 저장한다. 이를 리플렉션이라고도 하고, 프로퍼티 시스템이라고도 부른다. 리플리케이션 시스템은 부가 기능으로, 리플렉션 시스템에 보이도록 했으면 하는 유형이나 프로퍼티에 주석을 달아두면 UHT 가 컴파일시 해당 정보를 수집하게 된다. 프로퍼티 시스템 계층 구조는 아래와 같다. (UField 아래에 UStruct, UEnum, UProperty 가 있음) #include "MyObject.generated.h" UCLASS(Blueprintable) class UMyObject : public UObject { GENERATED_BODY() public: MyUObject(); UP..

    [Unreal] GetClass 와 StaticClass 의 차이

    GetClass vs StaticClass StaticClass 는 컴파일 타임에서 UClass 타입의 정보를 얻어오는 것이며, GetClass 는 런타임에서 실제 객체의 클래스를 조회할때 사용된다. AMyActor* ActorPtr = NewObject(...); UObject* ObjPtr = Actor; UClass* MyActorClass = AMyActor::StaticClass(); // AMyActor UClass* ObjectClass = UObject::StaticClass(); // UObject UClass* ActorPtrClass = ActorPtr->GetClass(); // AMyActor UClass* ObjPtrClass = ObjPtr->GetClass(); // AMyA..

    [Unreal] 업/다운캐스팅 (Cast 함수) 동작 원리

    실제로 언리얼의 Cast 는 다음과 같이 구현되어 있다 : // Dynamically cast an object type-safely. template FORCEINLINE To* Cast(From* Src) { return TCastImpl::DoCast(Src); } 내부적으로 TCastImpl 을 부르고 있다 template struct TCastImpl { // This is the cast flags implementation FORCEINLINE static To* DoCast( UObject* Src ) { return Src && Src->GetClass()->HasAnyCastFlag(TCastFlags::Value) ? (To*)Src : nullptr; } FORCEINLINE sta..

    [Unreal] 메모리 관리

    메모리 관리는 안정성이 높고 버그가 없는 프로그램을 작성하는 과정에서 늘 중요한 주제다. dangling pointer는 이미 메모리에서 지워진 대상을 참조하는 포인터이며, 추적하기 어려운 버그를 만드는 대표적인 사례다. UE4의 UObject 참조 카운팅 시스템은 UObject 클래스로부터 파생된 액터와 클래스의 메모리를 관리하는 기본적인 수단으로, 이를 통해 UE4 프로그램 내에서 메모리가 관리된다. 만약 UObject에서 파생하지 않은 C++ 클래스를 작성한다면 TSharedPtr/TWeakPtr 를 사용하면 된다. 이번 글에선 메모리 관리와 코드 디버깅 방법을 설명한다. 메모리 관리 기능의 도움을 받으면 메모리 해제를 잊는 실수를 걱정하지 않아도 된다. 메모리 관리를 하는 프로그램에서는 동적으로 ..

    [Unreal] Actor 와 ActorComponent 의 개념 (vs. Unity 에서의 GameObject 와 비교)

    Actor 와 ActorComponent 유니티에서는 게임 오브젝트 아래에 게임 오브젝트를 넣는 식으로 Hierarchy 를 만들어낼 수 있다. 하지만 언리얼은 그런 식으로 동작하지 않는다. 유니티에서는 항공기가 있다고 했을 때, 프리팹에 각종 게임 오브젝트를 하위에 넣어 조합하는 방식으로 해당 오브젝트를 제작할 수 있다. 그런데 언리얼에서 Actor 는 Bucket 같은 개념으로, 다양한 액터 컴포넌트를 담고 있다. 즉, 언리얼은 Bucket 안에 다른 Bucket 을 넣는 방식으로 오브젝트를 생성하지 않는다. 액터 컴포넌트는 재사용가능한 기능을 정의하는 컴포넌트에 대한 베이스 클래스로 충돌, 메시, 월드 이동, 소리 재생, 빛과 명암 등의 다양한 기능을 지원한다. 언리얼에서는 트랜스폼을 가진 액터 컴..

    [Unreal] 가비지 컬렉터 (GC) 정리

    언리얼 엔진은 Reference Graph 를 만들어 오브젝트들의 사용 여부를 구분한다. 이 그래프 루트에는 "Root Set" 이라고 지정된 오브젝트 셋이 있으며, "Root Set" 에 포함된 객체들은 GC 대상에서 제외된다(Mark & Sweep 방식으로 추적). 세 가지 규칙 : UPROPERTY 선언 : 클래스 내부 멤버 변수가 클래스의 객체의 수명과 운명을 함께할 경우 선언 멤버가 가리키는 포인터 : 엔진이 인식하거나 관리하지 않는 메모리 영역을 가리키도록 만들면 안됨 TArray 를 활용 : UObject 또는 자식들에 대한 포인터를 안전하게 담을 수 있는 유일한 컨테이너 기타 인터페이스 예시 : // Object 를 살아있게 만드는 3가지 방법; // 1. UPROPERTY 붙여주기 (참조..

    [Unity] MVC, MVP, MVVM 디자인 패턴

    MVC 패턴 ▶ Model - View - Controller로 각각에 대한 역할을 구분하여 독립적인 기능을 수행하도록 설계하는 디자인 패턴이다. ▣ Model : 어플리케이션에서 사용하는 데이터의 집합이라고 볼 수 있다. ▣ View : 어플리케이션에서 사용자에게 보여지는 화면, UI 이라고 볼 수 있다. ▣ Controller : Model과 View를 이어주는 징검다리의 역할로 사용자는 Controller를 사용하여 Model의 데이터를 수정하게 된다. [ MVC 패턴 ] : MVC 패턴은 Model의 업데이트에 따라 View에 적용이 되야하는 부분에서 서로 간의 의존성이 발생하게 된다. MVP 패턴 ▶ MVC 패턴에서 파생된 디자인 패턴으로 Controller를 대신해 Presenter가 추가되었..