목록Game Dev/Unreal C++ : Dev Log (48)
KoreanFoodie's Study
현재 시간 로그 찍기 핵심 : 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" 한 존에 위젯이 잘리는 것을 방지할 수 있다! 참고 : 언리얼 공식 문서
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..
슬레이트 구조 (아키텍처) 사실 언리얼에는 이미 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 에는 위..
더티 플래그 패턴이란? 더티 플래그 패턴에 대해서는, 이전 블로그 글에서 간단하게 언급한 바 있다. 더티 플래그 패턴은 일반적으로 렌더링 과정에서, 계층 구조가 존재할 경우, 필요할 때 / 필요한 타이밍에 화면을 갱신하는 부분에서 자주 쓰인다. 또한 더티 플래그를 체크해 UI 를 갱신하게 되면, Tick 마다 UI 업데이트가 중복해서 일어나는 것을 막을 수 있다. 그렇다면 이 패턴을 언리얼에서는 어떤 방식으로 적용해 볼 수 있을까? 예를 들어, 우리가 어떤 UI 를 갱신 하는데,Dirty Flag 를 두어 해당 더티 플래그가 켜져 있을 때만 UI 를 갱신한다고 가정해 보자. 일단, 실제로 UI 클래스를 만들기 전에, 더티 플래그 패턴을 사용할 위젯들이 공통적으로 사용할 인터페이스를 다음과 같이 정의할 수..
MoveTo 와 애니메이션 비헤이비어 트리 로직을 짜면서 MoveTo 를 테스트했는데, 해당 지점으로 이동할 때 걷는 애니메이션이 재생되는 것이 아니라 캐릭터 메시 자체가 미끄러지듯이 슬라이딩하는 현상이 생겼다. 애니메이션을 어떻게 하면 재생할 수 있지? 라고 생각하며 AnimBP 를 잘 연결해줬는데도 동작이 제대로 안되는 상황이 있었다. 언리얼 포럼에서는 다양한 해결책을 제시한다. 1. 애니메이션 블루프린트 연결 확인하기 2. CharacterMovement -> NashMovement 에서 Use Acceleration for Paths 체크하기 근데 나는 이 두가지 전부 아니였다. 나의 경우, 아래와 같이 Speed 값에 따라 애니메이션을 변경하는 블렌드 스페이스를 만들었는데, 알고보니 Speed ..