목록전체 글 (952)
KoreanFoodie's Study

클래스 타입 체크 (런타임) 우리가 아이템을 사용하는데, 소모품일 경우 수량을 깎는 코드를 짠다고 가정해 보자. 코드는 다음과 같다. if (nullptr != Cast(myItem)) { this->consumeItem(myItem); } else { this->useItem(myItem); } (물론 현실적으로 이런 경우, FConsumable 클래스에서 useItem 을 override 하겠지만.. 여튼) 위처럼, 객체의 클래스 타입을 체크하는 경우, 어떻게 하는 것이 효율적일까? 위와 같은 경우에, 만약 캐스팅이 실제로 필요한 경우가 아니라면(즉, 그냥 타입 체킹만 하면 되는 경우라면), Cast(언리얼의 Cast 는 업/다운 캐스팅을 할 수 있도록 구현되어 있다)를 쓰는 것보다, IsA 를 활용..

텍스트 조회 보통 프로젝트 규모가 커지게 되면, 각종 스트링들을 스트링 테이블에 넣어서 사용할 것이다. 이때 스트링 테이블은 Namespace 와 키 값 두 개가 있고, 원하는 Namespace 에서 키를 대입해 원하는 텍스트를 찾게 된다. Namespace 는 간단히 말해 스트링 테이블 파일의 이름이라고 보면 된다. 실제로 C++ 코드로 짜면, 다음과 같다 : FText findText; FText::FindText(TEXT("your_namespace"), TEXT("your_key"), findText); your_namespace 와 your_key 에 적합한 값을 주면, 원하는 값이 findText 에 들어갈 것이다. 텍스트 데이터를 이용해 테이블과 키값 조회 반대로, 텍스트 데이터를 이용해 테..

Delay 실행 만약 일정 시간이 지난 후 함수가 실행되길 원한다면, FTimerHandle 을 이용해 다음과 같이 코드를 짜면 된다. FTimerHandle myTimerHandle; GetWorld()->GetTimerManager().SetTimer(myTimerHandle, FTimerDelegate::CreateLambda([&]() { // 내가 원하는 코드 구현 DoSomething(); // 타이머 초기화 GetWorld()->GetTimerManager().ClearTimer(fadeOutTimerHandle); }), InDelayTime, false); // 반복 실행을 하고 싶으면 false 대신 true 대입 아, 참고로 FTimerHandle 은 글로벌 타이머 매니저에서 사용하며..

inline 과 FORCEINLINE 의 차이 사실 이 둘의 차이는 이미 단어에서 쉽게 파악할 수 있다. 일단 함수의 인라인화라는 것은, 컴파일러가 함수 바디를 컴파일 타임에 붙여 넣어 함수 호출의 오버헤드를 줄이는 최적화 방식이라고 볼 수 있다. C++ 에서 inline 은 컴파일러에게 함수를 인라인화할 것을 '요청' 한다. 이는 '명령' 이나 '강제'가 아니다. 복잡한 함수나 가상함수는 컴파일러가 인라인화 해주지 않으며, inline 키워드를 쓰지 않더라도 작고 간단한 함수의 경우 컴파일러가 알아서 인라인화를 해 주기도 한다. 반면 FORCEINLINE 은 말 그대로 강제적으로 인라인화를 시킨다. 생성자와 소멸자 등, 인라인화 시키기에 적합하지 않은함수들이 생각보다 많이 존재하므로, FORCEINLI..

C++ 에 대해 공부한 것과, 개발하면서 알게 된 것들을 다룹니다 RTTI RTTI 는 간단히 말해, 실시간 타입 정보라는 뜻이다. RTTI 라는 단어를 평소에는 잘 들어볼 일이 없다가, dynamic_cast 를 사용하기 위해 비주얼 스튜디오 옵션을 뒤적이던 중 해당 항목을 발견했다. 알다시피, C++ 는 리플렉션 기능을 제공하지 않는다. C# 에서는 리플렉션을 제공하는데, 해당 기능은 런타임에서 클래스 타입, 메소드, 프로퍼티 등의 메타 정보를 제공해 준다. 비주얼 스튜디오에서는 해당 기능을 끄고 킬 수 있게 만들어 놓았다. 간단히 말해, 해당 기능을 키게 되면 런타임에서 타입에 대한 정보를 얻을 수 있다. RTTI 는 가상 함수가 있는 클래스에 대해서만 동작하며, 이는 클래스의 타입 관련 정보가 v..

C++ 에 대해 공부한 것과, 개발하면서 알게 된 것들을 다룹니다 파생 클래스에서의 기반 클래스 생성자 호출 사실 파생 클래스가 생성될 때, 기반 클래스 생성자가 호출된다는 건, C++ 을 조금이라도 해 본 사람은 누구나 알고 있는 사실이다. 또한 함수의 생성자/소멸자의 호출 순서가 다음과 같다는 것도, 익히 알려진 사실이다. 즉, A 클래스가 기반 클래스이고, B 클래스가 파생 클래스라고 가정했을 때 B 클래스 변수를 선언하면 호출 순서가 다음과 같이 나올 것이다 : A 클래스 생성자 B 클래스 생성자 B 클래스 소멸자 A 클래스 소멸자 하지만 한 가지 기억해야 할 것은, 파생 클래스를 만들 때 호출되는 기반 클래스 생성자는 '인자가 없는 기반 클래스의 생성자' 이다. 즉, 인자를 받는 형식의 기반 클..

C++ 에 대해 공부한 것과, 개발하면서 알게 된 것들을 다룹니다 우측값과 좌측값 우리는 C++03 까지, 우리는 우측값과 좌측값 두 가지의 개념을 사용하여 코딩을 했었다. 간단히 말하자면, 좌측값은 '식의 좌측에 있는 변수'를, 우측값은 '식의 우측에 있는 값'을 의미했다. // a 는 좌측값, 5 는 우측값이다 int a = 5; 흔히들 좌측값을 '이름이 있는 녀석'으로 인식하기도 했다. 엄밀히 말하면 틀린 말은 아니다. 그런데 move semantics 가 도입되기 시작하면서, C++11 부터 대격변이 시작되는데... 여기서 많은 사람들이 좌측값과 우측값에 대한 개념을 헷갈려하기 시작한다(필자 포함). move semantics 가 뭔지 잘 모르겠다면, 이전 글(기초, 응용, 심화)을 꼭 읽고 오자..

C++ 에 대해 공부한 것과, 개발하면서 알게 된 것들을 다룹니다 const_cast 많은 사람들이 알고 있듯이, C++ 에서 제공하는 casting 의 종류는 크게 4 가지이다. 각 용도를 간단히 적어보면 다음과 같다 : static_cast : '일반적인' C 스타일의 캐스팅. 보통 업캐스팅(파생 클래스의 포인터를 기반 클래스의 포인터로 가리킴) 시 사용한다. dynamic_cast : 상속 관계에 있는 클래스들 사이의 캐스팅. 보통 다운 캐스팅(기반 클래스의 포인터를 파생 클래스의 포인터로 가리킴) 시 사용한다. 만약 실패하면 nullptr 를 리턴한다. 참고로, dynamic_cast 는 polymorphic 한 클래스만 가능한데, 간단히 말하면 virtual 함수가 포함된 클래스이어야 dynam..

슬레이트 구조 (아키텍처) 사실 언리얼에는 이미 UMG 라는, 매우 편리한 위젯 관련 툴이 존재한다. 하지만 코드로 UI 를 컨트롤할 수 있다는 장점 때문에, 실제로 많은 곳에서 슬레이트(Slate) 를 활용하고 있다. 슬레이트는 어떤 녀석이고, 어떻게 디자인되어 있는지, 공식 문서(번역본)를 통해 먼저 간단하게 짚고 넘어가도록 하자! 이번 글에서는 슬레이트가 추구하는 방향과 철학에 대해 다룬다. 일단, 에디터 인터페이스의 대부분은 슬레이트로 제작되어 있다. Contents Browser 뿐만 아니라 블루프린트 에디터, 애니메이션 에디터 등 엔진 인터페이스의 대부분을 차지하고 있다. 슬레이트는 다음과 같은 접근법을 사용한다 : (불투명 캐시와 중복 스테이트를 피하기 위해. 전통적으로 UI 는 스테이트를 ..

UUserWidget 의 Native 함수 //native SObjectWidget methods (see the corresponding BlueprintImplementableEvent declarations above for more info on each) friend class SObjectWidget; virtual void NativeOnInitialized(); virtual void NativePreConstruct(); virtual void NativeConstruct(); virtual void NativeDestruct(); virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime); UserWidget 에는 위..