목록Categories (1103)
KoreanFoodie's Study

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 구조체의 대략적인 구조를 보자..

ENUM_CLASS_FLAGS 사용하기 (언리얼 플래그 사용법) 핵심 : 1. 여러 조건을 동시에 가질 수 있는 상황을 다를 때는, Enum Class 의 값을 Shift 연산자를 활용해 Bit Flag 처럼 사용하는 것이 좋다. 2. EnumClassFlags 파일에 정의된 템플릿 함수들(e.g. EnumHasAnyFlags)을 활용하면, Enum Class 에 정의된 플래그들을 이용해 케이스들의 중첩을 효율적으로 체크할 수 있다. 3. 일반적으로 Enum Class 내의 값들을 Flag 로 표현하는 경우는 UI 나 환경설정 세팅 등이 있다. 일반적으로 Enum Class 는 같은 주제 내에서 여러 조건들을 다룰 때 사용한다. 그런데 만일 여러 복합적인 상황을 동시에 다뤄야 하는 케이스가 있다고 하면 ..

TimerHandle 배열 사용하기 (TimerHandle Array) 핵심 : 1. TArray 타입을 사용하면 된다. 2. 새로운 FTimerHandle 을 넣을 때는 Emplace 를 사용한다. 3. 객체가 파괴되거나 정리하는 시점에 ClearTimer 및 배열을 비워주는 작업을 해 주자. 설명할 것은 위의 3줄 요약에서 다 했으니, 코드만 보자. // 선언 // 일정 시간 후 UTextBlock 본래 색상으로 돌아가게 만들때 사용하는 타이머핸들 TArray timerHandleList; // 구현 void UTestWidget::NativeConstruct() { for (int i = 0; i < 10; ++i) { FTimerHandle newTimerHandle; timerHandleList..

동적으로 컴포턴트 생성하기 (Dynamically create ActorComponent) 핵심 : 1. 일반적으로 ActorComponent 는 생성자에서 CreateDefaultSubobject 함수를 통해 CDO 가 생성된다. 2. 동적으로 액터 컴포넌트를 생성할 때는 두 가지 방법이 있다. 블루프린트에서는 AddComponent 함수를 사용하면 되며, C++ 에서는 NewObject 로 ActorComponent 를 생성 후, 기존 RootComponent 에 Attach 하는 방식을 활용한다. 3. 커스텀 AddComponent 함수를 만들어서 편하게 활용하거나, 템플릿 함수를 만드는 것도 좋은 방법이다. 블루프린트에서 AActor 클래스에는 AddComponent 라는, 내부적으로 NewObj..

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); } 내부..