목록Categories (1096)
KoreanFoodie's Study
SetTimer 에 함수 및 람다(Lambda) 연결하기 핵심 : 1. UObject 상속 클래스에서는 기존 함수를 SetTimer 함수에서 바로 연결할 수 있다. 2. 일반적으로는 FTimerDelegate 에 Lamda 함수를 연결해 사용하며, UObject 를 상속하지 않는 클래스에서도 이 방법을 사용할 수 있다. 3. FTimerHandle 은 전역이며, 사용 완료 후에는 ClearTimer 를 이용해 타이머를 해제해 주도록 하자! 이전 글에서 언급한 바 있지만, 일정 시간 이후 특정 함수가 호출되도록 만드는 방법을 조금 더 자세히 기록해보려 한다. SetTimer 에 함수와 람다를 연결하는 방법을 추가로 소개한다! 1. 기존 함수에 그대로 연결 (UObject 클래스에서 사용 가능) FTimer..
현재 시간 로그 찍기 핵심 : 1. FDateTime 구조체를 이용해서 각종 시간을 체크할 수 있다. 2. FDateTime::Now() 를 통해서 현재 시간(초까지)를 구할 수 있다(static). 3. FDateTime::GetMillisecond() 를 통해 현재 밀리 초를 구할 수 있다(non-static). 아래 코드를 이용해서 현재 시간을 구하는 간단한 로그를 찍어 볼 수 있다! FDateTime dateTime; UE_LOG(Error, FText::FromString( FString::Format(TEXT("Current Time : %s:%d ms"), { FDateTime::Now().ToString(), dateTime.GetMillisecond() }))); UE_LOG 매크로는 F..
SafeZone 위젯 핵심 : 1. SafeZone 위젯을 사용하면, 콘솔/PC/모바일 등 에서 패널 가장자리에 UI 및 컨텐츠가 제대로 출력이 되지 않는 문제를 해결할 수 있다. 먼저, SafeZone 패널에 대한 언리얼 엔진의 설명은 다음과 같다 : 언리얼 공식 문서에 있는 세이프 존에 대한 그림을 보자. 왼쪽은 SafeZone 위젯이 없는 경우이고, 오른쪽은 SafeZone 위젯이 있는 경우이다. 오른쪽의 경우, Uniform Safe Zone (균등 세이프 존) 영역을 0.9(빨강) 으로 설정했다. 이렇게 세이프 존을 활용하면, 가장자리의 "Unsafe" 한 존에 위젯이 잘리는 것을 방지할 수 있다! 참고 : 언리얼 공식 문서
언리얼의 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); } 내부..
UObject 의 클래스 타입 체크 (런타임) 우리가 아이템을 사용하는데, 소모품일 경우 수량을 깎는 코드를 짠다고 가정해 보자. 코드는 다음과 같다. if (nullptr != Cast(myItem)) { this->consumeItem(myItem); } else { this->useItem(myItem); } (물론 현실적으로 이런 경우, FConsumable 클래스에서 useItem 을 override 하겠지만.. 여튼) 위처럼, 객체의 클래스 타입을 체크하는 경우, 어떻게 하는 것이 효율적일까? 위와 같은 경우에, 만약 캐스팅이 실제로 필요한 경우가 아니라면(즉, 그냥 타입 체킹만 하면 되는 경우라면), Cast(언리얼의 Cast 는 업/다운 캐스팅을 할 수 있도록 구현되어 있다)를 쓰는 것보다..
텍스트 조회 보통 프로젝트 규모가 커지게 되면, 각종 스트링들을 스트링 테이블에 넣어서 사용할 것이다. 이때 스트링 테이블은 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..