목록Game Dev/Unreal C++ : Study (37)
KoreanFoodie's Study
코어 리다이렉트란? 프로젝트를 멋지게 완성했는데, 만약 변수 명이나 애셋 명을 바꿔야 한다면 어떨까? 해당 변수나 애셋을 참조하는 모든 코드를 전부 헤집어 놓는 것은 상당한 낭비를 수반할 것이다. 이를 위해, 언리얼에서는 "기존 이름 -> 새로운 이름" 을 한번에 바꿔주는 기능을 제공하는데, 그것이 바로 '코어 리다이렉트' 이다. 코어 리다이렉트는 DefaultEngine.ini 파일이나, Default.ini 파일 등에 넣어주면 된다. 예시를 보자. [CoreRedirects] +ClassRedirects=(OldName="Pawn",NewName="MyPawn",InstanceOnly=true) +ClassRedirects=(OldName="/Script/MyModule.MyOldClass",NewN..
FSoftObjectPath 와 TSoftObjectPtr 사용할 때마다 로드하는 것이 아니라, 애셋을 전부 로딩하지 않으면서 로딩하고 싶은 애셋을 미리 준비시켜 놓고 싶다면 어떨까? 그럴 경우, FSoftObjectPath 와 TSofrObjectPtr 를 이용하면 된다. FSoftObjectPath 는 실제로 애셋의 경로를 FName 으로 저장하고 있는 구조체이며, TSoftObjectPtr 는 FSoftObjectPath 를 wrapping 한 TWeakObjectPtr 이다. TSoftObjectPtr.Get( ) 으로 참조된 애셋을 가져올 수 있으며, FSoftObjectPath 로 애셋을 로딩할 수 있다. The Asset Registry and Object Libraries 애셋 레지스트리는..
Assert assert 는 일반적으로 참조하고자 하는 변수가 null 인지 아닌지를 체크하는 용도로 자주 사용된다. 실제 개발을 할 때는 프로젝트명으로 된 헤더파일에 assert 구문을 이용한 커스텀 로그를 만들어 놓는 게 간편하다. 언리얼에서의 assert 종류는 크게 check, verify, ensure 이 있다. // assert 는 DO_CHECK = 1 일때만 실행 // check 는 false 값이면 실행을 중지 check(Mesh != nullptr); checkf(MyPtr, TEXT("MyPtr is nullptr")); // false 이면 로그 출력 checkcode(MyPtr, TEXT("MyPtr is nullptr")); // checkf 와 비슷 checkNoEntry();..
언리얼 문자열 클래스 언리얼 문자열 클래스는 3 가지가 있다. (FName, FString, FText) 이 중, 조작이 가능한 클래스는 FString 이다. 참고 - 문자열의 변환 : 출처 FName 은 FName(*FString) 꼴을, FString 은 .ToString( ) 꼴을, FText 는 FText::FromName( ) 꼴을 활용하는 것을 알 수 있다. 기타 세부 구현은 소제목 링크의 문서를 참고하자. FName FName 은 콘텐츠 브라우저에서 애셋 이름을 지을 때, 스켈레탈 메시에서 본에 접근할 때 등등에 사용된다. FName 은 문자열을 하나하나 비교하지 않고, 주어진 문자열을 해싱한 테이블에 저장한 후, index 로 값을 비교한다. 이 때문에 키로 FName 에 접근하는 속도가 ..
가비지 컬렉션 언리얼에서 UProperty 를 붙인 객체는 언리얼 엔진이 자동으로 가비지 컬렉터를 이용해 메모리를 관리한다. 가비지 컬렉션을 수행함에 있어 리플렉션 시스템을 사용하는데, 엔진이 객체와 속성값을 알고 있으므로, 더 이상 사용되지 않아 삭제해도 괜찮은 객체들을 구분할 수 있기 때문이다. 언리얼 엔진에서는 Reference Graph 를 만들어 오브젝트들의 사용 여부를 구분한다. 이 그래프 루트에는 "Root Set" 이라 지정된 오브젝트 셋이 존재하며, "Root Set" 에 포함된 객체들은 가비지 컬렉션 대상에서 제외된다. UObject::BaseUtility::AddToRoot 함수를 이용하면 객체를 "Root Set" 에 추가시킬 수 있다. ( 예시 : UMyObject->AddToRo..
스마트 포인터 3대장 C++ 에는 대표적인 스마트 포인터 3 가지가 있는데, 언리얼에서는 이를 T로 시작하는 라이브러리로 제공한다. TUniquePtr TSharedPtr TWeakPointer 기본적인 원리와 기능은 C++ 와 비슷하다. 기본적인 메서드 차이만 잠깐 짚고 넘어가면, TUniquePtr : C++ 에서 std::move 를 이용해 소유권을 이전했다면, 언리얼에서는 MoveTemp 를 사용한다. TSharedPtr : C++ 에서 std::maked_shared 를 이용했다면, 언리얼에서는 MakeShared 을 사용한다. 해제 시 Reset( ) 을 호출한다. shared_ptr(new MyClass()) 같은 식으로 사용할 때는 MakeShareable 을 사용한다. MakeSharea..
시리얼라이제이션 시리얼라이제이션이라는 개념은, 텔레포트와 같다고 이해하면 쉽다. 텔레포트로 사람을 전송한다고 했을 때, 정상적으로 작동하는 텔레포터는 사람 전체를 온전히 주고받는 형태일 것이다. 즉, 절반만 보낸다거나, 나눠서 보내지 않는다는 뜻이다. (나눠서 보내면... 그건 텔레포터가 아니라 살상무기가 아닐까) 시리얼라이제이션은 언리얼 오브젝트를 한번에 안전하게 전달하기 위해 FArchive 클래스를 만들어 파일, 메모리 등등 데이터를 전송하는 모든 매체를 관리하고 있다. 실제로 데이터를 전송하는 모든 매체는 FArchive 클래스를 상속받아서 구현한다. FArchive 객체를 이용해 파일을 만들고 쓰기/읽기를 구현한 예제 코드를 보자. FString FullPath = FString::Printf(..
델리게이트 C# 에서는 발행자-구독자(Publisher-Subscriber) 패턴의 구현이 가능해, 특정 이벤트를 구독한 객체는 특정 이벤트가 발행되었을 때 원하는 콜백함수가 실행되도록 만들 수 있다. 이때, 앞서 이야기한 특정 이벤트를 다른 말로 "델리게이트"라고 한다. C++ 에서는 델리게이트 시스템이 없지만, 언리얼은 자체적으로 델리게이트를 제공하고 있다. 델리게이트를 이용하는 것은 기존에 함수 포인터 등을 이용했던 것보다 간편하며 안전하다. 대리자를 통해 함수를 호출하므로 호출할 함수나 이를 포함하는 객체가 없어져도 대리자가 체크해 안전하게 함수를 호출할 수 있으며, 동일한 형을 가진 함수 여러 개를 대리자가 묶어서 관리하고 필요할 때 동시에 모두 호출할 수도 있다. 델리게이트를 사용하기 위해서는..
하드 레퍼런싱 vs 소프트 레퍼런싱 CDO 생성시, 생성자에서 애셋의 유무를 확인하기 위해 ConstructorHelpers 함수를 호출해 애셋을 로드한다. 하지만 게임 시작 전에 반드시 존재하는지 체크할 필요가 없는 경우도 있는데, 전자의 경우를 하드 레퍼런싱(Hard Referencing), 후자를 소프트 레퍼런싱(Soft Referencing) 이라고 한다. 소프트 레퍼런싱 방식을 사용할 시 애셋의 정보를 가져올 때에는 FStringAssetReference 구조체를, 애셋의 클래스 정보를 가져올 때에는 FStringClassReference 구조체에 경로 정보를 지정해주면 된다. 여러 애셋을 가져올 때는 TArray 형식을 사용하면 된다. ABPawn.h (로딩한 애셋을 실제 사용할 언리얼 오브젝..
언리얼 INI 파일 설정 만약 캐릭터의 HP 를 편집하고 싶은데, HP 값을 변경하기 위해 매번 캐릭터를 에디터에서 수정해야 한다면 매우 비효율적일 것이다. 이를 위해, 언리얼은 INI 파일을 이용해 블루프린트나 별도의 에디터 작업이 없이도 속성값을 바꿀 수 있는 기능을 제공하고 있다. (원래 INI 파일은 윈도우에서 시스템 구성 요소의 설정을 위해 만들어진 파일 형식이다) INI 파일의 형식은 속성과 값, 그리고 이 두 가지를 포괄하는 섹션으로 구성되어 있다. 섹션 : 현재 프로젝트에서 사용하는 C++ 클래스 식별자 속성 : C++ 클래스에서 INI 를 사용하도록 지정한 UPROPERTY 멤버 변수 값 : 속성에 지정할 값 C++ 클래스 식별자는 고유한 식별자로 구분되며 다음과 같은 형식을 가진다. {..