- Unreal Engine에는 Engine과 Engine Code, Data 사이의 호환성을 정의하거나 보증하는
다양한 Version Control System을 제공한다.- 이를 이용하면 호환 불가능한 Code나 Data 감지가 가능한다.
- 여기에 더불어, Custom Serialization 및 Convert Data를 관리할 수 있다.
Engine Version
- Unreal Engine에서 가장 수준 높고 사용자 가시성이 뛰어난 Version Control
- Editor 내 Help 메뉴 -> About Unreal Editor 섹션에서 확인 가능
- 엔진 버전은 다음과 같이 구성되어 있으며, FEngineVersion/FEngineVersionBase 클래스에서 확인할 수 있다.
-
더보기
[MajorVersion].[MinorVersion].[PatchVersion].[ChangeListNumber][BranchName]
5.0.3.20979098+++UE5+Release-5.0
- Engine Version을 구성하는 각 Component는 상위 값이 증가하지 않는 한 값이 감소하지 않는다.
- 달리 말하면, 두 Engine Version의 Component별로 비교하면 어느 Version이 최신인지 파악할 수 있다.
- Major, Minor, Patch Version이 같은 경우,
Epic의 Changelist보다 이용자가 생성한 Changelist를 항상 최근 버전으로 간주한다. - BranchName은 호환성 검사에 사용하지 않는다.
- 주로 외부에 표시하는 용도
-
- Engine Version이 호환되지 않으면 Engine에서 Asset을 Load 할 수 없다.
- 최신 Engine Version에서 저장된 Asset은 Contents Browser에 나타나지 않는다.
- 해당 Asset에 Reference는 null로 취급된다.
- 이 때 Asset을 저장하면 인지하지 못한 Reference가 오염되기 때문에 저장하지 않는 것이 좋다.
- Changelist 0이 포함된 Engine Version은 다른 모든 Engine Version과 호환되는 것으로 간주한다.
- Engineer 입장에서는 Engine 개발이 간편해지는 측면이 있지만, Disk에 저장하는 관점에서는 부적합하다.
- 대신 Contents Creator는 배포된 Editor의 Binary Build를 사용해야 한다.
- 그래야 정확한 Engine Version Data를 지닌 Asset으로 작업을 하게 된다.
- 또한 Asset으로 인한 Data 손실을 방지할 수 있다.
Asset and Package
- Asset은 저장에 사용한 Editor의 Engine Version 정보가 포함되어 있다.
- Engine은 Load 시 이 값을 확인하고,
Code 변경을 통해 Serialize 된 Data에 추가되거나 제거된 Property를 적절히 처리할 수 있다. - Serialize를 해제하는 중(ex. Asset을 Load 하는 경우)
- Field를 제거하는 경우에는 해당 Field가 인식되지 않고 무시된다.
- Field를 추가하는 경우에는 Data에서는 없어지지만, 기본값을 유지한다.
- Asset의 Data를 Disk에 저장하기 위해 Serialize 하는 경우
- 삭제된 Field의 Data는 바로 폐기 된다.
- 새로 추가된 Field의 Data는 유지되어 다른 Property와 함꼐 Serialize된다.
- 이 결과 Data 구조는 서서히 변경되며,
해당 Data 구조의 Serialized Expression은 새 Field를 추가하는 동안 필요 없는 Field는 자연스럽게 폐기가 된다. - 따라서 Serialize 된 Data는 Engine Version과 무관하게 동일하거나 그 이상의 Version에서만 인식할 수 있다.
- 이 규칙을 통해 이전 Engine Version의 Data 손실 Error를 방지할 수 있다.
- 최근 Version의 Property를 폐기하고 Data를 다시 Disk상에 Serialize 하면서 발생함.
Programming by Engine Version
- FEngineVersion 클래스를 통해 Project의 Engine Version에 Access할 수 있다.
- Engine Version을 표시하거나, 호환성 검사 할 때 아래 함수들을 이용하는 것이 좋다.
- Unreal Game Sync를 통해 동기화되지 않은 Code-based Engine Build가 있는 경우,
이 Build의 ChangeList를 0으로 표시하면 Version Check와 관련해 훨씬 유연한 환경을 만들 수 있다. - 하지만 Cooking 과정에서는 해당 Asset에서 Warning이 발생하므로 사용을 지양하는 것이 좋다.
- 만약 이 Warning을 비활성화 하려면,
DefaultEngine.in 파일의 [Core.System] Section에 ZeroEngineVersionWarning=0을 추가하면 된다.
- 만약 이 Warning을 비활성화 하려면,
Engine Version Update
- Build의 Engine Version은 Engine 내 /Build/Build.version 파일에서 정의한 값으로 제어할 수 있다.
- 이 파일을 직접 수정한 뒤, 다음 2가지 방법으로 Version을 Update 할 수 있다.
- UpdateLocalVersion Commandlet 실행
- UGC(Unreal Game Sync)로 Sychronize
-
더보기
{ "MajorVersion": 4, "MinorVersion": 26, "PatchVersion": 2, "Changelist": 0, "CompatibleChangelist": 14830424, "IsLicenseeVersion": 0, "IsPromotedBuild": 0, "BranchName": "++UE4+Release-4.26" }
- Changelist
- 수동으로 정의
- 수동으로 업데이트 하거나, UpdateLocalVersion Commandlet으로 Update
- Update 시 디포 Directory Name을 사용하고 /를 +로 교체
- CompatibleChangelist
- 해당 Engine Version과 호환 가능한 것으로 간주할 수 있는 가장 낮은 Changelist
- 가장 처음 만들어진 Changelist
- Engine의 Local Build에서처럼 0으로 설정할 때도 있다.
- 하지만 정식 출시된 Epic의 Build나 내부적으로 배포된 Build가 0이 아니므로
Local Version과 호환되지는 않는다.
- 하지만 정식 출시된 Epic의 Build나 내부적으로 배포된 Build가 0이 아니므로
- 해당 Engine Version과 호환 가능한 것으로 간주할 수 있는 가장 낮은 Changelist
- IsLicenseeVersion
- Source Control에서 Synchronize 된 Local Build에 사용할 경우 0으로 지정
- UpdateLocalVersion Commandlet을 통해 System Build를 할 경우 1
- Promoted Build에서 사용할 때에는 1이 더 적절하다.
- Version Check가 더 까다로워지는 대신 Hot Reload가 비활성화 된다.
- IsPromotedBuild
- 해당 Build가 Promoted Build인지 여부
- 기본 값은 1
- BuildId
- 위 예시에는 없지만 제공되는 정보
- Compile 할 때 Engine 및 Module에 전부 이 값을 Tag 한다.
- Engine에서는 이 값이 없는 모든 Module은 호환 불가능한 대상으로 간주
- 보통은 공백으로 두는 편이 좋다.
- 공백으로 둘 경우 Compile 할 때마다 고유한 새 값이 생성된다.
- Changelist
UpdateLocalVersion Commandlet
- 전용 Build Machine에서 Compile할 때처럼 Build/Build/version 파일을 수동으로 편집 할 필요가 없는 경우에 유용
-
더보기
RunUAT.bat UpdateLocalVersion [-CL=INT] [-CompatibleCL=INT] [-Build=STRING] [-SkipHeader] [-Licensee] [-Promoted=BOOL] [-Branch=STRING]
- CL
- Build.Version의 Changelist
- CompatibleCL
- Build.Version의 CompatibleChangelist
- Build
- Source Code의 BUILD_VERSION 매크로를 Update해 Engine의 Build Version String을 변경
- SkipHeader
- 이 Parameter가 있으면 Engine의 Header File이 Update 되지 않는다.
- License
- Build.version의 IsLicense
- 이 Parameter가 있는 경우 true로 취급
- Promoted
- Build.version의 IsPromotedBuild
- 0 이외의 정수를 입력하면 true로 간주하고 Field에 1이 입력
- Branch
- Build.Version의 BranchName
Object Version
- UObject 파생 Class는 Engine Version 외에 Object Version Control System을 별개로 운영한다.
- Engine Level Version
- Object Level Version
- Object Serialization은 다음의 용도로 사용된다.
- 대량의 Burk Data를 포함한 Asset Performance Optimize
- 단위 변환 시 Data Format 변경을 구현
- Object Data를 압축된 Format의 Disk에 저장할 때 공간 절약을 위한 Customize
- Custom Serialization을 위해서는 다음 2가지 작업이 필요하다.
- UObject::Serialize 함수를 Override하여 Project의 필요에 따라 Data Format 변경
- 신규 Code의 Object Version에 기반한 검사
- Serialization이 변경 되어도 하위 호환성을 보존하면서, Engine Version과 같은 방식으로 Data 손실을 방지할 수 있다.
Serialization and Version Control of Engine Level
- Engine Level에서는 EUnrealEngineObjectUE5Version을 사용해 Serializer Function의 Version을 관리한다.
- Custom Serializer가 변경될 때마다 새 항목이 EUnrealEngineObjectUE5Version에 추가된다.
- Epic Games가 Public Unreal Engine Launch Version에서 이 Type을 수정하면,
병렬 Global EnumType인 EUnrealEngineObjectLicenseeUEVersion은 사용자가 자체적으로
Engine Level Version 관리를 추가할 수 있다. - 이후 Package를 저장하면 두 Enum값이 증가한 채로 저장이 된다.
- Serializer, Deserializer Code는 이 값으로 Data Read/Write 방식을 결정한다.
- Engine에서는 자동으로 이 Version의 값을 자동으로 자체검사한다.
- Engine보다 높은 Version이 있는 Package는 Load 할 수 없다.
- 이 방식은 Engine의 여러 분야를 별개의 팀이 작업하는 곳에서는 적합하지 않다.
- 다수의 Version에서 Enum Type을 업데이트 할 수 없다.
- Merge 시 상수를 다시 정렬하는 동안 해당 Version Number로 저장한 Asset이 손상되거나 무효화 된다.
- 이 경우에는 Engine Level이 아닌 Object Level의 Serialization이 더 적절하다.
Serialization and Version Control of Object Level
- Programmer들이 동시에 각자 다른 Branch로 개발하는 경우,
Engine이 FGuid 기반 Custom Version을 통해 Object Level Version Control을 제공해야 한다. - FGuid 구조에는 다른 Version과 같이 증가하는 정수형 Version Number 뿐 아니라,
팀의 요구에 따라 동시에 다양한 Custom Version을 보유할 수 있는 GUID(Global Unique Identifier)도 제공한다. - System이나 Branch별로 Custom Version을 유지하면 다른 Branch의 Code와 병합할 때 Conflict가 발생하지 않는다.
-
더보기
const FGuid FAnimationCustomVersion::GUID(0x2EB5FDBD, 0x01AC4D10, 0x8136F38F, 0x3393A5DA); // 코어로 커스텀 버전 등록 FCustomVersionRegistration GRegisterAnimationCustomVersion(FAnimationCustomVersion::GUID, FAnimationCustomVersion::LatestVersion, TEXT("AnimGraphVer"));
- Object Level에서는 FArhcive::UsingCustomVersion 함수를 통해 FGuid를 Serialize 할 수 있다.
- Custom Code에서는 등록된 FGuid에 있는 Version Number를 고려해 Data의 Read/Write 방식을 결정한다.
- 이런 식으로 등록된 FGuid와 연결된 Version Number는 절대 감소하지 않는다.
- 이를 통해 Engine은 신규 Version의 Asset을 Load하지 않도록 할 수 있다.
Custom Serialization Function
- Object는 Serialize를 override 하여 Disk에 있는 정밀 Data 표현을 제어할 수 있다.
- FArchive를 이용해 Read/Write를 수행하므로 Data Format을 한번만 배치하면 된다.
- 아래는 FArchive에서 Serialization Code에서의 Version based logic을 작성할 때 유용한 함수들이다.
- LicenceUEVer에 대한 UEVer 호출을 변경할 경우,
Epic의 공식 Version Number가 아니라 사용자의 Version Number를 사용하도록 코드가 변경된다.- 자체 Version의 Unreal Engine을 따로 관리하는 Epic 외 사용자에게 사용을 권장한다.
- https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Core/Serialization/FArchiveState?application_version=5.2
예시
- PhysXVehicles Plugin의 WheeledVehicle은 Engine Object Version 및 Custom Version을 모두 사용하고,
실제 코드를 변경하기 전에 만들어진 Asset과도 하위 호환성을 유지한다. -
더보기
void UWheeledVehicleMovementComponent::Serialize(FArchive& Ar) { Super::Serialize(Ar); Ar.UsingCustomVersion(FFrameworkObjectVersion::GUID); if (Ar.CustomVer(FFrameworkObjectVersion::GUID) < FFrameworkObjectVersion::WheelOffsetIsFromWheel) { bDeprecatedSpringOffsetMode = true; } }
- 여기서 Custom Version은 WheelSuspension을 표현하는 Physics Spring Object에 대한
Offset의 계산 방식 변경 변수를 설정할 때 사용된다. - 사용된 Version 값은 Physics Code를 관리하는 팀에서 제작한 Enum Type을 가져온다.
- 여기서 Custom Version은 WheelSuspension을 표현하는 Physics Spring Object에 대한
-
더보기
void FConstraintInstance::PostSerialize(const FArchive& Ar) { #if WITH_EDITORONLY_DATA // ... if (Ar.IsLoading() && Ar.UEVer() < VER_UE_FIXUP_MOTOR_UNITS) { AngularVelocityTarget = 1.f / (2.f PI); } // ... #endif }
- Angular Velocity가 RPS 대신 RPM으로 발생하는 물리적 변화에 대응해 단위 전화을 수행한다.
- Angular Velocity는 단위가 없는 부동소수점으로 저장되므로 낮은 Version에서는 Load 중 변환이 필요하다.
- 이 경우 Asset Load 할 때 Angular Velocity만 수정하면 된다.
- 이 Type으로 저장되는 모든 Asset은 이미 RPM으로 저장되며,
다음에 Load 할 때 Code를 변환할 필요가 없도록 현재 Engine Version Number로 저장한다.
Binary Version Control
- UBT 확인 할 때 자세한 내용 다룰 예정
- https://dev.epicgames.com/documentation/ko-kr/unreal-engine/how-to-version-binaries-in-unreal-engine
'UE5 > Architecture' 카테고리의 다른 글
[Architecture] Command-line Arguments (0) | 2024.05.07 |
---|---|
[Architecture] Config File (0) | 2024.05.06 |
[Architecture] Task System (0) | 2024.05.06 |
[Architecture] Programming Subsystem (0) | 2024.05.06 |
[Architecture] String (0) | 2024.05.06 |