갬장장이
갬장장이의 코드 대장간

전체 글

game engines/Unreal Engine

[UE5] FRunnable, FRunnableThread 사용 시 참고

언리얼 5.2.1 기준으로 작성되었습니다 1. FRunnable의 가상함수들은 직접 호출할 필요가 없다. FRunnableThread의 여러 함수들이 스레드와 연결되어있는 FRunnable의 가상함수를 내부적으로 호출해 사용한다. 때문에 코드 작성 시에는 FRunnableThread로 스레드 동작의 흐름을 제어하며, FRunnable 가상함수를 직접 호출할 일은 거의 없다. 2. FRunnable::Init()의 override가 false를 반환하고 있지는 않은지 확인해야 한다. VS에서 자동으로 정의를 만드는 기능을 사용해 함수 구현부를 자동 생성하면 항상 false를 반환하도록 구현하기 때문에 주의가 필요하다. 3. FRunnableThread::Kill()을 사용할 때는 조심해야 한다. 이 함수는..

game engines/Unreal Engine

[UE5] Standalone Playmode에서 빌드가 업데이트가 안되는 경우

빌드를 하고 나서 뷰포트 Playmode에서는 정상적으로 최신 빌드가 플레이 되지만 Standalone playmode에서는 플레이 되는 경우가 있다. 원인은 Live Coding과 관련된 이슈로 추정되며, Live Coding을 끄고 다시 한 번 빌드를 하고 실행하면 Standalone playmode에서도 제대로 최신 빌드가 실행되는 것을 볼 수 있다.

game engines/Unreal Engine

[UE5] exception_access_violation writing address 0x0000000000000000

결론부터 말하면, 어디선가 Null포인터에 접근하고 있을 가능성이 크다. NULL Check를 코드 전체에서 제대로 하고 있는지 확인하자. 크래시 발생 시 출력되는 로그를 살펴보면 대략적인 에러 지점을 알 수 있는데, 정확한 에러지점이 아닌 경우가 있어 해당 포인트 이전 실행과정들을 거슬러 올라가며 살펴봐야 한다.

game engines/Unreal Engine

[UE5] 윈도우 라이브러리를 사용하며 발생하는 문제들

윈도우 계열의 일부 라이브러리를 사용할 경우, 언리얼에서 정의된 값들 간의 이름 충돌 방지를 위해 헤더 추가지점과 외부 헤더에 정의된 값을 사용하는 코드의 앞뒤를 특수한 헤더로 감싸주어야 한다. 그렇지 않을 경우 링커 관련 에러가 발생할 수 있다.// Socket.h #include // (코드) // 에러 발생// Socket.h #include "Windows/AllowWindowsPlatformTypes.h" #include "Windows/prewindowsapi.h" #include // (코드) #include "Windows/PostWindowsApi.h" #include "Windows/HideWindowsPlatformTypes.h" 또 AllowWindowsPlatformTypes.h는..

game engines/Unreal Engine

[UE5] Could not be compiled, Try rebuilding ...

해당 에러를 발생시키는 다양한 이유들이 있을 수 있지만 가장 흔한 사유는 Dependencies에 필요한 모듈을 추가하지 않는 경우이다. 예시로, 소스코드의 어떤 부분에서 FSocket을 사용한다면 FSocket이 정의된 Sockets 모듈을 .Build.cs의 Public 또는 Private dependencies에 추가해주어야 에러가 발생하지 않는다.

game engines/Unreal Engine

[UE5] MSB3073 에러

당연히 에러 코드만 보고 정확히 진단하기 어렵고 원인이 여러 가지가 있을 수 있는데, 프로젝트 초반부에 빌드 시 이 에러가 발생한다면 UE5의 Live coding과 관련해 발생하는 것일 가능성이 크다. 이 경우 Ctrl Alt f11을 눌러 Live coding을 사용해 컴파일, 빌드하거나 혹은 아예 Live coding 기능을 꺼버린 후 VS에서 빌드하는 방식으로 해결 가능하다.

lang/c++

std::shared_ptr은 thread-safe한가?

1) shared_ptr의 레퍼런스 카운팅은 thread safe하다 2) 즉 shared_ptr의 control block(레퍼런스 카운트 정보를 담고 있는 부분, 참고)은 thread safe 하다 3) 그러나, shared_ptr 자체가 가리키는 객체는 thread safe하지 않다 4) C++20부터는 atomic_shared_ptr의 사용이 가능하다// Thread-safe std::shared_ptr ptr = std::make_shared(4); for (auto i =0;i

life

군생활 회고록

짧다면 짧고 길다면 긴 군대에서의 1년 6개월이 지나갔다. 지난 1년 6개월간은 정말 다이나믹했다. 분명 육군 전체에서도 꽤 유니크한 편이라고 생각한다. 군대에서 있었던 에피소드들을 털어놓는 것도 재미는 있겠지만, 그런 건 친구들과의 안줏거리 정도로 만족한다. 이번 포스트에서는 지난 1년 6개월간 내가 무엇을 배웠고, 앞으로 어떻게 해 나갈 것인지를 정리해보고자 한다. 1년 반, 무얼 얻었나? 군생활을 하면서 우스갯소리로 "군대에서 얻을 건 없다"는 말을 종종 듣곤 했지만, 돌이켜보면 얻은 게 없지는 않다. 군대는 체력적으로 더 강해질 수 있는 여건을 마련해주었다. 입대 전에도 맨몸운동 정도는 꾸준히 했지만, 입대 후 규칙적인 생활 패턴 속에서 생활하며 더 체계적으로 운동을 할 수 있게 되었다. 스스로가..

computer graphics/DirectX

[D3D Engine] 8.Error handling, Custom icon

이번 시간에는 에러 발생 시 이를 제대로 처리해줄 수 있도록 C++ exception을 활용하여 기능을 추가할 것이다. 커스텀 Exception 클래스를 정의하자. 여기서의 핵심이 되는 내용은 whatBuffer와 what()인데, stringstream을 활용해 타입과 로그 string을 whatBuffer에 저장하고 whatBuffer.c_str()으로 char*를 반환한다. 이때 그냥 한번에 return oss.str().c_str()을 하지 않는 이유는 stream의 특성 상 함수 종료시 삭제되기 때문에 (정확히는 stream은 copy가 불가능하므로 함수의 반환값으로 lvalue stream을 사용할 수 없는 것) 함수 외부의 클래스 멤버로 저장된 whatBuffer에 데이터를 저장해둔 후 이를..

computer graphics/DirectX

[D3D Engine] 7. Window framework

지금까지 만든 내용들을 사용하기 편하도록 프레임워크의 형태로 만들어보자. 우선 winapi 헤더를 직접 define하는 대신 별도의 헤더를 정의해 거기서 window 헤더를 define해주고 대신 그 헤더를 define해주자. 사실 이런 방식은 다른 프로젝트에서도 흔히 볼 수 있는 방식인데, WinApi를 사용할 때 특히 이 부분이 중요한 이유는, 윈도우api가 자체적으로 정의하는 요소들이 프로젝트 내부에서 문제를 일으킬 수 있기 때문이다. 한가지 예시로, 아래 헤더에서 #define NOMINMAX는 windows minmax 사용해제 옵션 매크로를 켜준 것으로, 이걸 켜주지 않으면 std::min std::max 등과 충돌해 예기치 못한(잡기도 힘든) 버그들이 발생할 수 있다. 추가로, 이 헤더를 정..

computer graphics/DirectX

[D3D Engine] 6. WM_CHAR, Mouse

이번 시간에는 WM_CHAR 메세지와 마우스 관련 메세지 처리에 대해 알아보자. 프로그램 실행 후 알파뱃 키를 누르면 WM_CHAR과 WM_KEYDOWN 둘다 뜨는 것을 볼 수 있는데, 이 둘은 용도가 다르다. WM_CHAR은 텍스트 인풋을 받는다거나 할 때 사용되는 메세지로, 알파뱃키(+엔터나 스페이스바와 같은 일부 특수한 경우)에 대해서만 호출된다. 즉 F1을 누르면 WM_KEYDOWN은 뜨지만 WM_CHAR 메세지는 받지 않는다. 또 대소문자 구분(Shift)없이 누른 키에 대한 값을 출력했던 WM_KEYDOWN과 달리, WM_CHAR은 쉬프트 눌린 여부에 따라 파라미터 값도 변한다. 그리고 이렇게 어떤 상황에서 WM_CHAR을 출력해야하는지를 결정하는 과정이 앞서 대략적인 흐름을 살필 때 봤던 T..

computer graphics/DirectX

[D3D Engine] 5. Window Messages

지난 시간에 이어서 윈도우 메세지를 계속 다뤄보자. 시작하기에 앞서, 윈도우 MSDN에는 메세지 하나하나에 대한 개별적인 항목은 있으나 메세지들의 목록이 없어 불편하기 때문에, 대신 사용할 수 있는 사이트 하나를 기재한다. https://wiki.winehq.org/List_Of_Windows_Messages 다만 여기에는 목록만 있을 뿐 어떤게 자주 쓰이는지에 대한 정보는 없기 때문에, 편의를 위해 우리의 커스텀 WndProc이 어떤 메세지를 수신할 때마다 그 메세지의 이름과 lParam, wParam을 출력해주는 WindowsMessageMap이라는 객체를 만들어 사용하자. 또 이 객체에는 자주 쓰는 메세지들에 대해서는 메세지 int와 메세지 이름을 맵핑시켜주어 출력될 수 있게 만들자. 구현에 어려운..