['언리얼 서밋 2018' 발표자 소개] 신광섭 리드 개발자는 에픽게임즈 코리아에서 릴레이션 리드 및 프로그래머로 재직 중이다. 이전에는 언리얼 엔진 2, 3을 이용한 ‘마그나카르타’ PS2/PSP와 XBox 360 버전 개발에 참여한 바 있다.

UE4는 VS를 사용하지만 특별한 빌드 시스템을 통해 코드 빌드가 되고, 기본 언어로 C++을 사용하지만 게임 오브젝트를 위한 UObject 클래스 사용을 통해서 일반 C++에는 없는 기능들을 지원한다. 신광섭 개발자는 이런 특징들로 UE4를 처음 접하는 프로그래머분들이 혼란을 겪는 요소에 관해서 설명한다. 또한, 엔진 수정 후 배포 빌드 방법 그리고 모바일 프로그래밍을 위해서 알면 좋을 팁들도 같이 소개했다.

UE4로 개발 환경을 갖추기 위해서 PC의 경우 마이크로소프트의 비주얼 스튜디오를 함께 사용해야 한다. 4.15 버전부터는 VS2017이 기본으로 탑재되어 있다. Mac을 사용할 경우 Xcode를 IDE로 사용하면 된다. 비주얼 스튜디오 2017을 설치할 때에는 ‘C++를 사용한 게임 개발’을 선택하고, 풀 소스코드 개발의 경우 ‘.NET 데스크톱 개발’을 선택하면 된다. ‘언리얼 엔진 설치 관리자’는 개발자의 선택 사항이다.

신광섭 개발자는 비주얼 스튜디오의 첫 번째 설정으로 솔루션 컨피그레이션(Solution Configuration)의 크기를 늘리라고 조언했다. 사소하지만 생산성을 늘려주는 팁이다. 이 칸의 길이를 늘이는 방법은 사용자 지정에 있는 도구 모음(표준), 솔루션 구성의 선택 사항 수정을 클릭한다. 이후 솔루션 구성의 너비를 알맞게 수정하면 된다. 신광섭 개발자는 너비를 ‘160’으로 맞춰 사용한다.

비주얼 스튜디오를 사용하는 개발자라면, 언리얼VS(UnrealVS)를 ‘꼭’ 같이 사용하는 게 좋다. 언리얼VS를 설치하면 프로젝트의 파라미터를 사용할 수 있다. 즉, 디버그를 할 때 어떤 맵을 열고 속성 확인 등을 언리얼VS를 통해 가능하다. 그뿐만 아니라, 파라미터의 기록이 남아 클릭으로 히스토리를 확인할 수 있다. 또는 풀 소스 코드 관리에 유용하다.

▲ 맞춤형 라이선시는 별도의 계약이 필요하다

깃허브를 통해 유용한 UE4 브랜치를 다운받을 수 있다. 4.xx 브랜치는 런처의 각 바이너라 엔진 버전과 같은 코드이다. 주목할 것은 디벨롭먼트 단계인 Dev-xxx 브랜치다. 디벨롭먼트 브랜치는 에픽게임즈에서 지난 5월 10일부터 깃허브에 푸쉬(push)한 브랜치로, 본사에서 개발한 코드를 실시간으로 확인하고 적용해볼 수 있다. 상위 단계인 Master 브랜치는 Dev-xxx의 내용이 모이는 브랜치다. 단, 빌드나 실행 등의 이슈가 있을 수 있어 주의가 필요하다. Promoted 브랜치는 Master의 기본적인 QA가 통과된 빌드이다. 안정적인 사용을 원할 경우 내부 QA를 완벽히 통과한 Release 브랜치를 사용하는 게 좋다.

기본적인 설정을 마치고 UE4로 프로젝트를 시작하면 재미난 일이 발생한다. 기본 코드가 있는 C++ 템플릿을 개발자가 빌드하지 않았음에도 새로운 프로젝티의 에디터와 함께 VS나 Xcode가 자동으로 열린다. UE4의 자동 빌드의 비밀은 언리얼빌드툴(UnrealBuildTool)에 있다. UE4의 소스코드를 실제로 빌드하는 툴로, VS와 Xcode는 편집기의 역할만 한다. 실제로 빌드는 언리얼빌드툴이 한다.

UE4는 언리얼빌드툴을 사용함으로써 멀티 플랫폼 개발이 편리하다. PC, 안드로이드, iOS, PS4, Xbox One, 닌텐도 스위치 등 다양한 플랫폼의 개발을 VS로 할 수 있다. 특히 언리얼빌드툴은 iOS 빌드를 윈도우 PC에서 Mac으로 원결 빌드가 가능하도록 지원해준다. 또한, 언리얼 엔진 유오브젝트(UObject) 시스템을 위한 언리얼헤더툴(UnrealHeaderToll)을 자동으로 실행한다. 이를 통해 유오브젝트 헤더 파일들을 파싱해서 실제 빌드에 사용하는 헤더 파일을 자동으로 생성한다.

단, 언리얼빌드툴은 기존에 알던 컴파일러 옵션 등의 설정 방식이 다르다. 프로젝트 속성에서 설정하는 게 아니라, UnrealBuildTool 파라미터 또는 코드 수정으로 설정해야 한다. 그리고 컴파일돼야 하는 소스코드 파일을 가져오는 방식이 달라 프로젝트에 추가되지 않은 코드들도 컴파일됨을 염두해야 한다.

언리얼 엔진은 개발자가 필요한 거만 뽑아 쓸 수 있도록 최대한 모듈을 나누어 제작됐다. 같은 엔진이라도 클라이언트, 서버 개발자에 따라 필요한 기능이 한정돼 있기 때문이다. 프로젝트의 각 모듈은 소스 폴더 아래 모듈 이름의 폴더를 가진다. 이 폴더 아래에 소스 코드들이 자동으로 빌드되는 게 언리얼 엔진의 특징이다. 모듈 이름의 폴더 아래 '모듈이름.Build.cs' 파일이 필요하고, 이 파일에는 참조하는 다른 모듈들의 설정 및 빌드 관련 옵션 기록이 있다. 타겟 빌드시에 설정된 모듈들만 빌드되기 때문에 효율적이다.

언리얼 빌드 시스템에서 'IDE 프로젝트 관리'는 필요한 소스 코드만 공유하고 각 프로그래머가 로컬에서 만들 수 있도록 한다. 즉, 언리얼 엔진은 VS솔루션, 프로젝트, 워크스페이스(workspace) 파일들을 공유할 필요가 없다. 플랫폼별 프로젝트에 코드 추가, 제거를 신경 쓰지 않아도 되고, 프로젝트 머지(merge) 이슈에서 해당된다는 장점이 있다. 단, 프로젝트에서 코드를 제거했다고 안심하면 안 되고 필요 없는 코드는 꼭 삭제해야 한다.

▲ UE4의 솔루션 컨피그는 상황에 맞게 씀이 좋다

UE4의 솔루션은 선택된 플랫폼에 따라, 언리얼빌드툴이 설정된 정보로 자동으로 빌드되게끔 한다. 빌드가 되면 '프로젝트 폴더/Binaries/플랫폼' 폴더에 바이너리 파일이 생성된다. 에디터(Editor)가 붙으면 Win64/Mac 등 에디터가 되는 데스크탑 플랫폼만 지원된다.

내부적으로 엔진 코드를 수정해야 할 경우에는 빌드그래프(BuildGraph)를 사용할 수 있다. 이 툴은 언리얼 엔진이 제공하는 스크립트 기반의 빌드 시스템이다. 수정을 통해 개발자가 원하는 플랫폼만 빌드할 수 있어 유용하다. 수정 후에 간단히 RunUAT.bat에 파라미터를 주고 실행해서 빌드가 가능하며, 풀 소스 코드 경로/LocalBuilds/Engine/Window 폴더에 배포해야 할 파일들이 생성된다.

▲ 빌드한 배포 버전을 등록하는 방법

UE4에서 C++의 한계를 넘도록 해주는 것이 유오브젝트(UObject)이다. 유오브젝트는 UE4의 일반적인 클래스들의 최상의 클래스이다. C++의 제한을 넘어선 여러 가지 유용한 기능을 제공하는데, 자동 변수 Serialization, 가비지 컬렉션, 블루프린트 integration, 네트워킹 등이다. 특별한 마크업(Markup)들로 C++ 클래스를 선언하며, 빌드 시에 UnrealHeaderTool이 파싱해서 실제 헤더 파일을 생성한다.

언리얼 프로그래밍에서 AActor는 레벨에 배치, 생성되어 위치 정보를 갖는 게임플레이의 기본 요소다. 유오브젝트의 자식 클래스로, 같은 특징을 다 갖는다. 생성한 액터는 명시적인 삭제가 필요하다. 레벨이 이동 등으로 언로딩 되면, 생성된 모든 액터들이 삭제되니 주의해야 한다. 중요 함수로는 BeginPlay, Tick, EndPlay가 있다.

▲ 숙지하면 크게 도움 되는 언리얼 타입 이름 규칙

▲ 람다 함수 등 중요한 C++ 11 기능을 UE4에서 지원한다

또한, UE4는 TArray, TMap, TSet 등 유용한 자체 컨테이너를 지원한다. FVector, FRotator, FColor 등 게임에 꼭 필요한 기본 변수형들도 물론 있다. 이외에도 UE4는 자체적으로 스마트 포인터와 String 타입을 제공한다. 수학 관련 함수는 FMath는 각 플랫폼별 PlatformMath.h에서 각 헤더를 확인할 수 있다. 파일 매니징 클래스의 경우 FPlatformFileManager를 통해 실제 플랫폼 파일 시스템 인터페이스에 접근할 수 있다.

UE4는 로깅을 위한 유용한 유틸 클래스가 있다. UE_LOG를 통한 로깅은 버퍼 형식인데, 매크로를 통해서 원하는 로그 종류를 선언할 수 있다. 이 방식은 일반적인 로깅에 이용된다. 즉각적인 로깅이 필요하고, 플랫폼에 특화된 디버깅용 로딩은 FPlatformMisc::LowLevelOutputDebugString이 있다.

신광섭 개발자는 "많은 UE4 입문자가 시작 포인트를 궁금해할 텐데, 메인 루프에 위치한다"고 소개한다. UE4의 메인 엔진 루프는 각 플랫폼에서 해당 엔진의 Tick을 호출한다. 게임 플레이의 시작 포인트는 AGameMode 클래스이다. 게임의 중심은 맵이고, 로딩 시 그에 맞는 한 개의 기본 GameMode 인스턴스가 생성된다. 그는 GameMode 클래스가 게임의 지배자라고 빗댄다.

UE4의 '핫 리로딩(Hot Reloading)' 기능은 에디터가 켜져 있는 상태에서 C++ 코드 빌드 및 적용이 되는 기술이다. '컴파일' 버튼 클릭으로 핫 리로딩이 가능하다. 신광섭 개발자는 에디터가 열려있는 상태에서 VS 빌드시에도 핫 리도딩 빌드가 가능하다고 덧붙였다.

▲ 디자이너가 편히 쓸 수 있도록 편수 에디터를 만들 수도 있다

▲ 경우에 따라 체크박스를 비활성화시켜 실수를 예방한다

끝으로 신광섭 개발자는 플랫폼별 디버깅 팁을 소개했다. iOS 디버깅 시 Xcode의 기본 설정에서는 연결된 디바이스가 보이지 않을 때가 있다. 이때 Build Configuration 설정을 iOS 디바이스가 호환되도록 변경하면 된다.

iOS 디버깅을 위해서는 쿠킹된 콘텐츠가 필요한데, 그는 Mac보다는 PC가 좋은 CPU를 가진 경우가 많으니 PC에서의 쿠킹을 추천했다. PC에서 iOS 타겟으로 쿠킹한 콘텐츠를 준비하고 디버깅에 사용할 ipa 파일 패키지를 열어 cookeddata를 복사하면 된다. 이렇게 하면 브레이크 포인트를 걸고 자유로운 디버깅이 가능하다.

안드로이드의 디버깅은 Open으로 브레이크 포인트를 걸고 싶은 소스 코드를 열어 건다. 이후 Run의 Debug 'app'으로 디버깅을 하고, 코드 수정이 생기면 다시 VS에서 Debug 'app'을 실행한다. 이 과정을 거치면 안드로이드 스튜디오를 통해서 gradle 빌드 및 설치가 훨씬 빨라진다.