데이터 레지스트리(Data Registry) 는 USTRUCT
태그가 지정된 데이터 구조를 위한 효율적인 글로벌 스토리지 공간입니다. 데이터 레지스트리는 동기식 및 비동기식 데이터 액세스와 사용자 정의 캐싱 행동을 지원합니다. 또한 데이터 레지스트리는 일반 읽기 전용 데이터로 작동하도록 설계되었습니다.
데이터 레지스트리는 플러그인의 일부입니다. 데이터 레지스트리 퀵스타트에서 프로세스를 살펴보고 기본 개념을 익힐 수 있습니다. 스토리 진행 상황이나 캐릭터의 현재 스테이트와 같은 특정 세션 기반 데이터의는 엔진의 세이브 게임(Save Game) 시스템을 사용합니다.
데이터 레지스트리를 환경설정하여 다양한 소스로부터 데이터를 로드하거나 생성할 수 있으며, 에셋 스캔과 수동 등록으로 데이터 레지스트리를 채울 수도 있습니다. 데이터 레지스트리는 컴포짓 데이터 테이블 과 비슷하지만 표준 테이블 행뿐 아니라 커브 데이터도 저장할 수 있으며, 다수의 테이블을 수동으로 합성하는 대신 인디렉션 레이어를 사용합니다.
데이터 소스
데이터 레지스트리는 두 가지 타입의 소스에서 데이터 항목을 수집합니다. 바로 데이터 레지스트리 소스(Data Registry Sources) 와 메타 데이터 레지스트리 소스(Meta Data Registry Sources) 입니다. 이 두 소스는 실제 데이터 항목이 아닙니다. 데이터 레지스트리가 이 둘을 사용하여 데이터 항목을 찾거나 생성합니다. 데이터 레지스트리에 데이터 소스가 나타나는 순서는 중요합니다. 하나의 소스에서 특정 데이터 항목이 발견되지 않는 경우, 데이터 레지스트리는 목록상 그다음에 나타나는 소스에서 해당 항목을 찾게 됩니다.
이에 따라 오버라이드 및 예비 전환 행동이 나타날 수 있으며, 컨텍스트별 소스는 일반 소스를 오버라이드할 수 있습니다. 데이터 레지스트리 플러그인은 데이터 테이블 과 커브 테이블 을 래핑하는 내장된 데이터 레지스트리 소스 및 메타 데이터 레지스트리 소스를 포함합니다.
데이터 레지스트리는 두 가지 타입의 소스에서 데이터 항목을 수집합니다. 바로 데이터 레지스트리 소스(Data Registry Sources) 와 메타 데이터 레지스트리 소스(Meta Data Registry Sources) 입니다. 이 두 소스는 실제 데이터 항목이 아닙니다. 데이터 레지스트리가 이 둘을 사용하여 데이터 항목을 찾거나 생성합니다. 데이터 레지스트리에 데이터 소스가 나타나는 순서는 중요합니다. 하나의 소스에서 특정 데이터 항목이 발견되지 않는 경우, 데이터 레지스트리는 목록상 그다음에 나타나는 소스에서 해당 항목을 찾게 됩니다.
이에 따라 오버라이드 및 예비 전환 행동이 나타날 수 있으며, 컨텍스트별 소스는 일반 소스를 오버라이드할 수 있습니다.
데이터 레지스트리 플러그인은 데이터 테이블 (UDataTable
)과 커브 테이블 (UCurveTable
)을 래핑하는 내장된 데이터 레지스트리 소스 및 메타 데이터 레지스트리 소스를 포함합니다.
데이터 레지스트리 소스
데이터 레지스트리는 데이터 레지스트리 에셋 내의 배열에서 생성하고 환경설정하는 데이터 레지스트리 소스 오브젝트 세트를 직접 소유합니다. 이러한 오브젝트는 개별 데이터 테이블이나 웹 데이터베이스처럼 데이터 레지스트리가 정보를 찾을 수 있는 특정 데이터 소스의 인터페이스를 나타냅니다. C++ 개발자가 다른 타입의 데이터를 처리하거나 데이터 항목에 식별자를 매핑하는 여러 인디렉션 규칙을 구현하려면 데이터 레지스트리 소스 자손 클래스를 생성하면 됩니다. 프로젝트에 하나 이상의 데이터 레지스트리 소스 자손 클래스가 있으면 데이터 레지스트리 에셋에 새로운 데이터 소스를 추가할 때 목록에 이 클래스가 나타납니다.
데이터 레지스트리는 데이터 레지스트리 에셋 내의 배열에서 생성하고 환경설정할 수 있는 데이터 레지스트리 소스 오브젝트 세트를 직접 소유합니다.
이러한 오브젝트는 개별 데이터 테이블이나 웹 데이터베이스처럼 데이터 레지스트리가 정보를 찾을 수 있는 특정 데이터 소스의 인터페이스를 나타냅니다.
다른 타입의 데이터를 처리하거나, 데이터 항목에 식별자를 매핑하는 여러 인디렉션 규칙을 구현하려면 UDataRegistrySource
의 자손 클래스를 생성하면 됩니다.
생성한 모든 자손 클래스는 데이터 레지스트리 에셋에 새로운 데이터 소스를 추가할 때 드롭다운 목록에 나타납니다.
메타 데이터 레지스트리 소스
메타 데이터 레지스트리 소스는 런타임에 다른 데이터 소스를 생성하고 소유합니다. 메타 데이터 레지스트리 소스는 모든 데이터 소스를 명시적으로 나열하는 대신, 사용자 이름이 지정된 경로 세트를 스캔하는 것과 같이 일반 규칙을 사용하여 데이터 항목이 포함된 에셋을 찾습니다. 메타 데이터 레지스트리 소스는 특정 에셋의 수동 등록을 수신할 수도 있습니다. 메타 데이터 레지스트리 소스와 소스 내의 데이터 항목은 동적으로 생성되는 데이터 소스입니다. 그래서 런타임에 데이터 레지스트리로 가는 로드를 발견합니다.
C++ 개발자는 데이터 레지스트리와 마찬가지로 다른 데이터 타입을 처리하기 위해 메타 데이터 레지스트리 소스 자손 클래스를 생성하거나 다양한 스캔 규칙을 생성할 수 있습니다. 프로젝트에 하나 이상의 메타 데이터 레지스트리 소스 자손 클래스가 있으면 데이터 레지스트리 에셋에 새로운 데이터 소스를 추가할 때 드롭다운 목록에 이 클래스가 나타납니다.
메타 데이터 레지스트리 소스는 런타임에 다른 데이터 소스를 생성하고 소유합니다. 메타 데이터 레지스트리 소스는 모든 데이터 소스를 명시적으로 나열하기보다, 사용자 이름이 지정된 경로 세트를 스캔하는 것과 같이 일반 규칙을 사용하여 데이터 항목이 포함된 에셋을 찾습니다. 또한 메타 데이터 레지스트리 소스는 특정 에셋의 수동 등록을 수신할 수도 있습니다.
메타 데이터 레지스트리 소스는 동적으로 생성되므로 해당 소스가 발견한 데이터 소스(소스 내 데이터 항목 포함)는 런타임에 데이터 레지스트리로 로드됩니다.
데이터 레지스트리 소스와 마찬가지로 다른 데이터 타입을 처리하기 위해 자체적인 자손 클래스를 생성하거나 다양한 스캔 규칙을 생성하는 등의 작업이 가능합니다. 이렇게 하려면 UMetaDataRegistrySource
클래스를 오버라이드합니다.
생성한 모든 자손 클래스는 데이터 레지스트리 에셋에 새로운 데이터 소스를 추가할 때 드롭다운 목록에 옵션으로 나타납니다.
식별자
데이터 레지스트리 플러그인은 자체적인 식별자 타입을 사용하여 데이터 레지스트리와 여기에 포함된 개별 데이터 항목을 식별하거나 검색합니다. 이러한 식별자는 근본적으로 스트링 기반 이름이지만, 데이터 레지스트리 에셋의 FDataRegistryType
및 데이터 레지스트리 내 개별 항목의 FDataRegistryId
구조는 래퍼로 작용하며 에디터 내에서 유용한 함수 기능을 제공합니다.
FDataRegistryType
은 데이터 레지스트리 에셋을 식별하고, FDataRegistryId
는 데이터 레지스트리와 그 안에 있는 특정 데이터 항목을 식별합니다. 데이터 레지스트리 에셋을 찾거나 에셋에서 개별 데이터 항목을 얻어야 할 때 이러한 식별자 타입을 사용합니다.
각 데이터 레지스트리 에셋은 Registry Type 필드에 고유한 이름이 있어야 합니다. 두 데이터 레지스트리 에셋의 이 필드 이름이 동일할 경우, 시스템은 그중 하나만 인식하고 채웁니다. 마찬가지로 여러 데이터 항목에 동일한 식별 값(이름 또는 게임플레이 태그)이 있는 경우, 레지스트리는 모든 항목을 읽지만 얻기 작업은 데이터 레지스트리 에셋이 로드한 것 중 첫 번째 항목에만 액세스합니다. 데이터 항목이 로드되는 순서에 대해 알아보려면 데이터 소스 섹션을 참조하세요.
C++를 사용하는 개발자는 자손 데이터 레지스트리 클래스를 생성하고 ResolveDataRegistryId
함수를 오버라이드하여 이 행동을 변경할 수 있습니다.
데이터 레지스트리 에셋 식별자
개발자는 데이터 레지스트리 에셋을 설정할 때 Registry Type 필드를 고유한 이름 값으로 설정해야 합니다. 이는 데이터 레지스트리의 식별자입니다. 이 값을 설정하면 에디터의 모든 레지스트리 타입 필드는 즉시 드롭다운 목록에 새로운 데이터 레지스트리 이름을 추가하게 됩니다.
이렇게 되면 다른 에셋의 데이터 레지스트리를 참조할 때 사용자의 맞춤법 오류가 발생하지 않으며, 더욱 쉽고 빠르게 선택 프로세스를 진행할 수 있습니다.
개발자는 데이터 레지스트리 에셋을 설정할 때 Registry Type 필드를 고유한 이름 값으로 설정해야 합니다. 이는 데이터 레지스트리의 식별자입니다.
이 값을 설정하면 에디터의 모든 FDataRegistryType
필드는 드롭다운 목록에 새로운 데이터 레지스트리 이름을 즉시 추가하게 됩니다.
이렇게 되면 다른 에셋의 데이터 레지스트리를 참조할 때 사용자의 맞춤법 오류가 발생하지 않으며, 더욱 쉽고 빠르게 선택 프로세스를 진행할 수 있습니다.

위는 데이터 레지스트리 에셋의 식별자를 설정하는 것입니다. 아래는 데이터 레지스트리 에셋을 참조해야 하는 액터에서 식별자(또는 해당 데이터 레지스트리 내의 특정 행)를 선택하는 것입니다.

데이터 항목 식별자
데이터 테이블 내의 행과 같은 개별 데이터 항목을 식별하려면 데이터 레지스트리 에셋과 데이터 항목 자체를 지정해야 합니다. 데이터 레지스트리 ID에는 두 식별자가 모두 포함됩니다. Data Registry Type 필드는 드롭다운 목록으로 나타나며, 알려진 모든 데이터 레지스트리는 이 목록에서 식별 이름에 따라 선택할 수 있습니다. 이 드롭다운 목록에서 데이터 레지스트리 이름을 선택하면 데이터 레지스트리 ID(Data Registry ID) 필드가 해당 데이터 레지스트리에 맞게 변경됩니다.
데이터 레지스트리의 ID 포맷이 게임플레이 태그를 사용하는 경우, 유저 인터페이스는 게임플레이 태그와 모든 관련 자손을 포함하는 필터링된 목록을 표시하게 됩니다. 데이터 레지스트리의 ID 포맷이 게임플레이 태그를 사용하지 않는 경우, 유저 인터페이스는 데이터 레지스트리 에셋에 포함된 알려진 모든 행의 드롭다운 목록을 표시하게 됩니다.
데이터 테이블 내의 행과 같은 개별 데이터 항목을 식별하려면 데이터 레지스트리 에셋과 데이터 항목 자체를 지정해야 합니다. FDataRegistryId
타입에는 두 식별자가 모두 포함됩니다. Data Registry Type 필드는 드롭다운 목록으로 나타나며, 알려진 모든 데이터 레지스트리는 이 목록에서 식별 이름에 따라 선택할 수 있습니다.
이 드롭다운 목록에서 데이터 레지스트리 이름을 선택하면 데이터 레지스트리 ID(Data Registry ID) 필드가 해당 데이터 레지스트리에 맞게 변경됩니다.
데이터 레지스트리의 ID 포맷이 게임플레이 태그를 사용하는 경우, 유저 인터페이스는 게임플레이 태그와 모든 관련 자손을 포함하는 필터링된 목록을 표시하게 됩니다. 데이터 레지스트리의 ID 포맷이 게임플레이 태그를 사용하지 않는 경우, 유저 인터페이스는 데이터 레지스트리 에셋에 포함된 알려진 모든 행의 드롭다운 목록을 표시하게 됩니다.
데이터 레지스트리 에셋을 편집하는 경우, 데이터 항목 식별자를 사용하여 해당 에셋을 참조하는 다른 에셋에 변경 사항이 즉시 적용되지 않을 수도 있습니다. 이 경우 데이터 항목 식별자는 드롭다운 목록에 구버전 행을 포함할 수도 있습니다. 데이터 레지스트리 에셋 자체가 아닌 데이터 레지스트리를 참조하는 에셋에서 컴파일(Compile) 버튼을 클릭하여 현재 데이터 항목 정보로 인터페이스를 업데이트합니다.

왼쪽은 게임플레이 태그를 사용하는 ID 포맷이 적용된 데이터 레지스트리 에셋의 항목을 선택한 것입니다. 오른쪽은 단순한 이름을 사용하는 데이터 레지스트리 에셋의 항목을 선택한 것입니다.
FDataRegistryId
에는 RegistryType
이라는 FDataRegistryType
멤버가 있으므로 별도의 FDataRegistryType
식별자 없이도 해당 행을 포함하는 데이터 레지스트리 에셋을 찾을 수 있습니다.
식별자 해석
시스템은 입력한 데이터 레지스트리 ID의 항목 이름(Item Name) 을 검색하여 데이터 항목을 찾습니다. C++에서는 자손 데이터 레지스트리 클래스를 생성하여 이 행동을 변경할 수 있습니다. 더 자세한 정보를 알아보려면 이 페이지의 C++ 버전으로 토글하시기 바랍니다.
동적 식별자 해석
기본적으로 시스템은 입력한 FDataRegistryId
의 ItemName
필드 값을 검색하여 데이터 항목을 찾습니다. 이 행동이 프로젝트에 적합하지 않은 경우, 자체적인 UDataRegistry
서브클래스를 생성하고 MapIdToResolvedName
함수를 오버라이드하여 로컬 영역에 FDataRegistryResolverScope
구조체를 추가로 포함합니다. FDataRegistryResolverScope
서브클래스 안에서 ResolveIdToName
함수를 오버라이드하면 동적 정보나 플레이어별 정보를 사용해서도 들어오는 행 이름을 리매핑할 수 있습니다. 시스템은 ID를 해석한 후 시스템 내에서 항상 고유하며 캐싱 고유 ID로 사용되는 FDataRegistryLookup
을 생성합니다.
함수 퀵 레퍼런스
다음은 데이터 레지스트리를 시작할 때 유용한 함수입니다. 이 레퍼런스에서는 모든 함수를 다루지는 않지만, 프로젝트에서 데이터 레지스트리를 설정한 후 데이터에 액세스할 때 필요한 기본적인 함수를 알아볼 수 있습니다.
- 데이터 레지스트리 항목 획득(Acquire Data Registry Item) 은 주어진 항목을 검색하고 성공 시 이 항목을 캐시에 로드합니다. 이 함수는 이 메타 데이터 레지스트리 소스에서 제공된 데이터 항목에 중요합니다. 다른 데이터 레지스트리 함수는 캐시된 데이터 항목에만 액세스할 수 있기 때문입니다. 어딘가 있을 수도 있지만 현재 캐시에는 없는 데이터 항목에 액세스하려면 이 함수를 호출합니다.
이 함수를 호출할 경우 오른쪽에 있는 핀을 통해 실행이 즉시 재개됩니다. 반환 값은 로딩 작업이 시작되었는지 여부를 나타내지만 해당 작업의 결과는 나타내지 않습니다. 작업에 실패했다는 것은 작업을 시작할 수 없으며 연결한 콜백 함수가 호출되지 않는다는 것을 의미합니다. 일단 콜백 함수가 실행되고 검색 및 로드 작업이 완료되면, 성공적으로 로드되었다는 가정하에 이 섹션에 설명된 다른 함수를 사용하여 캐시에서 데이터를 얻으려고 시도할 수 있습니다. 이때 데이터가 캐시에 즉시 저장되지 않으면 찾지 못한 것입니다.
한 번 데이터 항목을 성공적으로 얻었는데 이후 동일한 항목을 얻지 못했다면 캐시에서 해당 항목이 제거되었을 수도 있습니다. 데이터 레지스트리 항목 획득(Acquire Data Registry Item) 을 다시 호출하고 콜백 함수를 입력한 직후에 해당 항목을 얻습니다. 프로젝트의 특정 요구 사항에 따라 자체적인 데이터 사본을 만들거나 데이터 항목의 캐시 행동을 조정하는 것도 좋습니다.

- 데이터 레지스트리 항목 찾기(Find Data Registry Item) 는 데이터 레지스트리 캐시의 항목을 확인하고, 항목을 찾았는지 여부에 따라 분기됩니다. 항목을 찾았다면 오른쪽의 Out 항목 핀을 통해 해당 항목에 액세스할 수 있습니다. 이 함수는 즉시 반환하므로 어딘가 있지만 캐시에는 없는 데이터 항목을 찾지 못합니다.

- 데이터 레지스트리 항목 가져오기(Get Data Registry Item) 는 데이터 레지스트리 항목 찾기(Find Data Registry Item) 와 비슷하지만 분기되는 대신 성공/실패 값을 반환하고, 성공 시 왼쪽의 Out 항목 핀에 연결된 변수를 자동으로 채웁니다. 이 함수는 즉시 반환하므로 어딘가 있지만 캐시에는 없는 데이터 항목을 찾지 못합니다.

- 데이터 레지스트리 커브 평가(Evaluate Data Registry Curve) 는 캐시된 커브를 찾습니다. 데이터 레지스트리 항목 찾기(Find Data Registry Item) 처럼 이 함수도 동기식이므로 즉시 반환하지만, 함수를 호출할 때 커브가 캐시에 없으면 커브를 찾지 못합니다. 이 함수는 성공/실패 여부에 따라 실행을 분기하며, 실패 시 입력된 디폴트값을 반환합니다. 이 기능은 커브 데이터의 사용 가능 여부와 상관없이 출력 값이 필요한 경우에 사용할 수 있습니다.

함수 | 설명 |
---|---|
UDataRegistrySubsystem::Get |
UDataRegistrySubsystem 인스턴스의 포인터를 반환합니다. 이 목록에서 유일한 스태틱 함수이며, 서브시스템의 엔트리 포인트로 작동합니다. |
UDataRegistrySubsystem::GetRegistryForType |
독립적으로 또는 FDataRegistryId::RegistryType 에서 이름이나 FDataRegistryType 을 가져오고, UDataRegistry 포인터가 있다면 일치하는 데이터 레지스트리에 반환합니다. |
UDataRegistrySubsystem::RegisterSpecificAsset |
FDataRegistryType 으로 데이터 레지스트리를 검색하고 여기에 특정 에셋을 추가합니다. 유효한 FDataRegistryType 을 제공하지 않으면 서브시스템이 그 안에 있는 모든 데이터 레지스트리에 에셋을 추가하려고 시도합니다. 하나 이상의 데이터 레지스트리가 에셋을 허용하면 true 를 반환합니다. |
UDataRegistry::GetCachedItem |
제공된 FDataRegistryId 에 상응하는 데이터 항목을 찾기 위해 데이터 레지스트리를 검색합니다. 함수가 호출될 때 캐시에 해당 항목이 없으면 함수는 null을 반환합니다. 항목이 있으면 함수는 데이터 레지스트리가 저장한 구조체 타입의 const 포인터를 반환합니다. |
UDataRegistry::GetAllCachedItems |
데이터 레지스트리에 캐시된 항목마다 엔진 내 UScriptStruct 데이터(const uint8* )의 포인터로 맵을 채웁니다. 이때 항목의 FDataRegistryId 를 키로 사용합니다. 또한 별도의 출력 파라미터를 통해 UScriptStruct 자체를 제공합니다. 이렇게 하면 UScriptStruct::ExportText 함수를 사용하여 캐시된 각 항목의 콘텐츠를 로깅하는 것처럼, 디버깅 툴로 캐시를 반복작업하는 데 유용한 경우가 많습니다. |
UDataRegistry::EvaluateCachedCurve |
제공된 FDataRegistryId 에 상응하는 커브를 찾아 주어진 입력 값으로 평가합니다. 호출될 때 캐시에 요청된 커브가 없으면 이 함수는 실패합니다. 이 함수의 반환 값은 FDataRegistryCacheGetResult 타입으로서 요청한 커브의 캐시된 결과에 대한 정보를 제공할 뿐 아니라 무엇보다 커브가 발견되었는지 여부를 알려줍니다. float 타입의 커브 출력 값은 출력 파라미터를 통해 제공됩니다. |
UDataRegistry::AcquireItem |
GetCachedItem 과 비슷하지만 호출될 때 캐시되지 않은 데이터 항목도 검색합니다. 이 함수는 비동기식입니다. 검색이 완료되면 FDataRegistryItemAcquiredCallback 타입의 콜백 함수가 실행됩니다. 함수의 반환 값은 bool 로서 콜백 예약에 성공했음을 나타냅니다. false 반환 값은 오류가 발생하여 콜백 함수가 실행되지 않음을 의미합니다. true 반환 값은 콜백 함수가 실행되지만 데이터 항목이 없을 수도 있음을 의미합니다. |
데이터 레지스트리에서 얻은 구조체 포인터를 캐시하는 것은 안전하지 않을 수 있습니다. 언제나 사용 가능한 데이터 항목도 있지만, 동적으로 로드되고 데이터 레지스트리에 의해 경고 없이 언로드되는 데이터 항목도 있습니다. 언로드될 수 있는 데이터를 처리하고 있을 가능성이 있는 경우, 데이터를 얻는 즉시 사용하거나, 데이터 레지스트리의 포인터를 보관하는 대신 자체적인 사본을 캐시하는 것이 좋습니다.
게임 피처와 통합
데이터 레지스트리 플러그인은 게임 피처 플러그인으로부터 데이터 레지스트리와 개별 데이터 레지스트리 소스를 모두 추가할 수 있습니다. 이 프로세스의 구체적인 작동 방식은 게임 피처 및 모듈형 게임플레이를 참고하세요.