최근 새로 설치한 팀시티 빌드 에이전트에서 언리얼 엔진 소스를 체크아웃받아 놓은 폴더가 있었는데, 어느 날 확인 해보니 사라져 있었다.

엔진은 리빌드를 하면 너무 오래 걸리기 때문에 수정된 내용만 컴파일되도록 가급적 건드리지 않는 게 좋은데, 이렇게 사라져 버리면 전체 빌드를 하느라 시간이 많이 걸린다. 

원인을 파악해 보니 예전에도 본 것 같은 기능이 있었는데, 팀시티는 여러가지 이유로 체크아웃 폴더를 삭제하고 다시 받도록 할 수 있는데, VCS 설정이 바뀌거나 디스크 용량이 부족해서 삭제를 하는 것은 당연하지만 아무것도 안 했는데 삭제를 하는 것은 기간만료 기능 때문이다. 약 8일 정도 사용을 안 하면 자동으로 삭제를 한다고 한다.

팀시티 문서 링크: https://www.jetbrains.com/help/teamcity/2024.07/build-checkout-directory.html#Checkout+Directory+Expiration

 

Build Checkout Directory | TeamCity On-Premises

 

www.jetbrains.com

 

해당 기능을 끄려면 문서에도 나와 있듯이 두가지 방법 중 하나를 사용하면 된다.

빌드 에이전트 머신으로 들어가서 buildAgent.properties 파일을 찾아서 다음의 속성을 추가한다.

teamcity.agent.build.checkoutDir.expireHours=never

이 방법은 에이전트 머신마다 설정하는 방법이고 해당 에이전트에서 빌드하는 모든 프로젝트에 적용된다.

 

혹은, 팀시티 프로젝트에서 다음의 속성을 추가한다. (이 방법 추천)

system.teamcity.build.checkoutDir.expireHours

이 방법이 더 나은 거 같다. 원하는 프로젝트나 설정에만 적용할 수 있기 때문이다. 물론 전체 적용을 원한다면 Root project에 한 번만 설정하면 된다.

'개발 > 팀시티' 카테고리의 다른 글

팀시티 2018 설치하기  (0) 2019.03.12
팀시티 2018에서 사용할 MySQL 설치하기  (0) 2019.03.12

언리얼 엔진 최신 버전(5.4.2)을 비주얼 스튜디오 최신 버전 (2022)으로 컴파일하려고 하니 다음과 같은 경고가 뜬다.

Visual Studio 2022 compiler version 14.40.33811 is not a preferred version. Please use the latest preferred version 14.38.33130

 

그리고, 이상한 곳에서 컴파일 에러도 뜬다.

...Engine\Source\Runtime\Core\Public\Templates\SharedPointer.h(1092) : error C4702: unreachable code

 

검색을 해 보니, 언리얼 엔진 최신 버전과 비주얼 스튜디오 최신 버전간 호환성 문제가 있다고 한다.

비주얼 스튜디오 인스톨러에서 14.38에 해당되는 툴체인을 설치하면 해결된다.

정확히 뭐가 필요한 지 몰라서 14.38로 검색되는 걸 일단 다 설치해 보니 문제가 해결되었다.

일반적으로 많이 사용하는 Actor나 ActorComponent가 아니라, 간혹 Object를 바로 상속받거나 LocalPlayerSubsystem 같은 클래스를 상속받은 BP 클래스를 만들어서 사용해야 할 때가 있다. 그런데, 그렇게 상속받은 클래스에서 BlueprintFunctionLibrary에 정의된 함수를 호출하려고 하면 잘 안된다. 에디터에서 마우스 오른쪽을 눌러 다른 BP 함수 라이브러리의 함수를 찾아도 아예 보이지가 않는다.

 

정확한 원인은 잘 모르겠지만, BlueprintFunctionLibrary 함수를 호출할 때는 호출하려는 클래스의 GetWorld 함수 접근이 필요한데, Actor나 ActorComponent의 경우 해당 함수가 에디터에서도 접근할 수 있게 노출되어 있지만, UObject나 Subsystem 계통의 클래스들은 그게 안되어 있어서 생긴 문제로 보인다.

 

그래서, BP 클래스를 만들기 전에 부모 클래스를 c++로 만들고, Blueprintable 속성을 넣어주고, GetWorld 함수를 오버라이드하면 해결이 된다.

// MyGameSoundSubsystem.h
UCLASS(Blueprintable)
class MYGAME_API UMyGameSoundSubsystem : public ULocalPlayerSubsystem
{
    GENERATED_BODY()

public:
    virtual UWorld* GetWorld() const override;
//...
};
  
  
// MyGameSoundSubsystem.cpp
UWorld* UMyGameSoundSubsystem::GetWorld() const
{
#if WITH_EDITOR
    if (IsTemplate())
    {
        return nullptr;
    }
#endif

    return Super::GetWorld();
}

가장 간단한 방법은 위의 코드처럼 cpp 함수의 구현부에서 그냥 부모 함수만 호출해도 되긴 하는데, 에디터에서는 뭔가 또 다르게 작동하는 게 있어서 예외처리는 필요하다.

 

항상 위의 코드처럼 작성해야 하는 건 아니고 경우에 따라서는 부모 클래스나 Outer 클래스를 참조해야 할 필요도 있고, WorldContext를 명시적으로 노출해서 사용해야 하는 경우도 있다.

 

코드 출처: https://forums.unrealengine.com/t/can-you-use-a-blueprint-function-library-in-an-object-class/350918/31

 

ps. 일반적으로 Actor나 ActorComponent는 현재 맵(Level)의 월드에 귀속되지만, UObject를 상속받은 클래스 혹은 Subsystem 클래스들은 싱글턴처럼 쓰이는 경우가 많고, 현재 월드가 아닌 다른 월드(엔진 기본 월드?)에 귀속되어 있을 수 있다.

+ Recent posts