ENGINEMIGRATOR · 개발 프리뷰 · 2026-10-23

장면과 코드를 함께
다른 엔진으로 옮기기

Unity ↔ Unreal 양방향 프로젝트 포팅 도구입니다. 모든 스크립트·리소스·의존성과 모든 엔진 버전을 다루는 것이 목표이며, 현재는 아래에 명시한 범위를 실제 엔진에서 검증했습니다.

장면·지원 리소스·제한된 게임 로직을 실제 프로젝트로 생성합니다. 전체 게임 자동 포팅은 미완료입니다.

원본과 선택한 대상은 보존합니다. 독립 복사본에서 코드 컴파일, 객체·에셋 연결, 저장 후 재열기를 수행합니다. 검사 통과, 코드 생성, 저장 검증, 실제 실행 대조는 각각 다른 결과입니다.

01 · 현재 가능한 작업

장면·리소스

PNG/JPEG/TGA, 기본 URP Lit/Unlit 및 Standard/Unlit, 단일 서브메시, 계층·좌표, 카메라·방향광·일부 후처리·환경을 대상 엔진의 실제 객체로 만듭니다. Read/Write가 꺼진 FBX 메시도 에디터에서 읽습니다.

상태·상속·이동

제한된 MonoBehaviour 클래스를 Runtime Actor로 컴파일하고 장면 객체에 연결합니다. 인스턴스 값, private SerializeField, GameObject 참조, Vector3와 월드·로컬 위치 이동을 지원합니다.

양방향 확인

EngineMigrator가 생성한 네이티브 헤더를 실제 코드 본문에서 C#으로 복원하고 Unity 장면에 붙입니다. 엔진 고유 설정의 일부는 왕복 보존용 메타데이터에 남습니다.

02 · 실행과 사용 방법

  1. 원본·대상 프로젝트 폴더와 Unity → Unreal 또는 Unreal → Unity를 선택합니다. 대상은 해당 엔진 버전으로 생성한 프로젝트를 사용하세요.
  2. 사전 검사를 실행합니다. 버전·경로·스크립트 목록과 차단 사유를 확인합니다. 파일 목록이 모두 변환됐다는 뜻은 아닙니다.
  3. 장면·리소스 포팅을 누르고 프로젝트 외부의 결과 폴더를 선택합니다. Unity.exe와 UnrealEditor-Cmd.exe는 프로젝트 버전과 일치해야 합니다.
  4. Source/Target 복사본에서 엔진이 실행됩니다. 지원하는 장면 스크립트가 있으면 Runtime 플러그인을 생성하고 UHT·네이티브 컴파일을 수행합니다. 원본을 자동 업그레이드하지 않습니다.
  5. 성공하면 Target 프로젝트를 엔진에서 여세요. Unreal은 생성 맵을 시작 맵으로 설정하고, Unity는 생성 장면을 빌드 장면으로 설정합니다.
  6. 변환 대응표에서 원본 ID → 대상 에셋·객체 → 참조 ID와 실제 검증 JSON을 확인합니다. 오류가 나면 해당 작업 폴더의 Unity/Unreal 로그를 확인합니다.

‘MonoBehaviour / Actor 클래스 변환’ 메뉴는 클래스만 별도로 변환합니다. 장면 부착과 직렬화 값·참조 연결까지 수행하려면 ‘장면·리소스 포팅’을 사용하세요. 순수 정적 함수 코드 생성과 Blueprint Function Library 변환은 별도 메뉴입니다.

현재 Unity 입력은 활성 빌드 장면 하나가 필요합니다. Unreal 입력은 Config/DefaultEngine.ini에 /Game/ 시작 맵이 필요합니다. 다른 렌더 파이프라인, 동일 이름의 외부 플러그인, 매핑되지 않은 코드·컴포넌트는 오류로 남깁니다.

03 · 무엇이 어디로 대입되나요?

Unity 원본Unreal 결과역방향·주의점
GameObject와 계층Actor와 Attachment. 위치 (x,y,z)m → (z,x,y)×100cm저장한 객체 ID를 유지하고 부모·메시·머티리얼 참조를 다시 연결합니다.
MeshFilter / MeshRendererStaticMesh / StaticMeshComponent와 실제 머티리얼 슬롯삼각형·UV0·법선을 이전합니다. 렌더러 활성·그림자 생성 상태를 보존합니다. 다중 서브메시·스키닝·LOD는 미완료입니다.
텍스처 / 기본 머티리얼Texture2D와 Base Color 또는 Emissive 그래프. Metallic → Metallic, Smoothness → 1−RoughnessJPEG/TGA는 PNG 중간 데이터로 변환합니다. 샘플러·sRGB·밉 설정과 참조를 연결합니다. 복잡한 셰이더·추가 PBR 맵은 차단합니다.
Camera / AudioListenerCameraActor. 수직 FOV를 화면비에 맞는 수평 FOV로 변환하고 근거리 클립을 cm로 설정MainCamera를 자동 플레이어 카메라로 지정합니다. 원거리 클립·URP 고유 옵션·오디오 시스템의 동등성은 미검증이며 일부 값은 왕복용으로 보존합니다.
Directional LightDirectionalLight의 색·광도 수치·색온도·그림자 설정Unity 광도와 Unreal lux가 같은 외형이라는 보장은 없습니다. 포인트/스폿 광원·쿠키는 미완료입니다.
Global Volume / ProfilePostProcessVolume과 Bloom·Vignette·MotionBlur 대응 값Unity 복원 시 공유 프로파일 참조를 재연결합니다. Neutral/ACES 톤매핑과 세부 렌더링 값은 동일 효과를 보장하지 않으며 원본 값을 보존합니다.
하늘·환경광SkyAtmosphere / SkyLight와 환경 설정 메타데이터Unity 절차적 하늘을 그대로 렌더링하는 구현은 아닙니다. 원래 셰이더·색상·설정으로 되돌릴 수 있게 보존합니다.
MonoBehaviour 컴포넌트원래 객체에 부착된 개별 Runtime Actor 인스턴스여러 인스턴스의 저장 값을 각각 적용합니다. 엔진 객체의 표현 방식은 다르며 지원 API만 변환합니다.
GameObject 필드실제 대상 Actor를 가리키는 추적 참조다른 객체·자기 자신·null을 연결합니다. 기본 Prefab Asset 참조도 복원합니다. 일반 Component·기타 외부 에셋·서비스 참조는 미완료입니다.
Box / Sphere / Capsule Collider · Rigidbody실제 ShapeComponent · Chaos 강체 · PhysicalMaterial크기·중심·트리거·활성·질량·중력·감쇠·축 잠금과 공유 물리 머티리얼을 연결합니다. 평균 마찰/반발 결합을 지원합니다. 복합 콜라이더·관절·충돌 콜백은 미완료입니다. 접촉 순간의 궤적은 엔진별 차이가 있습니다.
Legacy Animation의 위치·크기 곡선LevelSequence의 실제 Transform 채널 · 재생 Actor시간·키·접선·반복·대상 참조를 읽어 Unity AnimationClip으로 복원합니다. Animator·스켈레탈·회전·이벤트는 미완료입니다.
Overlay Canvas · RectTransform · Image / RawImage / Text / ButtonWidget Blueprint · CanvasPanel · Image / TextBlock / Button앵커·피벗·오프셋·색·텍스트를 실제 WidgetTree로 구성합니다. ConstantPixelSize 1만 지원합니다. 폰트는 대체되며 동일한 화면 렌더링은 미검증입니다. 기본 PNG 텍스처와 RawImage UV를 연결합니다. Simple Sprite의 rect는 UMG Brush UV로 적용하고, Sprite pivot·PPU는 왕복 복원용 메타데이터로 보존합니다. 실제 UI 배치는 RectTransform의 피벗·앵커·크기를 CanvasPanelSlot에 적용합니다. 공유 Sprite는 Unity 복원 시 같은 자산으로 연결합니다. 패킹·트리밍·슬라이스·별도 overrideSprite 상태·preserveAspect·TMP·자동 레이아웃은 미지원입니다.
Button.onClick의 인수 없는 public void 콜백런타임 UMG 리스너 → 실제 Actor Custom Event대상 컴포넌트·메서드·순서·비활성 리스너를 연결하고 Unity persistent listener로 복원합니다. 고정 인수·임의 델리게이트·마우스 입력 시스템의 통합은 미완료입니다.

프로젝트 단위 · 사전 진단과 참조 연결

여러 장면 또는 프리팹이 있으면 프로젝트 단위 처리를 자동으로 선택합니다. 활성·비활성 장면, 같은 이름의 장면을 별도 ID로 구분하고 빌드 순서와 활성 상태를 보존합니다. 작업 복사본에서 모든 단위를 검사한 뒤 대상 엔진 자산을 생성합니다.

원본실제 대입·복원 방식
장면 / Scene GUID각각 별도 Unreal 맵으로 저장하고 다시 엽니다. Unity 복원 시 장면과 Build Settings 활성 상태를 복원합니다.
공유 메시·재질·텍스처프로젝트 내 동일 ID는 같은 실제 자산을 재사용합니다. 같은 ID에 서로 다른 데이터/PNG 바이트가 있으면 생성 전에 차단합니다.
프리팹 정의·인스턴스Unreal에는 정의 맵을 만들고 배치 객체는 펼쳐서 변환합니다. Unity로 돌아올 때 실제 Prefab Asset과 인스턴스를 연결하며, 지원 속성 오버라이드·내부/인스턴스 간 GameObject 참조를 재연결합니다.
진단중복 GUID·끊어진 로컬 fileID는 파일·줄·조치를 표시합니다. 패키지 GUID는 정적 검사에서 미확인으로 표시하고 Unity AssetDatabase로 확인합니다. 누락 GUID·미지원 컴포넌트·스크립트는 대상 엔진 생성 전에 차단합니다.
메시 방향·노멀OBJ의 handedness를 고려해 가져오며 정점·UV·노멀·삼각형 방향을 직접 대조합니다. 역변환은 압축된 렌더 노멀 대신 편집 가능한 원본 MeshDescription을 읽습니다.

Unreal에서 프리팹 정의를 수정했을 때 이미 펼친 배치에 자동 전파하는 기능은 미지원입니다. 중첩·Variant/Model 프리팹, 자식 추가·삭제·이름/순서 변경, 컴포넌트 삭제 오버라이드는 아직 처리하지 않습니다. 런타임 프리팹 생성은 활성 메시·스크립트 계층에 한정하며 물리·애니메이션·UI 등은 차단합니다. 임의 Unreal 프로젝트의 모든 맵 탐색과 추적된 변환 결과의 왕복은 구분합니다.

참조 오류는 결과 폴더의 Transfer/preflight.json, 단위별 package.json과 project-progress.json에서 확인합니다. 실패한 결과를 전체 완료로 표시하지 않습니다. 이전 버전으로 만든 메시 결과는 좌표 처리 수정이 적용되도록 원본에서 다시 포팅해 주세요.

복원 연결에는 Unity 6.0 PrefabUtility를 사용합니다. API 문서 확인과 실제 프리팹 수정 전파 검증은 별도로 수행합니다.

04 · 지원하는 코드와 차단하는 코드

MonoBehaviour ↔ Actor

float/double/bool/int/GameObject/Vector3 필드, public 및 private/protected SerializeField, 단일 상속, virtual/override와 명시적인 부모 호출을 지원합니다. 숫자·논리식, if/else, while, break/continue, 지역 변수와 포팅 클래스 계층의 함수 호출을 처리합니다.

int 덧셈·뺄셈·곱셈·증감은 C#의 기본 unchecked 오버플로를 유지하도록 생성합니다. 정수 나눗셈·나머지·비트 연산과 임의 형변환은 미지원입니다. Vector3 생성·기본 축·덧셈/뺄셈/스칼라 곱셈·좌표 성분 및 자신의 transform.position/localPosition 대입을 지원합니다.

Unity 메시지실행 대응
Awake초기 작성 객체는 명시적 순서의 시작 배치, 동적 객체는 PostInitializeComponents, 비활성 객체는 최초 활성화 때 한 번
Start활성화 후 한 번. 초기 활성 컴포넌트는 시작 배치, 비활성·동적 컴포넌트는 활성화·생성 시점에 따라 첫 Tick 전 또는 현재 Tick 뒤
Update / Time.deltaTimeTick / DeltaSeconds. 최소 프레임 제한을 해제하고 원본 최대 시간 제한을 적용
OnDestroyDestroyed 또는 EndPlay. 공통 종료 가드로 중복 호출 방지

루트 클래스에 생명주기 래퍼를 한 번만 생성합니다. 부모 호출은 원본 코드가 명시한 경우에만 실행합니다. 역변환은 EngineMigrator가 생성한 닫힌 헤더 문법을 검사하며, 지원 밖의 추가 코드가 있으면 건너뛰지 않고 차단합니다.

런타임 Transform 애니메이션 프리팹

Legacy Animation의 지원 Transform 클립을 포함한 프리팹을 생성할 때 재생 Actor도 함께 복제합니다. 각 LevelSequence 바인딩은 원래 프로토타입이 아닌 새 객체 계층으로 연결하고, 인스턴스별 시계로 평가합니다. 프로토타입은 재생하지 않습니다. 실제 테스트는 Loop·Once·ClampForever, 비활성 프리팹의 첫 활성화, 재활성화, 비활성 Animation과 재생 중 객체 복제를 포함합니다.

Unity 기준 실행에서는 생성 프레임의 애니메이션 평가가 0초 자세부터 시작했습니다. 재생 중 객체를 복제하거나 비활성 객체를 다시 활성화해도 내부 재생 시간은 처음부터 시작하지만, 호출 반환 시점의 Transform과 공개 스크립트 필드는 복사됩니다. Update에서 읽은 자세와 이후 프레임 관찰 자세를 모두 대조합니다. Once 종료 뒤 마지막 자세 유지도 확인했습니다. Unity의 Once/Clamp 열거형 별칭은 내보낼 때 Once로 정규화합니다.

객체 전체 삭제 시 소유 재생 Actor를 함께 제거합니다. 장면 전환에서는 월드 정리 콜백으로 재생 시계의 델리게이트를 해제합니다. 재생 중 객체를 남긴 채 다음 장면으로 이동하는 실제 실행도 검사합니다. 정의·프로토타입의 실제 채널과 바인딩을 저장·재열기 후 검증하며, 한쪽만 편집한 경우에는 동기화를 위해 재가져오기가 필요합니다.

검증 대상은 지원되는 Legacy Transform 자동 재생입니다. Animator 상태 기계·스켈레탈 애니메이션·AnimationEvent·블렌딩·임의 재생 제어 API·일반 애니메이션 컴포넌트 조회는 별도 미지원 범위가 남아 있습니다. 물리와 같은 Transform을 동시에 제어하는 조합은 기존 차단을 유지합니다. 런타임 UI 프리팹은 아직 구현 중입니다.

패키지 실행에서는 에디터와 달리 숨겨진 프로토타입까지 재생되는 차이를 발견했습니다. 프로토타입 클래스에서는 자동 재생 이벤트 그래프를 제거하고 평가 대상도 보조 Actor로 격리합니다. 복제본은 생성 후 실제 새 계층으로 다시 연결해 자체 시계로 평가합니다. 에디터 검사만으로 통과 처리하지 않고 패키지의 프로토타입 자세도 매 시점 대조합니다.

물리 프리팹의 런타임 생성과 활성 상태

기존 내보내기에서 지원하는 기본 충돌체·Rigidbody 구성의 런타임 프리팹 생성 경로를 추가했습니다. 실제 테스트는 동적 Box·Sphere, Kinematic Capsule, 비활성 Box 프리팹과 재활성화·삭제를 포함합니다. 충돌체 종류·크기·질량·중력·시뮬레이션 상태·속도와 프리팹/내부 객체 참조를 실행 및 재내보내기로 대조합니다.

Unreal의 장면별 프로토타입은 실제 물리 컴포넌트를 저장하지만 시뮬레이션은 정지합니다. 복제본은 자신의 활성 상태에 맞게 시뮬레이션을 시작하고, 비활성화할 때 속도를 보관해 재활성화 때 복원합니다. 프로토타입과 정의의 물리 속성을 각각 스냅샷으로 검사하므로 한쪽만 변경한 상태로 역변환하면 재가져오기를 요구합니다.

첫 실행에서는 Unreal이 Instantiate한 프레임부터 중력을 적용해 Unity보다 한 물리 단계 앞섰습니다. 변환 스크립트의 Update를 물리 처리 이후 단계로 옮겨 생성 프레임의 위상을 맞췄습니다. 서로 충돌하지 않는 무감쇠 자유낙하 테스트에는 위치 0.0001m, 속도 0.0001m/s 기준을 적용했습니다. 기존 지면 접촉·250프레임 검사의 별도 물리 해석 오차 기준은 유지하며, 두 엔진의 모든 물리 상황이 동일하다는 뜻은 아닙니다.

비활성 루트의 Rigidbody를 복합 충돌체로 잘못 판정한 내보내기 검사도 수정했습니다. 복합 충돌체·비지원 축/모드·임의 물리 API와 충돌 콜백, 물리와 애니메이션/UI를 함께 복제하는 모든 조합은 여전히 미지원 또는 미검증입니다. 런타임 Transform 애니메이션 프리팹은 위 절의 범위에서 지원합니다. UI 프리팹 실행 연결은 별도 구현 항목입니다.

프리팹 정의 간 연쇄·순환 참조

사용자 스크립트의 GameObject 필드가 다른 기본 프리팹 자산의 루트를 가리키는 경우를 지원합니다. 장면에서 A만 참조하더라도 A→B→C→A처럼 연결된 정의를 수집하며, 방문한 자산은 한 번만 구성합니다. 대상이 없는 참조는 가져오기 전에 차단합니다. 중첩 프리팹이나 Variant와는 별개의 자산 필드 참조입니다.

Unreal에서는 같은 장면 안의 비실행 프로토타입을 서로 연결합니다. 생성된 객체에서 다음 프리팹을 조회·생성하고, 순환 경로를 돌아 같은 유형을 다시 생성해도 내부 루트·컴포넌트 참조는 새 복제본으로 연결합니다. Unity가 자기 자신을 가리키는 필드를 저장할 때 내부 루트 참조로 직렬화하는 경우에는 그 내부 참조 의미를 보존합니다. 실제 자산 참조와 내부 참조는 내보낸 종류에 따라 구분합니다.

Unity 복원은 먼저 프리팹 자산의 경로와 식별자를 등록한 뒤 내용을 채우므로, 매니페스트 순서와 무관하게 앞방향·순환 참조를 복원합니다. 복원 후 실제 실행과 재내보내기로 참조·상태를 대조합니다. 비교식 안의 상태 변경 없는 사용자 컴포넌트 GetComponent 조회를 지원하며 AddComponent 같은 상태 변경 호출의 평가 순서 제한은 유지합니다. 런타임 물리 프리팹은 위 절의 범위를 참고하십시오. Transform 애니메이션은 위 절의 범위에서 지원합니다. UI 구성, 중첩·Variant 및 임의 API는 별도 미지원 범위입니다.

비활성 프리팹과 OnDisable 내부 복제

메시·사용자 스크립트로 구성된 비활성 루트·자식 프리팹의 런타임 생성을 지원합니다. 물리 구성은 위 절의 검증 범위에서 추가 지원합니다. 지원 Transform 애니메이션은 위 절의 범위를 참고하십시오. UI·카메라·라이트·Volume을 포함한 런타임 프리팹은 사전 검사를 유지합니다.

실제 Unity 기준으로 비활성 프리팹 생성 직후에는 Awake·OnEnable·Start가 실행되지 않습니다. 루트를 활성화하면 해당 루트의 Awake·OnEnable이 실행되고, 비활성 자식은 자신의 활성화까지 대기합니다. 이미 실행한 객체를 비활성 상태에서 복제하면 공개 필드 값은 복사하지만, 엔진 내부 초기화 상태는 새로 시작합니다. 따라서 공개 Awake·Start 카운터도 이후 콜백에서 다시 증가합니다.

GameObject 삭제 요청의 OnDisable 안에서 복제한 객체와, 계층 비활성화의 OnDisable 안에서 복제한 객체를 실제 실행으로 대조했습니다. 삭제 대기·계층 처리의 임시 태그를 복제본으로 전파하지 않고, 공개 필드와 내부 GameObject·컴포넌트 참조를 복제본으로 연결합니다. 검사한 재활성화·재삭제 흐름의 동등성이며 임의 깊이의 재귀 복제·모든 다른 콜백 조합은 미검증입니다.

GameObject 전체 삭제와 초기 프리팹 복제

Destroy(GameObject)는 컴포넌트 단독 삭제와 구분합니다. 검사한 활성 객체는 삭제 요청 안에서 컴포넌트 enabled가 false가 되고 OnDisable을 호출하지만, 호출 반환 직후 GameObject의 activeSelf·activeInHierarchy와 참조는 아직 유지됩니다. 최종 제거 단계에서는 삭제 루트의 자체 활성 값을 내리고 자식의 자체 값은 보존하며, 계층 활성 상태를 갱신한 뒤 OnDestroy를 한 번 호출합니다.

활성 객체의 disabled 컴포넌트는 Awake 이후 OnDestroy만 받는 경우를 검증했습니다. 한 번도 활성화되지 않은 객체는 Awake·OnEnable·Start·OnDisable·OnDestroy가 실행되지 않았습니다. Awake 내부 전체 삭제는 OnEnable·Start·Update를 실행하지 않는 흐름을 대조했습니다.

Update에서 생성한 컴포넌트의 늦은 Start 안에서 전체 삭제를 요청하고 OnDisable에서 다시 enabled·GameObject를 활성화하는 경우도 대조했습니다. 검사한 Unity 흐름은 첫 관찰 시점에 재활성화된 참조를 유지하고, 다음 Update 전 제거 과정에서 다시 OnDisable·OnDestroy를 호출합니다. 일반 삭제의 현재 Tick 이후 처리와 이 늦은 Start 경로를 분리했습니다. 이는 검사한 프레임 관찰 지점의 동등성이며 모든 렌더 단계·콜백 조합의 동등성을 뜻하지 않습니다.

활성 스크립트 프리팹을 초기 Awake·Start에서 Instantiate하고 내부 컴포넌트 참조, 호출 반환 때의 Awake·OnEnable 및 Start 보류, 첫 Update와 이후 전체 삭제를 검증했습니다. 삭제 대기·시작 배치·재진입의 임시 태그는 복제본에서 정리합니다. 비활성 프리팹·OnDisable 내부 복제의 검증 범위는 위 절을 참고하십시오. 그 외 모든 콜백 조합과 자산 자체 삭제·재부모화·부활 동작은 아직 미검증입니다.

초기 실행 순서와 활성 콜백 재진입

작성된 사용자 C++ 스크립트의 초기 Awake·OnEnable과 Start를 MonoImporter의 명시적 Script Execution Order 순서로 처리합니다. 초기 Awake·OnEnable을 모두 처리한 뒤 Start를 실행하며, 상속된 콜백과 명시적 부모 호출도 유지합니다. 비활성 객체는 이 배치에서 초기화하지 않고 실제 활성화까지 보류하며, 런타임 추가·복제 객체는 즉시 초기화하는 경로를 사용합니다. 동일 순위 사이의 순서는 보장하지 않습니다.

검증 프로젝트는 두 객체를 실행 순서와 반대로 배치하고 -100·100을 지정했습니다. 먼저 실행되는 객체는 다른 객체의 Awake·OnEnable·Start 횟수를 0으로, 나중 객체는 1로 읽는지와 전체 콜백 순서를 대조합니다. Update 제어 객체에는 -1000을 지정합니다.

OnEnable에서 자기 enabled를 false로 바꾸는 경우와 OnDisable에서 자기 enabled를 true로 되돌리는 경우를 검증했습니다. GameObject의 OnEnable 중 비활성화도 처리합니다. GameObject 비활성화 콜백 안에서 재활성화를 요청하면 Unity는 메시지를 기록하고 activeSelf=true·activeInHierarchy=false 상태로 남을 수 있습니다. 이때 불필요한 OnEnable을 호출하지 않고, 이후 SetActive(true) 요청에서 계층을 다시 활성화하도록 맞췄습니다.

임시 시작 배치·재진입 상태는 복제 객체에서 정리합니다. 이 조합 자체의 모든 복제·부모 변경·삭제 동등성을 검증했다는 뜻은 아닙니다. 동일 순위의 객체, 임의 동적 초기화 순서, 깊은 재진입과 다른 객체를 변경하는 모든 조합, 물리·UI·애니메이션의 모든 조합은 아직 확인 범위 밖입니다.

런타임 Transform 애니메이션 프리팹

Legacy Animation의 지원 Transform 클립을 포함한 프리팹을 생성할 때 재생 Actor도 함께 복제합니다. 각 LevelSequence 바인딩은 원래 프로토타입이 아닌 새 객체 계층으로 연결하고, 인스턴스별 시계로 평가합니다. 프로토타입은 재생하지 않습니다. 실제 테스트는 Loop·Once·ClampForever, 비활성 프리팹의 첫 활성화, 재활성화, 비활성 Animation과 재생 중 객체 복제를 포함합니다.

Unity 기준 실행에서는 생성 프레임의 애니메이션 평가가 0초 자세부터 시작했습니다. 재생 중 객체를 복제하거나 비활성 객체를 다시 활성화해도 내부 재생 시간은 처음부터 시작하지만, 호출 반환 시점의 Transform과 공개 스크립트 필드는 복사됩니다. Update에서 읽은 자세와 이후 프레임 관찰 자세를 모두 대조합니다. Once 종료 뒤 마지막 자세 유지도 확인했습니다. Unity의 Once/Clamp 열거형 별칭은 내보낼 때 Once로 정규화합니다.

객체 전체 삭제 시 소유 재생 Actor를 함께 제거합니다. 장면 전환에서는 월드 정리 콜백으로 재생 시계의 델리게이트를 해제합니다. 재생 중 객체를 남긴 채 다음 장면으로 이동하는 실제 실행도 검사합니다. 정의·프로토타입의 실제 채널과 바인딩을 저장·재열기 후 검증하며, 한쪽만 편집한 경우에는 동기화를 위해 재가져오기가 필요합니다.

검증 대상은 지원되는 Legacy Transform 자동 재생입니다. Animator 상태 기계·스켈레탈 애니메이션·AnimationEvent·블렌딩·임의 재생 제어 API·일반 애니메이션 컴포넌트 조회는 별도 미지원 범위가 남아 있습니다. 물리와 같은 Transform을 동시에 제어하는 조합은 기존 차단을 유지합니다. 런타임 UI 프리팹은 아직 구현 중입니다.

패키지 실행에서는 에디터와 달리 숨겨진 프로토타입까지 재생되는 차이를 발견했습니다. 프로토타입 클래스에서는 자동 재생 이벤트 그래프를 제거하고 평가 대상도 보조 Actor로 격리합니다. 복제본은 생성 후 실제 새 계층으로 다시 연결해 자체 시계로 평가합니다. 에디터 검사만으로 통과 처리하지 않고 패키지의 프로토타입 자세도 매 시점 대조합니다.

물리 프리팹의 런타임 생성과 활성 상태

기존 내보내기에서 지원하는 기본 충돌체·Rigidbody 구성의 런타임 프리팹 생성 경로를 추가했습니다. 실제 테스트는 동적 Box·Sphere, Kinematic Capsule, 비활성 Box 프리팹과 재활성화·삭제를 포함합니다. 충돌체 종류·크기·질량·중력·시뮬레이션 상태·속도와 프리팹/내부 객체 참조를 실행 및 재내보내기로 대조합니다.

Unreal의 장면별 프로토타입은 실제 물리 컴포넌트를 저장하지만 시뮬레이션은 정지합니다. 복제본은 자신의 활성 상태에 맞게 시뮬레이션을 시작하고, 비활성화할 때 속도를 보관해 재활성화 때 복원합니다. 프로토타입과 정의의 물리 속성을 각각 스냅샷으로 검사하므로 한쪽만 변경한 상태로 역변환하면 재가져오기를 요구합니다.

첫 실행에서는 Unreal이 Instantiate한 프레임부터 중력을 적용해 Unity보다 한 물리 단계 앞섰습니다. 변환 스크립트의 Update를 물리 처리 이후 단계로 옮겨 생성 프레임의 위상을 맞췄습니다. 서로 충돌하지 않는 무감쇠 자유낙하 테스트에는 위치 0.0001m, 속도 0.0001m/s 기준을 적용했습니다. 기존 지면 접촉·250프레임 검사의 별도 물리 해석 오차 기준은 유지하며, 두 엔진의 모든 물리 상황이 동일하다는 뜻은 아닙니다.

비활성 루트의 Rigidbody를 복합 충돌체로 잘못 판정한 내보내기 검사도 수정했습니다. 복합 충돌체·비지원 축/모드·임의 물리 API와 충돌 콜백, 물리와 애니메이션/UI를 함께 복제하는 모든 조합은 여전히 미지원 또는 미검증입니다. 런타임 Transform 애니메이션 프리팹은 위 절의 범위에서 지원합니다. UI 프리팹 실행 연결은 별도 구현 항목입니다.

프리팹 정의 간 연쇄·순환 참조

사용자 스크립트의 GameObject 필드가 다른 기본 프리팹 자산의 루트를 가리키는 경우를 지원합니다. 장면에서 A만 참조하더라도 A→B→C→A처럼 연결된 정의를 수집하며, 방문한 자산은 한 번만 구성합니다. 대상이 없는 참조는 가져오기 전에 차단합니다. 중첩 프리팹이나 Variant와는 별개의 자산 필드 참조입니다.

Unreal에서는 같은 장면 안의 비실행 프로토타입을 서로 연결합니다. 생성된 객체에서 다음 프리팹을 조회·생성하고, 순환 경로를 돌아 같은 유형을 다시 생성해도 내부 루트·컴포넌트 참조는 새 복제본으로 연결합니다. Unity가 자기 자신을 가리키는 필드를 저장할 때 내부 루트 참조로 직렬화하는 경우에는 그 내부 참조 의미를 보존합니다. 실제 자산 참조와 내부 참조는 내보낸 종류에 따라 구분합니다.

Unity 복원은 먼저 프리팹 자산의 경로와 식별자를 등록한 뒤 내용을 채우므로, 매니페스트 순서와 무관하게 앞방향·순환 참조를 복원합니다. 복원 후 실제 실행과 재내보내기로 참조·상태를 대조합니다. 비교식 안의 상태 변경 없는 사용자 컴포넌트 GetComponent 조회를 지원하며 AddComponent 같은 상태 변경 호출의 평가 순서 제한은 유지합니다. 런타임 물리 프리팹은 위 절의 범위를 참고하십시오. Transform 애니메이션은 위 절의 범위에서 지원합니다. UI 구성, 중첩·Variant 및 임의 API는 별도 미지원 범위입니다.

비활성 프리팹과 OnDisable 내부 복제

메시·사용자 스크립트로 구성된 비활성 루트·자식 프리팹의 런타임 생성을 지원합니다. 물리 구성은 위 절의 검증 범위에서 추가 지원합니다. 지원 Transform 애니메이션은 위 절의 범위를 참고하십시오. UI·카메라·라이트·Volume을 포함한 런타임 프리팹은 사전 검사를 유지합니다.

실제 Unity 기준으로 비활성 프리팹 생성 직후에는 Awake·OnEnable·Start가 실행되지 않습니다. 루트를 활성화하면 해당 루트의 Awake·OnEnable이 실행되고, 비활성 자식은 자신의 활성화까지 대기합니다. 이미 실행한 객체를 비활성 상태에서 복제하면 공개 필드 값은 복사하지만, 엔진 내부 초기화 상태는 새로 시작합니다. 따라서 공개 Awake·Start 카운터도 이후 콜백에서 다시 증가합니다.

GameObject 삭제 요청의 OnDisable 안에서 복제한 객체와, 계층 비활성화의 OnDisable 안에서 복제한 객체를 실제 실행으로 대조했습니다. 삭제 대기·계층 처리의 임시 태그를 복제본으로 전파하지 않고, 공개 필드와 내부 GameObject·컴포넌트 참조를 복제본으로 연결합니다. 검사한 재활성화·재삭제 흐름의 동등성이며 임의 깊이의 재귀 복제·모든 다른 콜백 조합은 미검증입니다.

GameObject 전체 삭제와 초기 프리팹 복제

Destroy(GameObject)는 컴포넌트 단독 삭제와 구분합니다. 검사한 활성 객체는 삭제 요청 안에서 컴포넌트 enabled가 false가 되고 OnDisable을 호출하지만, 호출 반환 직후 GameObject의 activeSelf·activeInHierarchy와 참조는 아직 유지됩니다. 최종 제거 단계에서는 삭제 루트의 자체 활성 값을 내리고 자식의 자체 값은 보존하며, 계층 활성 상태를 갱신한 뒤 OnDestroy를 한 번 호출합니다.

활성 객체의 disabled 컴포넌트는 Awake 이후 OnDestroy만 받는 경우를 검증했습니다. 한 번도 활성화되지 않은 객체는 Awake·OnEnable·Start·OnDisable·OnDestroy가 실행되지 않았습니다. Awake 내부 전체 삭제는 OnEnable·Start·Update를 실행하지 않는 흐름을 대조했습니다.

Update에서 생성한 컴포넌트의 늦은 Start 안에서 전체 삭제를 요청하고 OnDisable에서 다시 enabled·GameObject를 활성화하는 경우도 대조했습니다. 검사한 Unity 흐름은 첫 관찰 시점에 재활성화된 참조를 유지하고, 다음 Update 전 제거 과정에서 다시 OnDisable·OnDestroy를 호출합니다. 일반 삭제의 현재 Tick 이후 처리와 이 늦은 Start 경로를 분리했습니다. 이는 검사한 프레임 관찰 지점의 동등성이며 모든 렌더 단계·콜백 조합의 동등성을 뜻하지 않습니다.

활성 스크립트 프리팹을 초기 Awake·Start에서 Instantiate하고 내부 컴포넌트 참조, 호출 반환 때의 Awake·OnEnable 및 Start 보류, 첫 Update와 이후 전체 삭제를 검증했습니다. 삭제 대기·시작 배치·재진입의 임시 태그는 복제본에서 정리합니다. 비활성 프리팹·OnDisable 내부 복제의 검증 범위는 위 절을 참고하십시오. 그 외 모든 콜백 조합과 자산 자체 삭제·재부모화·부활 동작은 아직 미검증입니다.

초기 실행 순서와 활성 콜백 재진입

작성된 사용자 C++ 스크립트의 초기 Awake·OnEnable과 Start를 MonoImporter의 명시적 Script Execution Order 순서로 처리합니다. 초기 Awake·OnEnable을 모두 처리한 뒤 Start를 실행하며, 상속된 콜백과 명시적 부모 호출도 유지합니다. 비활성 객체는 이 배치에서 초기화하지 않고 실제 활성화까지 보류하며, 런타임 추가·복제 객체는 즉시 초기화하는 경로를 사용합니다. 동일 순위 사이의 순서는 보장하지 않습니다.

검증 프로젝트는 두 객체를 실행 순서와 반대로 배치하고 -100·100을 지정했습니다. 먼저 실행되는 객체는 다른 객체의 Awake·OnEnable·Start 횟수를 0으로, 나중 객체는 1로 읽는지와 전체 콜백 순서를 대조합니다. Update 제어 객체에는 -1000을 지정합니다.

OnEnable에서 자기 enabled를 false로 바꾸는 경우와 OnDisable에서 자기 enabled를 true로 되돌리는 경우를 검증했습니다. GameObject의 OnEnable 중 비활성화도 처리합니다. GameObject 비활성화 콜백 안에서 재활성화를 요청하면 Unity는 경고를 기록하고 activeSelf=true·activeInHierarchy=false 상태로 남을 수 있습니다. 이때 불필요한 OnEnable을 호출하지 않고, 이후 SetActive(true) 요청에서 계층을 다시 활성화하도록 맞췄습니다.

임시 시작 배치·재진입 상태는 복제 객체에서 정리합니다. 이 조합 자체의 모든 복제·부모 변경·삭제 동등성을 검증했다는 뜻은 아닙니다. 동일 순위의 객체, 임의 동적 초기화 순서, 깊은 재진입과 다른 객체를 변경하는 모든 조합, 물리·UI·애니메이션의 모든 조합은 아직 확인 범위 밖입니다.

부모 변경과 초기 Awake/Start 내부 생성·삭제

Transform.SetParent(parent), SetParent(parent, worldPositionStays)와 transform.parent = null의 부모 해제를 지원합니다. 활성·비활성 부모 사이 이동 후 activeSelf를 보존하고 activeInHierarchy·OnEnable·OnDisable·Update 상태를 갱신합니다. 월드 좌표 유지와 로컬 좌표 유지 옵션, 월드·로컬 위치와 회전을 함께 대조했습니다.

초기 Awake 또는 Start 안에서 비활성 객체를 만들고 사용자 컴포넌트를 추가·설정한 뒤 활성화하는 흐름을 검증했습니다. 생성 호출이 반환될 때 Awake·OnEnable은 실행됐지만 Start는 아직 실행되지 않습니다. 첫 Tick 전에 생성한 컴포넌트의 Start를 첫 Update 전에 처리하여 같은 프레임부터 Update가 실행되도록 합니다. Update 도중 생성한 경우에는 기존처럼 현재 Tick 뒤에 Start를 처리하고 다음 프레임부터 Update를 실행합니다.

Destroy(this)로 컴포넌트를 자기 삭제할 수 있습니다. 검증한 활성 컴포넌트의 Awake 내부 삭제는 Awake→OnDisable→OnDestroy 순서이며 OnEnable·Start·Update는 실행하지 않습니다. Start 내부 삭제는 Awake→OnEnable→Start→OnDisable→OnDestroy 순서이고 Update는 실행하지 않습니다. OnDisable은 삭제 요청 안에서 호출하고 실제 제거·OnDestroy는 해당 프레임의 Tick 이후 처리합니다.

이 범위는 초기 생성과 검사한 부모 변경 흐름에 대한 실행 검증입니다. 초기 실행 순서와 재진입은 해당 항목의 확인 범위를 참고해 주세요. 그 밖의 상호·재진입 콜백, 잘못된 순환 부모 지정, 임의 생성 단계와 모든 물리·UI·애니메이션 조합의 동등성은 아직 미검증입니다.

스크립트 식별자와 실행 순서

원본 MonoScript의 GUID와 Editor의 Script Execution Order 값을 내보내어 Unreal 프로젝트의 스크립트 정의에 보존합니다. C# 복원 시 같은 GUID와 executionOrder를 가진 .meta를 생성하며, 대상 자산이 이미 그 GUID를 사용하면 충돌로 중단합니다. 메타데이터가 없는 이전 패키지도 계속 복원할 수 있습니다.

Unreal의 작성된 사용자 C++ 스크립트는 명시적 실행 순서에 따라 초기 Awake·OnEnable을 처리한 뒤 Start를 정렬 실행합니다. Update도 낮은 순위의 Actor를 Tick 선행 조건으로 사용합니다. 런타임 AddComponent에도 해당 클래스의 순서 설정을 전달합니다. 동일 순위·임의 동적 생성·모든 재진입 조합의 실행 동등성은 별도 검증 범위이며, 명시적 순서가 있는 원본을 내보낼 때 이 범위를 안내합니다.

Unity 6000.0 공식 문서에 따르면 같은 값이나 기본값을 사용하는 스크립트 사이의 실행 순서는 비결정적입니다. 활성 계층 테스트는 제어 스크립트에 -100, 나머지 스크립트에 0을 명시합니다. 순서를 명시하기 전후의 원본 Unity 결과가 동일함을 대조한 뒤 포팅·역변환·패키징 실행을 비교합니다. 임의 기본 순서의 프레임별 결과를 동일하게 보존한다고 보장하지 않습니다.

GameObject 활성 상태와 비활성 계층

GameObject.SetActive(bool), activeSelf와 activeInHierarchy 조회를 네이티브 Actor 코드로 변환하고 다시 C#으로 복원합니다. 작성 시 비활성인 장면 객체와 부착 스크립트·참조도 함께 전달합니다. 원본 프로젝트는 수정하지 않습니다.

GameObject 자체의 activeSelf는 해당 객체의 태그로 보존하고, activeInHierarchy는 부모 계층과 활성화 진행 상태를 반영합니다. 부모가 비활성이어도 자식의 activeSelf는 유지됩니다. 계층이 실제 활성 상태로 전환될 때 스크립트의 Awake·OnEnable을 호출하고 Start를 지연 실행합니다. 비활성 객체에 AddComponent로 추가한 스크립트도 첫 활성화까지 Awake를 보류합니다. 비활성화는 OnDisable을 동기 호출하고 Update를 중지하며, 재활성화한 프레임의 Update는 보류합니다.

검증 시나리오는 부모 토글, 부모가 비활성일 때 자식 자체 토글, 반복 동일 값 설정, 같은 프레임 false→true, 작성 시 비활성 객체의 최초 활성화, disabled 컴포넌트와 계층 활성 상태 조합, 비활성 런타임 객체에 컴포넌트 추가 및 삭제입니다. 객체의 일반 활성/비활성 상태는 메시 표시와 Actor 충돌 상태에도 연결됩니다. 모든 종류의 물리·UI·애니메이션 컴포넌트 토글, 검사한 경우 외의 활성 콜백 재진입·상호 호출, 비활성 프리팹 생성은 아직 실행 검증 범위 밖입니다.

OnEnable/OnDisable과 컴포넌트 enabled

사용자 MonoBehaviour의 OnEnable·OnDisable, 자기 자신과 다른 컴포넌트의 enabled 읽기·단순 대입을 추가했습니다. 작성 시 disabled인 컴포넌트도 플래그와 참조를 저장·재열기·역변환합니다. GameObject의 활성 상태와 계층 전파는 아래 SetActive 지원 범위를 참고해 주세요.

활성 GameObject의 disabled 컴포넌트는 Awake를 실행하고 첫 활성화까지 OnEnable·Start·Update를 보류합니다. enabled의 실제 값이 바뀔 때 OnEnable/OnDisable을 동기 호출하고, 재활성화한 프레임의 Update를 보류합니다. Start는 한 번만 실행합니다. 컴포넌트 Destroy 호출은 즉시 enabled를 false로 바꾸고 OnDisable을 호출하며, OnDestroy와 실제 제거는 업데이트 이후에 실행합니다.

반복 false/true 대입, Start 전 비활성화, 비활성 작성 상태의 첫 활성화, 같은 프레임 false→true와 삭제를 원본 Unity의 이벤트 기록·프레임별 Update 횟수와 대조합니다. 이 기능은 네이티브 Actor 경로를 사용합니다. 임의 생성 시점·재진입·전체 실행 순서는 별도 검증 범위입니다.

동적 MonoBehaviour와 컴포넌트 참조

GameObject.AddComponent<사용자클래스>()와 GetComponent<사용자클래스>()를 추가했습니다. 컴포넌트는 소유 GameObject에 붙은 런타임 Actor로 생성하며, 조회는 상속 관계와 컴포넌트 순서를 적용해 첫 일치 항목을 반환합니다. 장면에 붙어 있지 않은 사용자 컴포넌트 클래스도 컴파일된 타입 참조를 따라 수집합니다.

사용자 MonoBehaviour 타입 필드를 별도 컴포넌트 ID로 저장합니다. 모든 객체·컴포넌트를 만든 뒤 참조를 연결하므로 앞/뒤 방향과 순환 참조를 복원할 수 있습니다. 컴포넌트 필드 읽기·단순 대입과 지원 숫자 연산, public 함수의 기본형·GameObject 인수/반환을 네이티브 프로퍼티와 UFunction 호출에 연결합니다. 가상 함수 오버라이드도 적용합니다. 지원 타입의 var 지역 변수는 의미 분석으로 타입을 결정해 명시적 타입과 같은 C++ 코드로 변환합니다.

Update에서 동적 생성한 경우 AddComponent 반환 시 Awake가 끝나고 Start는 아직 실행되지 않는 순서를 대조했습니다. 같은 프레임 후반에 Start가 실행되고 첫 Update는 다음 프레임부터 실행됩니다. 컴포넌트 단독 삭제와 GameObject 계층 복제를 처리하며 파괴된 컴포넌트와 null 변수 비교를 보강했습니다.

실행 검증 범위는 활성 사용자 컴포넌트, Update 중 생성, int·float·double·bool 반환과 GameObject 전달, 상속 조회·순환 참조입니다. 엔진 컴포넌트·배열 조회·일반 Component 복제·벡터나 사용자 컴포넌트 타입의 함수 인수/반환은 미지원입니다. Awake/Start의 임의 재진입과 장시간 GC 이후의 모든 참조 동등성은 미검증이며, 전체 생명주기 동등성을 뜻하지 않습니다.

빈 객체 생성과 런타임 초기화

new GameObject(), new GameObject("이름")을 실제 Unreal Actor와 루트 SceneComponent로 생성합니다. 이름 생성자와 object.name = "이름"에는 문자열 상수만 지원하며 한글·따옴표·대소문자를 보존합니다. Unreal 내부 객체명은 엔진이 고유하게 부여하고, 원본 이름은 별도 런타임 이름으로 보존합니다. 이름 읽기·문자열 변수/계산·NUL 이름은 아직 지원하지 않습니다.

객체의 transform.position, localPosition, rotation, localRotation, localScale 읽기·단순 대입, parent 읽기·대입과 SetParent(parent)·SetParent(parent, worldPositionStays)를 추가했습니다. 다른 객체의 Transform에도 적용합니다. 생성된 빈 객체는 메시나 사용자 스크립트를 자동으로 붙이지 않습니다. 사용자 MonoBehaviour의 제네릭 AddComponent/GetComponent를 지원합니다. 일반 엔진 컴포넌트와 Component 자체 복제는 미지원입니다.

원본 Unity, Unreal 게임 월드, 복원 Unity와 패키징한 Windows 실행 파일에서 12개 시점을 대조해 빈 객체 생성·한글 이름 변경·600자 한글 이름·대소문자 구분·부모 연결/해제·좌표/회전/크기·복제·계층 삭제·재생성과 두 번의 장면 전환이 통과했습니다. 이번 부모 검증은 회전된 부모와 균일 크기를 사용하며 비균일 크기·회전의 전단 변형은 미검증입니다.

생성 위치·회전·부모와 참조

Instantiate(source, position, rotation), Instantiate(source, parent), Instantiate(source, parent, worldPositionStays), Instantiate(source, position, rotation, parent)를 GameObject 원본에 지원합니다. 대상 엔진에서는 계층을 지연 생성하고 객체 참조와 최종 좌표·부모를 연결한 뒤 생명주기를 시작합니다. 위치·회전 인수는 Unity 좌표계를 변환하며, 부모 지정 시 로컬/월드 유지 규칙을 적용합니다.

직렬화된 Transform 장면 참조와 Quaternion 필드를 양방향으로 복원합니다. 지원 스크립트의 transform.parent, transform.rotation, transform.localRotation 읽기와 Quaternion 생성·identity를 추가했습니다. Transform 필드는 Unreal Actor 포인터로 연결하고 Unity 복원 시 해당 GameObject의 Transform으로 되돌립니다. 프리팹 에셋의 Transform 참조, 임의 Component 복제와 전체 Transform API는 아직 미지원입니다.

장면 내부 런타임 프로토타입과 참조된 프리팹 정의의 계층·좌표·직렬화 상태·메시/재질 연결이 독립적으로 수정되면 역변환을 차단합니다. 동기화 자동 전파는 아직 제공하지 않으며 원본에서 다시 임포트해야 합니다. 이전 결과에 검사 기준이 없으면 재임포트가 필요합니다. 공유 자산 자체의 모든 편집 속성을 감시하는 검사는 아닙니다.

추가 실행 검증: 10가지 생성 방식 × 프리팹/장면 원본 20개 사례를 Unity 6000.0.83f1 → Unreal 5.8.1 → 복원 Unity와 Windows 패키지에서 대조했습니다. 생성 시점의 월드/로컬 위치·회전·크기, 부모와 Awake 기록, 내부 GameObject/Transform 참조가 통과했습니다. 회전된 부모와 균일 크기를 사용했으며 비균일 크기·회전 조합의 전단 변형은 미검증입니다. 장면 7개·프리팹 정의 3개·객체 44개의 재내보내기 데이터·리소스·연결과 기존 250프레임 회귀 검사도 통과했습니다.

런타임 객체 복제·삭제와 장면 전환

Instantiate(GameObject)는 장면 객체 또는 기본 Prefab Asset의 자식 계층·연결된 지원 스크립트를 복제합니다. 직렬화된 상태와 내부 객체 참조는 새 인스턴스에 연결하고, 복제 범위 밖의 참조는 유지합니다. Destroy(GameObject)는 해당 객체와 자식 계층을 업데이트 이후 제거하며, 호출 직후의 null 비교 결과도 실행 대조합니다. Prefab Asset 필드는 Unreal의 숨겨진 장면별 프로토타입에 연결하고, Unity 복원 시 실제 Prefab Asset에 연결합니다. 프로토타입의 생명주기와 Tick은 실행하지 않습니다. 기본 프리팹 루트 간 GameObject 자산 필드 참조는 위 절의 범위에서 지원합니다. Component 자체 복제와 지연 시간 인수가 있는 삭제는 아직 미지원입니다. 모든 물리·애니메이션·UI 조합의 동적 복제는 검증하지 않았습니다.

SceneManager.LoadScene(1) 또는 활성 빌드 장면의 고유한 이름 상수를 사용하는 단일 장면 전환을 지원합니다. 비활성 장면·중복 이름·범위 밖 인덱스는 생성 전에 차단합니다. 복원 Unity 장면의 파일 이름과 빌드 순서를 보존하고, Unreal에는 해당 맵 경로를 런타임 태그로 연결합니다. 변수 인수·전체 경로·비동기/Additive 전환·DontDestroyOnLoad·사용자 정의 GameInstance의 일반 변환은 미지원입니다.

Unity 6000.0.83f1 → Unreal 5.8.1 → Unity에서 생성·삭제·재생성과 두 번의 실제 월드 전환을 실행했습니다. 생성/삭제 프레임을 포함한 8개 지점에서 Awake/Start 횟수, 계층·위치, 내부/외부 참조와 삭제 직후 유효성을 대조했습니다. 기본 프리팹의 메시·재질·내부 참조도 대조했으며 Windows 게임으로 빌드·쿠킹·패키징한 실행 파일에서 같은 검사를 통과했습니다. 삭제 콜백 해제 후 캡처값을 읽는 문제를 수정했습니다. 전체 게임·렌더링 동일성 및 모든 엔진 버전의 통과를 뜻하지 않습니다.

별도 코드·Blueprint 메뉴

정적 함수 생성기는 제한된 float/double/bool 수식·분기·지역 변수·루프를 C# ↔ C++로 생성합니다. Blueprint 변환은 double 입력·반환, +/−/×·비교·Branch/Return을 사용하는 순수 Function Library에 한정됩니다. 실제 노드·핀·실행 흐름을 읽어 동등한 C# 표현으로 복원합니다.

실제 Actor Blueprint 이벤트 그래프

float/double/bool 필드, 수식·비교·분기·대입, Start→BeginPlay, Update→Tick, OnDestroy→EndPlay, 상속과 명시적 부모 호출을 실제 노드로 생성합니다. 저장된 노드·핀·실행 흐름을 다시 읽어 C#으로 복원합니다. 제한된 문법의 기존 Actor Blueprint도 부모 클래스를 함께 추출합니다. 더 넓은 C++ Runtime Actor 경로와 지원 문법이 다릅니다.

임의 Actor Blueprint 노드, 지연·비동기·루프·엔진 함수 호출, FixedUpdate/LateUpdate, OnEnable/OnDisable, 비활성 컴포넌트 생명주기, 코루틴·제네릭·외부 DLL·패키지 코드는 미완료입니다. 장면에 붙지 않은 모든 보조 스크립트가 자동 통합되는 기능도 아직 없습니다.

05 · 실제 검증과 완료 판정

추가 패키징 검사에서 게임 타깃·Runtime 모듈을 생성해 실제 Windows 실행 파일을 구동했습니다. Unity에서 기록한 동일 deltaTime 입력으로 250프레임을 실행했으며, Unreal의 시작 전 부트스트랩 프레임 1개는 제외했습니다. 이 검사는 자연 FPS, 실제 마우스 입력 또는 렌더링 외형의 동일성을 보장하지 않습니다.

Unity 장면에는 원래 없는 DefaultPawn이 생성되어 물리에 영향을 주지 않도록 해당 맵 전용 GameMode를 저장합니다. Pawn·Spectator·HUD 자동 생성은 끄고 기본 PlayerController는 유지합니다. 사용자 정의 GameMode 로직의 일반 변환은 아직 지원하지 않습니다.

추가한 Actor Blueprint·기본 물리·Legacy Animation·UMG는 Unreal 5.8.1 및 5.5.4에서 실제 자동 변환·저장·250프레임 실행 검증을 통과했습니다. 250프레임 실행에서 상속·상태·종료 이벤트와 애니메이션 위치·크기를 대조했습니다. 물리 자유낙하는 약 0.000002m 이내였으나 접촉 회복 중 최대 약 0.20m 차이가 있어 전체 궤적 동등성은 통과로 표시하지 않습니다. UMG 객체 생성은 확인했으며 화면 외형·마우스 입력은 미확인입니다.

확장 테스트는 18개 장면 객체를 Unity → Unreal → Unity로 저장·재추출해 대조했고 오류가 없었습니다. Actor 3개, 애니메이션 1개, 동적 강체 2개, UMG 위젯 트리와 두 번의 버튼 콜백을 원본·Unreal·복원 Unity의 250프레임에서 비교했습니다. 활성 콜백의 순서와 비활성 리스너 보존 결과는 상태값 1212로 일치했습니다. 기존 비소유 Actor Blueprint도 상속·인스턴스 값·종료 상태를 별도로 실행 대조했습니다. float 중간 연산은 반올림 보존을 위해 C++ Actor 경로를 사용합니다.

검증 엔진: Unity 6000.0.83f1, Unreal 5.8.1 및 5.5.4. 제공된 EngineMigratorUnity는 기본 URP 장면이며, 게임 로직은 원본과 분리한 복사본에 검증용으로 추가했습니다.

모든 버전·모든 프로젝트를 지원한다고 판정한 상태가 아닙니다.

전체 코드·의존성의 대응, 미해결 차단 해소, 대상 컴파일·시작 장면·핵심 플레이·렌더링·패키징 검증을 모두 통과해야 프로젝트 포팅 완료입니다. 현재 결과의 projectPortComplete는 false입니다. 렌더링 외형은 동일하다고 검증하지 않았습니다.

06 · 선택형 로컬 LLM

현재 로컬 LLM 연결 기능은 없습니다. 향후 선택 기능으로 제공하더라도 기본 추출·변환·오류 보고가 모델 없이 동작하도록 설계합니다. 모델이 만든 수정안도 실제 컴파일과 실행 대조를 거쳐야 성공으로 판정합니다.

07 · 남은 구현

지원하지 않는 기능을 삭제하거나 빈 코드로 바꿔 성공 처리하지 않습니다. 실패 로그와 생성된 작업 복사본을 남겨 이어서 해결합니다.

런타임 UI 프리팹과 콜백 연결

지원 Overlay uGUI 프리팹을 Instantiate하면 Canvas의 UMG 위젯과 표시 관리 Actor를 함께 생성합니다. 버튼의 대상은 장면 전체 태그 검색 대신 이번에 복제한 객체·컴포넌트 집합으로 연결합니다. 여러 인스턴스와 실행 중 재복제본의 콜백이 서로 섞이지 않도록 처리합니다.

검증 방식: Unity의 실제 Button.onClick.Invoke와 Unreal의 실제 UButton.OnClicked Broadcast를 같은 시점에 실행하고, 자기 인스턴스의 상태·순서·생명주기와 뷰포트 위젯 수를 대조합니다. 마우스 입력·클릭 좌표·렌더링 동일성 검증을 대신하지 않습니다.

범위: 기본 Overlay Canvas, 단위 배율, 기존 지원 Image/RawImage/Text/Button 레이아웃입니다. 중첩 Canvas·임의 UI 회전/배율·버튼 시각 전환·외부 폰트·UI Transform API의 화면 좌표·배율 동등성은 미지원입니다. 실제 실행에서 Canvas 루트 배율이 Unity 1과 현재 Unreal 프록시 0으로 다른 것을 확인했습니다. Unity가 프리팹 미리보기의 Overlay 루트에 기록하는 0 스케일은 실행 관찰에 근거해 사전 검사에서 구분합니다. 일반 0 스케일 UI 지원을 뜻하지 않습니다.

UI 컴포넌트 API와 씬 UI 복제

2026-10-23: 실제 Unreal 에디터 실행 20개 지점과 패키지 실행 20개 지점, 원본/복원 Unity 각각의 250프레임 Unreal 대조가 통과했습니다. 이 기능의 새 배포본 반영은 아직 남아 있습니다.

GameObject 또는 사용자 MonoBehaviour의 GetComponent<Canvas>(), GetComponent<Button>()와 Canvas.enabled, Button.enabled, Button.interactable의 읽기·단순 대입을 처리합니다. Canvas/Button 직렬화 필드는 소유 객체를 통해 실제 컴포넌트로 복원하고, 런타임 복제 시 내부 참조를 새 계층에 연결합니다.

Canvas를 꺼도 GameObject와 스크립트의 활성 상태는 유지하고 UI 표시만 바꿉니다. Button.enabled와 interactable은 별도 상태로 보존하며 실제 UMG 버튼에는 두 조건을 함께 적용합니다. 처음부터 꺼진 Canvas를 스크립트로 켜는 동작도 포함합니다.

씬에 배치된 UI도 표시 관리 Actor를 사용합니다. 복제 범위 안의 콜백 대상은 새 인스턴스로 연결하고, 범위 밖의 기존 컴포넌트는 원래 대상을 유지합니다. 원본 UI를 삭제한 뒤 복제본에서 외부 콜백이 계속 호출되는 것을 실행 대조합니다.

검증은 기본 Overlay UI와 지원 상태 API 범위입니다. UI 컴포넌트 AddComponent/Destroy, 런타임 AddListener, 일반 문자열·색·텍스트 API와 RectTransform 전체 API는 미완료입니다. UI Transform 좌표·배율의 프록시 차이는 여전히 미지원이며, 이번 상태 API 검증을 Transform 또는 렌더링 동등성으로 해석하지 않습니다.

개발 중 수정: 괄호가 있는 null 비교

Target == ((null)), (null) != Target도 기존 null 비교와 같은 객체 유효성 검사로 생성합니다. GameObject·Transform·사용자 MonoBehaviour·Canvas·Button의 해당 구문을 검사했습니다. 엔진 비실행 검사와 원본/복원 C# 실행을 통과했으며, 이 구문의 실제 엔진 실행은 미검증입니다.

현재 방화벽 알림 재발 방지를 위해 엔진 자동 실행을 차단한 상태로 코드 개발을 계속합니다. UI 컴포넌트 API 단계의 패키징 및 250프레임 왕복 검증은 미완료이며, 이전 UI 프리팹 배포본에 이번 수정이 포함됐다고 해석하지 않습니다.

개발 중: 참조형 default

지원 참조형 GameObject·Transform·사용자 MonoBehaviour·Canvas·Button의 default(T)와 문맥에서 타입이 추론되는 default를 처리합니다. 필드 초기화·지역 변수·대입·반환과 ==/!= 비교를 포함합니다. 비교는 기존 객체 유효성 검사로 생성하며, 괄호가 있는 default도 동일하게 처리합니다. 역변환 시 동등한 null 표현식으로 복원할 수 있습니다.

엔진 비실행 검사 194개 통과. 값 형식 default(int) 등은 이번 지원 범위가 아닙니다. 이 변경의 실제 Unity/Unreal 실행 및 배포 반영은 미완료입니다.

개발 중: for와 do/while

지원 표현식으로 작성한 for의 선언/초기식·조건·증감식과 do/while을 변환합니다. 중첩 범위·continue·break·조기 반환, 생략한 절과 빈 본문을 보존합니다. 정수 증감은 기존 오버플로 처리 함수를 사용합니다. 여러 초기식과 증감식은 순서대로 실행하며, 기존 미지원 연산과 상태 변경 평가 순서 검사는 그대로 적용합니다.

원본·복원 C#과 실제 생성 반복문 코드를 추출한 독립 C++를 실행 대조했습니다. Unreal 엔진·전체 게임 동작 검증과 배포 반영은 미완료입니다.

개발 중: int switch

int 선택값의 switch와 정수 상수 case, default, 묶인 라벨, 중첩 분기 및 반복문 안의 continue/break를 변환합니다. 선택식은 한 번 실행하며 빈 switch에서도 호출 효과를 보존합니다. 라벨의 상수 식은 정수값으로 계산해 생성합니다. 최소 정수값은 부호 경고가 없는 상수 식으로 출력합니다.

분기 안 지역 변수는 C++에서 초기화를 건너뛰는 문제를 피하도록 범위를 나눕니다. 여러 분기가 공유하는 지원 지역 변수는 switch를 감싸는 범위로 보존하며, 원래 초기화 식은 선택된 분기에서 실행합니다. 패턴·when·goto case 및 int 이외 선택값은 아직 차단합니다.

관리 코드 검사 204개와 생성 코드를 추출한 독립 C++ 실행 대조를 통과했습니다. 실제 Unity/Unreal 실행과 배포본 반영은 미완료입니다.

개발 중: 분기 간 공유 지역 변수

case 하나에서 선언하고 다른 case에서 대입 후 읽는 지원 지역 변수를 처리합니다. 여러 변수가 한 선언에 있으면 초기화 순서를 유지합니다. 선택되지 않은 분기의 초기화 함수를 미리 실행하지 않습니다. 저장 범위는 switch 주변 블록 안에 유지하므로 원래 바깥의 지역 변수 범위를 침범하지 않습니다.

관리 코드 검사 205개 통과. 정수 공유 변수는 원본/복원 C#과 생성 코드를 추출한 독립 C++에서, GameObject 참조는 관리 코드의 null/객체 상태로 대조했습니다. 실제 Unity/Unreal 동작과 배포 반영은 미완료입니다.

개발 중: 삼항 조건 연산자

int/float/double/bool 결과의 조건 ? 참인 경우 : 거짓인 경우 구문을 변환합니다. 중첩 조건도 처리하며, 선택되지 않은 분기의 함수는 실행하지 않습니다. 기존 수식의 상태 변경 평가 순서 검사는 그대로 적용합니다. 객체 참조 선택은 아래 개발 항목에서 별도로 확장했습니다. 벡터 선택은 아직 미지원입니다.

관리 코드 검사 208개와 실제 생성 코드를 추출한 독립 C++ 실행 대조를 통과했습니다. 실제 Unity/Unreal 동작과 배포 반영은 미완료입니다.

개발 중: 지역 const

메서드 안의 int/float/double/bool const를 컴파일러가 확인한 상수값으로 치환합니다. 상수 간 계산, 반복문 조건과 switch 라벨, case 사이에서 읽는 지역 상수를 처리합니다. 런타임 저장 공간은 만들지 않으며, 복원 C#에는 상수 이름 대신 값이 들어갈 수 있습니다.

관리 코드 검사 211개 및 생성 코드를 추출한 독립 C++ 실행 대조를 통과했습니다. 정수 경계값, 부동소수 비트와 음의 0도 대조했습니다. NaN/Infinity·미지원 타입·클래스 const 필드는 이번 범위가 아니며, 실제 엔진 동작과 배포 반영은 미완료입니다.

개발 중: 안전한 정수 상수 나눗셈

컴파일러가 값이 0·-1이 아닌 int 상수라고 확인한 나눗수의 /·%·/=·%=를 변환합니다. 음수 몫의 0 방향 절삭과 나머지 부호, 정수 경계값을 대조했습니다. 지원 컴포넌트 필드 대입과 반복문 증감식에도 같은 검사를 적용합니다.

런타임 변수·0·-1 나눗수는 차단합니다. 0 나눗셈·오버플로 예외의 Unity/Unreal 런타임 동등성은 아직 구현하지 않았습니다. float 나머지 복합 대입도 이번 범위가 아닙니다.

관리 코드 검사 215개와 독립 C++·별도 기대값 대조를 통과했습니다. 실제 엔진 검증 및 배포 반영은 미완료입니다.

개발 중: 객체 참조 조건식

GameObject·Transform·Canvas·Button 및 지원 사용자 컴포넌트의 조건 ? 참 참조 : 거짓 참조를 변환합니다. null 분기, 두 분기 모두 null인 대상 타입 추론, 중첩 조건, 상속 컴포넌트 선택을 처리합니다. 선택된 분기만 평가하고 참조의 정체성을 유지합니다.

관리 코드 검사 217개 통과. 생성 함수 본문을 추출한 독립 C++에서도 GameObject·Transform 선택과 호출 횟수를 대조했습니다. 독립 검사에는 추적 포인터의 대체 타입을 사용했으므로 실제 Unreal GC·추적 포인터 검증은 미완료입니다. 기존 엔진 실행 대상 49개 헤더는 동일합니다. 신규 기능의 실제 엔진 검증과 배포 반영은 미완료입니다.

실행 결과 비교 무결성 보완

중복 UI 소유자를 넣은 실제 저장 캡처가 기존 비교에서 통과하던 오류를 재현하고 수정했습니다. 중복 JSON 키·배우/객체/소유자 ID·상태 필드·검증 지점, 검증 순서와 누락, 여러 드라이버, 잘못된 bool/정수 타입 및 비표준 JSON 숫자를 거부합니다. Python 최적화로 의미 검사가 생략되는 실행도 거부합니다.

실패하면 기존 PASS 보고서를 FAIL로 원자적으로 교체하며 입력 캡처 덮어쓰기를 막습니다. 입력과 비교 코드의 SHA-256을 보고서에 기록합니다. 손상 데이터·정상 대조 검사 34개와 고정 경로 실제 패키지의 새 캡처 20개 지점이 통과했습니다. UI API 원본/복원 저장 캡처도 재대조했습니다. 이 결과는 신규 변환 기능의 실제 엔진 검증이나 전체 포팅 완료를 뜻하지 않습니다.

런타임 객체·프리팹·삭제 검증 무결성

객체 ID가 중복된 저장 캡처가 기존 런타임 월드·프리팹·삭제 비교 3종에서 통과하던 오류를 재현하고 수정했습니다. 필수 검증 지점의 중복·순서 오류·누락과 bool/숫자 혼동을 거부하고, 실패 보고서 및 입력·비교 코드 해시 기록을 공통 적용했습니다.

핵심 비교 검사 32개와 UI 회귀 34개가 통과했습니다. Unity 원본·Unreal·복원 Unity 저장 캡처 및 의존하는 배치 비교도 재대조했습니다. 기존 프리팹 패키지는 허용된 고정 실행 경로에서 새로 실행하여 8개 지점과 RuntimeSpawner → RuntimeMiddle → RuntimeFinal 전환이 통과했습니다. 신규 변환 기능의 엔진 검증과 배포 반영은 미완료이며 공용 에디터 실행은 기존 규칙을 확인한 전용 검증 경로에서 재개했습니다.

UI 컴포넌트 API 실제 실행 재개

사용자 위임으로 반복 확인 없이 감사된 실행 경로에서 개발을 재개했습니다. 기존 활성 프로필의 방화벽 규칙을 확인하고 Trace Server·Zen 자동 실행·UDP 메시징을 끈 Unreal 실행이 완료되어 UI API 20개 지점이 통과했습니다. Zen 저장소 쿠킹을 명시적으로 건너뛴 새 패키지도 고정 경로에서 실제 실행해 20개 지점이 통과했습니다.

물리·애니메이션·생명주기 등 10개 비교 도구의 입력 무결성과 실패 보고를 보완했습니다. 저장 캡처·손상 데이터·허용 오차 검사 94개, 기존 핵심 32개·UI 34개가 통과했습니다. 물리와 애니메이션 허용 오차는 확대하지 않았습니다.

복원 Unity의 250프레임 캡처는 완료했습니다. 원본 개인 복사본도 250프레임 캡처를 완료했고, 원본과 복원본 각각을 실제 Unreal에서 대조해 통과했습니다. 전용 IPC로 동작하는 UPM의 실제 인수와 TCP 수신 포트 없음도 기록했습니다. 신규 C# 변환 문법의 엔진 검증과 배포 반영, 전체 프로젝트 포팅은 아직 미완료입니다.

공통 엔진 실행 전 검사와 최적화 빌드 검증

일반 C# 변환 경로의 RunEditor에 읽기 전용 방화벽 검사, 충돌 인수 거부, 개인 프로젝트 경로 검증, 공유 실행 잠금, 디스크 감시와 실행 전후 기록을 연결했습니다. Unity UPM의 named IPC와 TCP 수신 포트 없음도 감시·기록합니다. 현재 실제 감사한 Unity 6000.0.83f1과 Unreal 5.8의 정확한 설치 경로 및 artifacts 내부에만 제한적으로 실행을 재개했으며, 차단 표식은 유지합니다. 다른 설치 경로·버전은 자동 승인하지 않습니다.

공통 실행 경로에서 생성 클래스 6개를 실제 컴파일하고 호출했습니다. 반복문·switch·숫자 조건식·지역 상수·안전한 정수 나눗셈과 GameObject 조건식이 통과했습니다. Transform·UI 참조 조건식은 이번 실행 대조에 포함되지 않아 미검증으로 남깁니다. Unity의 실제 프로젝트 내보내기는 기존 패키지와 45개 단위·131개 노드·49개 스크립트가 일치했습니다.

MSVC /O2와 실제 Unreal에서 오버플로 반복문 결과가 2 대신 -2147483646으로 바뀌는 것을 재현했습니다. 생성 정수 랩 도우미에 검증된 volatile 쓰기·읽기 경계를 넣은 뒤 실제 Unreal과 /O2 독립 5종에서 대조를 통과했습니다. 컴파일러 내부 변환 과정과 성능 영향은 별도로 측정하지 않았습니다. 이전 생성 헤더 49개의 역변환도 통과했습니다.

관리 코드 검사 262개 통과. Unreal 5.8은 UBA 로컬 실행기를 유지하므로 NoUBA를 실행기 제거라고 설명하지 않습니다. 디투어링·원격 실행을 차단하고 UBADisableRemote·NoXGE·NoFASTBuild·NoSNDBS를 명시합니다. 새 GUI 배포본과 전체 프로젝트 포팅 완료는 아직 아닙니다.

Transform·UI·상속 참조 조건식 실제 실행

Unity C# → 생성 C++ → 복원 C# 경로에서 Canvas·Button·부모/자식 컴포넌트 선택, null, 선택한 분기만 호출되는지와 UI 상태 쓰기의 격리를 검증했습니다. 원본·복원 C#에서 각각 22개 지점, 실제 Unreal 5.8에서 Transform null 선택까지 포함해 28개 지점이 통과했습니다. 기존 반복문·switch·상수·정수 나눗셈·GameObject 조건식 회귀도 함께 통과했습니다.

관리 코드 검사 263개가 통과했습니다. 실제 Unreal C++ 함수 호출 검증이며 화면 렌더링·마우스 입력의 동등성이나 전체 프로젝트 포팅 완료를 뜻하지 않습니다. 원본 프로젝트는 수정하지 않았으며 컴퓨터 유즈는 사용하지 않았습니다.

정수 비트 연산과 실제 양방향 실행 대조

int32의 &·|·^·~·<<·>> 및 지역 변수·필드·다른 컴포넌트 필드의 복합 대입을 추가했습니다. 시프트 횟수는 C# 규칙에 맞춰 하위 5비트를 사용하며, 음수 오른쪽 시프트는 부호를 확장합니다. 왼쪽 시프트는 unsigned 비트 연산과 비트 복사로 생성합니다.

Unity 6000.0.83f1의 원본·복원 컴포넌트, Unreal 5.8의 생성 C++(/Ox), 관리 코드 원본·복원 실행까지 5개 결과를 독립 기준값과 대조했습니다. 각 실행에서 128개 경계값 조합 × 9개 결과가 일치했고, 시프트 반복문도 31회로 종료했습니다. 기존 참조·UI 검사 28개를 포함한 Unreal 회귀와 관리 코드 267개 검사가 통과했습니다.

지원 범위는 부호 있는 int32입니다. bool·uint·long 비트 연산, 상태 변경 호출이 섞인 평가 순서 및 전체 프로젝트 포팅 완료를 보장하지 않습니다. 사용자 원본 기준 파일 60개는 변경되지 않았습니다.

계산된 빌드 인덱스로 실제 장면 전환

SceneManager.LoadScene의 int 필드·계산식·함수 반환값과 지역 int 상수를 지원합니다. 생성 C++는 인수를 한 번 평가하고 기존 프로젝트의 활성 빌드 인덱스 → 저장된 Unreal 맵 대응을 사용합니다. 단일 장면 전환 범위이며 동적 문자열 이름·비동기·Additive 로드나 잘못된 인덱스의 예외 동등성은 검증하지 않았습니다.

기존 프리팹 런타임 장면을 개인 복사본에서 실행했습니다. 원본 Unity → 생성 C++ Unreal → 복원 Unity에서 NextIndex()로 시작 → 중간 → 마지막 장면 전환이 통과했습니다. 생성·삭제·재생성 8개 지점, 내부 참조 재연결, 공유 메시·재질, Awake·Start 횟수, 삭제 요청 직후의 유효 상태도 일치했습니다. 모든 프레임의 장면 전환 시점이나 렌더링 동등성을 뜻하지 않습니다.

관리 코드 271개 검사가 통과했습니다. PCH 없이 실제 빌드하면서 발견한 검사 호스트의 UPackage include 누락과 Output 전역 이름 충돌을 수정한 뒤 빌드·실행을 통과했습니다. 실패 로그는 보존했습니다. 사용자 원본 기준 파일 60개는 변경되지 않았으며 전체 프로젝트 포팅 목표는 계속 진행 중입니다.

프로젝트 전체 헤더 49개를 함께 역변환하는 검사도 통과했습니다. 기존 LF·새 CRLF 도우미의 줄바꿈 차이를 정규화했으며 수정된 도우미를 거부하는 본문 검증은 유지했습니다. LF/CRLF 회귀 검사를 추가했고, 전체 역변환에서 나온 RuntimeSpawner C#은 실제 복원 Unity 실행에 사용한 파일과 SHA-256이 일치합니다.

Unity 객체의 bool 변환과 삭제 전후 유효성

GameObject·Transform·Canvas·Button·사용자 MonoBehaviour 참조를 if 조건, ! 연산, bool 변수·인수·반환값, 명시적 bool 캐스트, 조건 연산자와 &&·||에 사용할 수 있습니다. bool 상수 비교도 실제 변환 결과를 사용합니다. 생성 C++는 포인터 존재 여부 대신 객체 유효성을 확인하며, 비활성 객체를 삭제된 객체로 취급하지 않습니다.

null·살아 있는 객체·소유 객체가 삭제된 참조·비활성 소유 객체의 16조합에서 16개 결과를 대조했습니다. 관리 코드 원본·복원본, 실제 Unity 원본·복원본, 실제 Unreal 5종이 독립 기준값과 일치했습니다. 단락 평가에서 선택한 분기만 한 번 호출되는 것도 확인했습니다.

실제 프리팹 실행에서 비활성화 후 참조 true, 삭제 요청 직후 true, 다음 프레임 false와 !참조 분기가 원본 Unity → Unreal → 복원 Unity에서 일치했습니다. 기존 생성·삭제·재생성·내부 참조·공유 메시와 재질·생명주기·3개 장면 전환의 8개 지점도 통과했습니다. 전체 스크립트 헤더 49개 역변환과 관리 코드 274개 검사가 통과했습니다.

PCH에 의존하던 생성 런타임 헤더에 UPackage include를 추가하고 이전 헤더도 역변환할 수 있도록 유지했습니다. UI 컴포넌트만 따로 삭제하는 API, 렌더링·입력 동등성 및 전체 프로젝트 포팅 완료를 뜻하지 않습니다. 사용자 원본 기준 파일 60개는 변경되지 않았습니다.

GameObject GC 참조 수정 · 실제 왕복 검증 통과

2026-10-23 16:18:27 KST 기준. 서로 다른 삭제 객체의 참조가 GC 후 모두 null이 되어 같다고 판단하던 문제를 실제 Unreal 동기 GC에서 재현하고 수정했습니다. 객체 인덱스와 일련번호를 유지하는 약한 참조로 객체의 생존 여부와 식별 정보를 구분합니다.

Unity 코드Unreal 대응복원 결과
GameObject a, b / a == b동등성 비교가 있는 변환 묶음은 GameObject 필드·지역 변수·인수·반환값에 TWeakObjectPtr<AActor>를 사용합니다.GameObject / == 로 복원합니다.
삭제 객체와 null 비교명시적 null과 객체의 생존 상태를 구분합니다.삭제 객체는 null과 같게 처리합니다.
서로 다른 삭제 객체 비교GC 이후에도 인덱스·일련번호를 비교합니다. Get() 결과끼리 비교하지 않습니다.서로 다르면 같지 않습니다.
Instantiate / Destroy / SetActive 등엔진 API를 호출하는 경계에서만 살아 있는 Actor 포인터를 꺼냅니다. 약한 참조 복사 시 식별 정보는 유지합니다.지원 API의 원래 C# 호출로 복원합니다.

실제 Unity 원본·Unreal·복원 Unity에서 20개 조합의 GC 전후 비교 및 인수·반환·조건식·리플렉션 호출·인수의 값 복사·null 재대입 흐름을 대조했습니다. Unreal 동기 GC 완료 콜백 20회를 확인했습니다. 프로젝트 실행은 Unity 원본 55프레임·Unreal 56프레임·복원 Unity 55프레임이며, 8개 프리팹 수명주기·참조 체크포인트와 RuntimeSpawner → RuntimeMiddle → RuntimeFinal 장면 전환이 일치했습니다. 프로젝트 안에서도 GC 완료 후 서로 다른 삭제 객체와 복제 별칭을 확인했습니다. 프레임 타임라인 전체가 동일하다는 뜻은 아닙니다.

현재 .NET 검사 286개가 통과했습니다. 일반 공개 변환 API가 엔진에서 실행한 49개 헤더와 정확히 일치하는 코드를 생성했으며, 49개 스크립트를 복원했습니다. 변경 대상 RuntimeSpawner를 제외한 48개는 이전 복원본과 Roslyn 토큰 종류·텍스트·누락 여부가 일치했습니다. 기존 실제 Unity 원본/복원 250프레임 캡처와 새 Unreal 250프레임 실행의 회귀 대조도 통과했습니다. 이는 이번에 Unity 250프레임을 다시 실행했다는 뜻은 아닙니다.

지원 범위: 이번 실행 버전은 Unity 6000.0.83f1과 Unreal 5.8입니다. GameObject 참조 비교가 대상이며 모든 컴포넌트 식별·Blueprint 그래프·엔진 버전을 검증한 것은 아닙니다. 약한 GameObject 참조를 인수/반환값으로 쓰는 함수는 UFUNCTION()로 리플렉션되지만 해당 인수/반환값을 Blueprint 호출 핀으로 직접 노출하는 기능은 아직 지원하지 않습니다. 렌더링·입력·물리 궤적 동등성 및 전체 프로젝트 포팅 완료는 미확인입니다.

사용자 원본 60개 파일은 보존됐습니다. 전용 테스트 복사본과 기존 고정 에디터 경로를 사용하고 실행 전후 방화벽 검사, 배타 실행, IPC 감시를 유지했습니다. 전체 방화벽 설정이나 다른 프로젝트 프로세스는 변경하지 않았습니다. GUI 창 검사와 컴퓨터 유즈는 수행하지 않았습니다.

사용자 컴포넌트 GC 참조 — 실제 왕복 검증 통과

2026-10-23 20:38:44 KST 기준. 일반 변환 API에서 사용자 MonoBehaviour 참조 간 동등성 비교가 있는 변환 묶음은 컴포넌트 참조와 GameObject 참조를 약한 Actor 참조로 보존합니다. 지역 변수는 원래 컴포넌트 타입을 복원할 수 있는 별칭을 사용합니다. 함수 입력은 const 약한 참조로 전달받아 별도 지역 변수로 복사하므로 삭제 객체 식별 정보와 C# 인수의 값 복사 의미를 유지합니다. UHT가 약한 참조 입력 전용 매크로를 생성한 것도 확인했습니다.

실제 Unity 원본 → Unreal → 복원 Unity에서 34개 조합의 16개 값이 GC 전후 일치했습니다. 컴포넌트만 삭제, 소유 객체 삭제, 비활성 객체, 같은 소유 객체의 다른 컴포넌트, 함수 인수·반환값·인수 재대입을 포함합니다. Unreal 동기 GC 완료 34회를 확인했습니다. 일반 변환 API의 생성·복원 코드가 실행한 코드와 일치합니다.

프로젝트 49개 스크립트 생성·복원 및 실제 런타임 대조도 통과했습니다. 원본 Unity 55프레임·Unreal 56프레임·복원 Unity 55프레임에서 프리팹 8개 체크포인트와 RuntimeSpawner → RuntimeMiddle → RuntimeFinal 장면 순서가 일치했습니다. 기존 Unity 원본/복원 250프레임 캡처와 이번 Unreal 250프레임 회귀 대조도 통과했습니다. 이번에 Unity 250프레임을 새로 실행했다는 뜻은 아닙니다. 내부 검사 292개와 IPC 감시의 종료 경합 모의 검사 6개가 통과했습니다.

적용 안내: 지원하는 사용자 컴포넌트 참조의 == / != 비교가 있으면 자동 적용됩니다. 타입 메타데이터와 약한 참조 별칭은 역변환 시 검사하며, 임의 변경은 차단합니다. 일반 C#의 상태 변경 호출이 섞인 복합식은 기존 평가 순서 제한이 적용됩니다. 예를 들어 반환값 비교는 먼저 지역 변수에 받은 뒤 비교할 수 있습니다.

남은 범위: 실행 버전은 Unity 6000.0.83f1과 Unreal 5.8입니다. Transform·UI 컴포넌트의 전체 식별, 약한 참조를 쓰는 Blueprint 함수 핀, 모든 엔진 버전, 물리 궤적·렌더링 동등성 및 전체 프로젝트 포팅 완료는 검증하지 않았습니다. 사용자 원본 60개 파일의 해시는 기존 기준과 일치합니다. 방화벽 정책 변경·UAC·컴퓨터 유즈 없이 기존 안전 실행기의 검사·잠금·시간 제한을 사용했습니다. 보안창 유무의 GUI 검사는 하지 않았습니다.

Transform GC 참조 — 실제 재현·수정·왕복 검증

2026-10-23 20:54:03 KST 기준. 기존 Transform 변환은 GC 전에 삭제 객체와 null 비교 2개 조합에서, GC 후 서로 다른 삭제 객체 비교 1개 조합에서 Unity와 달랐습니다. 실제 수정 전 Unreal 캡처와 원본 Unity 캡처를 보존했습니다. 수정본은 Transform 참조 간 == / != 비교가 있는 변환 묶음에서 소유 Actor의 약한 참조 식별 정보를 사용합니다. Transform은 이번 검증에서 소유 GameObject와 함께 삭제됩니다. GameObject와 Transform의 서로 다른 객체 종류를 같은 것으로 취급하지 않으며, 두 종류 사이 직접 비교는 기존처럼 지원하지 않습니다.

Unity 코드Unreal 대응역변환
Transform 필드·지역 변수약한 Actor 참조, 지역 변수는 EM_TransformRef 별칭Transform 타입 유지
Transform 함수 입력·반환식별 정보를 유지하는 약한 참조와 입력의 지역 복사원래 입력·반환 타입 유지
localPosition / SetParent / parent실제 엔진 API 경계에서만 살아 있는 Actor 포인터를 사용Unity 속성·SetParent 호출로 복원

실제 Unity 원본 → Unreal → 복원 Unity에서 20개 조합의 18개 값이 GC 전후 일치했습니다. 동기 Unreal GC 완료 20회를 확인했습니다. 함수 인수·반환·재대입, 위치 변경과 부모 설정·해제를 포함합니다. parent = null은 SetParent(null, true)로 복원될 수 있으며 두 실행 결과를 대조했습니다. 일반 변환 API가 실행한 헤더·복원 코드를 그대로 생성하는 것도 확인했습니다.

49개 스크립트의 프로젝트 생성·복원 및 런타임 왕복도 통과했습니다. Unity 원본 55프레임·Unreal 56프레임·복원 Unity 55프레임에서 프리팹 8개 체크포인트, GC 후 Transform 식별, 세 장면 전환을 대조했습니다. 기존 실제 Unity 원본/복원 250프레임 캡처와 새 Unreal 250프레임 회귀 비교도 통과했습니다. 이번 단계의 내부 검사는 296개입니다. 사용자 원본 60개 파일의 해시가 기존 기준과 일치합니다.

남은 범위: 실행 버전은 Unity 6000.0.83f1과 Unreal 5.8입니다. UI 컴포넌트 식별, 모든 Transform API, 약한 참조 Blueprint 호출 핀, 모든 엔진 버전 및 전체 프로젝트 포팅 완료는 검증하지 않았습니다. 물리 궤적과 렌더링의 동등성도 보장하지 않습니다. 기존 안전 실행기와 방화벽 검사·잠금을 사용했으며 방화벽 정책 변경·UAC·컴퓨터 유즈는 수행하지 않았습니다. GUI 보안창 유무 자체는 검사하지 않았습니다.

Canvas·Button 참조·삭제·복제 — 실제 왕복 검증 통과

2026-10-23 22:39:00 KST 기준. 같은 소유 객체의 Canvas와 Button을 같은 참조로 판단하거나 Canvas만 삭제했는데 살아 있다고 판단하던 차이를 실제 엔진에서 재현했습니다. 수정 전 30개 조합 중 28개가 달랐으며, 수정 후 30개 조합의 GC 전후 값이 Unity 원본 → Unreal → 복원 Unity에서 일치했습니다.

Unity 동작Unreal 대응검증 범위
Canvas / Button 참조소유 Actor의 약한 식별 정보와 UI 종류·존재 여부를 함께 사용같은 소유 객체의 다른 UI 종류, null·삭제·비활성·GC 이후 비교
Destroy(Canvas) / Destroy(Button)현재 프레임은 유지하고 프레임 말에 UI 종류 표식을 제거하며 표시/입력 상태를 갱신중복 삭제, 다음 프레임 조회, 소유 GameObject 유지
삭제 후 복제실행한 Unity 버전에서 관찰한 대로 Canvas는 원본 삭제 참조 식별을 보존하고 Button은 실제 null로 복제관리 참조 null 상태와 명시적 약한 null 상태까지 대조
삭제 대기 중 복제복제본에 원본의 삭제 대기 요청을 전달하지 않음새 복제본의 Canvas를 별도로 삭제하는 동작 포함

삭제·복제 시나리오는 실제 게임/플레이 모드 7프레임의 17개 값을 대조했습니다. 수정 과정에서 두 UI 종류를 모두 null로 처리하는 안도 실제 관리 참조 비교에서 실패해 제외했습니다. 성공한 최종 빌드의 소스와 DLL 해시를 기록하고 일치하는 빌드만 실행했습니다.

내부 검사 302개가 통과했습니다. 프로젝트 49개 스크립트의 일반 생성·복원 코드 일치를 확인했고, 프리팹 8개 체크포인트·GC·세 장면 전환과 UI API 20개 체크포인트의 상태 분리·외부 클릭 콜백을 새 Unreal 실행으로 회귀 대조했습니다. Unity 복원 소스 49개는 이전 실제 실행본과 SHA-256이 같아 해당 원본/복원 Unity 캡처를 재사용했습니다. 기존 실제 Unity 250프레임 원본·복원 캡처와 새 Unreal 250프레임 대조도 통과했습니다. 이 회귀의 Unity 실행을 모두 이번에 새로 수행했다는 뜻은 아닙니다.

적용 안내: 지원 Canvas·Button 타입을 사용하는 스크립트 변환에 자동 적용합니다. 함수 입력·반환과 역변환 타입을 유지하며, 참조 별칭·복제 보일러플레이트가 바뀌면 역변환을 차단합니다. 이 Unity 버전의 중복 추가 시험에서는 한 객체의 Canvas와 Button이 각각 1개로 유지됐습니다.

남은 범위: 이번 실제 실행 버전은 Unity 6000.0.83f1과 Unreal 5.8입니다. Graphic·RectTransform 전용 속성 및 다른 UI 타입, UI와 GameObject/Transform의 혼합 비교, 모든 엔진 버전, 물리 궤적·렌더링 동등성 및 전체 프로젝트 포팅 완료는 지원·검증 완료로 표시하지 않습니다. 사용자 원본 60개 파일은 해시가 일치합니다. 기존 안전 실행기의 잠금·방화벽 검사·시간 제한을 유지했고 다른 프로젝트 프로세스나 전체 방화벽 정책은 변경하지 않았습니다.

Owner 필드 충돌 자동 대응 — 구현·실제 왕복 검증 완료

2026-10-24T02:31:07.281692+09:00. 기존 Unreal 빌드 로그에서 사용자 C# Owner 필드가 AActor.Owner와 충돌해 UHT가 거부한 것을 확인했습니다. 이제 C# 필드명은 Owner로 보존하고, 생성 C++의 필드와 참조 접근만 EM_Field_Owner로 대응합니다. 인수·지역 변수의 이름은 구분하며, 상속된 필드와 다른 컴포넌트의 필드 읽기·쓰기도 대응합니다.

Unity 6000.0.83f1 원본 → Unreal 5.8 실제 게임 실행 → 복원 Unity를 새로 실행해 삭제·복제 7프레임의 17개 값을 대조했습니다. Unreal 실제 어댑터 실행에서는 장면 참조 가져오기·참조 검증·내보내기·프리팹 상태 스냅샷의 Owner 키가 유지되고, 기본 AActor.Owner가 변경되지 않는 것을 확인했습니다. 내부 검사 305개가 통과했습니다.

기존 49개 스크립트의 생성 헤더와 복원 C#은 이전 실제 검증본과 동일한지 대조했습니다. 해당 전체 프로젝트의 엔진 실행을 이번 단계에서 다시 수행했다는 뜻은 아닙니다. 사용자 원본 60개 파일은 해시가 일치합니다. 이 단계는 Owner 필드 충돌에 대한 지원이며, 모든 Unreal 예약 필드·모든 엔진 버전·전체 프로젝트 포팅 완료를 의미하지 않습니다.

Canvas·Button 동적 추가·재추가 — 구현·실제 왕복 검증 완료

2026-10-24T02:57:33.265882+09:00. 지원 스크립트에서 GameObject.AddComponent<Canvas>()와 AddComponent<Button>()를 변환합니다. 빈 객체에서 생성하는 경우와 장면에 기존 UI 컴포넌트가 있는 경우를 각각 Unity 6000.0.83f1 → Unreal 5.8 → 복원 Unity에서 실행했습니다. 기존 UI 재추가 중 삭제 콜백의 자체 제거 후 캡처 값 접근 문제를 실제 중단 로그로 확인해 수정했습니다. 콜백에 필요한 값을 먼저 복사하며 기존 UI 삭제 헤더의 역변환 호환도 유지합니다. 두 시나리오의 실제 캡처 6개에서 10프레임·18개 값이 일치했습니다.

사용 동작확인한 결과
동일 종류 중복 추가이 버전의 실제 Unity와 같이 null 반환
Destroy 후 다음 프레임 재추가새 인스턴스 생성, 이전 참조는 계속 null 판정, 새 참조와 구분
enabled / interactable / gameObject기본값·설정값과 소유 객체 대응 유지
생성·재추가 후 GameObject 복제복제본의 UI 참조 분리와 속성 상태 유지
삭제된 이전 참조를 다시 삭제새 컴포넌트에 영향을 주지 않음

적용: 지원되는 Canvas·Button 동적 추가를 사용하는 스크립트 변환 시 자동 적용하며, 역변환 시 원래 AddComponent 호출로 복원합니다. 내부 검사 308개와 기존 49개 스크립트를 수정 런타임으로 다시 생성·빌드하고, 새 Unreal 실행으로 프리팹 8개 체크포인트·GC·세 장면 전환 및 UI API 20개 체크포인트 및 기존 250프레임을 회귀 대조했습니다. 복원 Unity 소스 49개의 SHA-256이 이전 실제 실행본과 같아 기존 Unity 원본·복원 캡처를 재사용했습니다. Unity 실행을 전부 이번에 다시 수행했다는 뜻은 아닙니다. 사용자 원본 60개 파일의 해시를 확인했습니다.

남은 범위: 이번 검증은 기본 Canvas·Button의 참조·상태·삭제·복제입니다. Graphic·텍스트·이미지 등 다른 UI 컴포넌트의 동적 생성, RectTransform 전용 속성, 새 위젯의 렌더링·사용자 클릭 동등성, 모든 엔진 버전 및 전체 프로젝트 포팅 완료를 검증한 것은 아닙니다.

Canvas·Button 이름 변경 — 소유 객체 대응 수정·실제 검증 완료

2026-10-24T03:14:53.017911+09:00. 동적 UI 컴포넌트의 name을 변경할 때 내부 참조 객체만 바뀌고 소유 GameObject 이름은 유지되던 차이를 실제 Unreal 게임 모드에서 재현했습니다. 수정 전 8개 관찰 행 중 3개가 Unity 원본·복원본과 달랐으며, 수정 후 기존 UI·동적 UI 모두 일치했습니다.

Unity 스크립트확인한 결과
Canvas.name = 문자열 상수소유 GameObject 이름 변경
Button.name = 문자열 상수같은 소유 GameObject 이름 변경
복제한 객체의 Canvas.name 변경복제본 이름만 변경하고 원본 이름 유지

UI 종류별 이름 변경과 복제 단계를 기존·동적 UI 두 시나리오에서 실행했으며, 한글과 공백을 포함한 이름을 확인했습니다. Unity 원본·복원 C#은 한 번의 실제 Unity 실행에서 각각 실행했습니다. 수정 후 복원 C# 바이트가 해당 실행본과 같음을 확인하고 캡처를 재사용했으며, 새 Unreal 게임 모드 실행 결과를 대조했습니다. 초기 편집기 Python 호출은 종료 오류로 성공 처리하지 않았고, 실제 검증은 정상 종료한 게임 모드 실행을 사용했습니다. 초기 종료 오류의 원인은 미확인으로 남아 있습니다.

동적 UI 생성·삭제·재추가·복제의 두 게임 모드 회귀와 내부 검사 312개가 통과했습니다. 기존 49개 스크립트의 생성 헤더·복원 C#은 직전 실제 검증본과 같음을 대조했습니다. 전체 49개 프로젝트의 엔진 실행을 이번에 다시 수행했다는 뜻은 아닙니다. 이전 UI 이름 변환 헤더는 백엔드 메타데이터를 보존해 역변환할 수 있으며, 새 헤더의 소유 객체 대응 코드를 제거하거나 이전 방식으로 바꾸면 역변환을 차단합니다. 사용자 원본 60개 파일은 해시가 일치합니다.

범위: 살아 있는 지원 Canvas·Button 참조에 대한 name 문자열 상수 대입을 검증했습니다. 이름 읽기·동적 문자열 연산·삭제된 참조의 예외 동등성·다른 UI 타입·렌더링·클릭 동등성·모든 엔진 버전·전체 프로젝트 포팅 완료는 검증하지 않았습니다.

C++ Runtime Actor 고정 이벤트 — 단일 장면 실제 왕복 검증 완료

2026-10-24T04:00:39.618693+09:00. 인수 없는 FixedUpdate와 상속·명시적 부모 호출, 이벤트 내부 Time.deltaTime 및 Time.fixedDeltaTime 읽기를 변환합니다. 고정 이벤트를 Unreal의 일반 Actor Tick보다 먼저 공통 시계에서 배치하며, 활성·비활성·삭제 대기 상태를 확인합니다. FixedUpdate가 단순 Blueprint 사용자 이벤트로 잘못 선택되지 않도록 C++ Runtime Actor 백엔드를 사용합니다. Blueprint 그래프 자체의 고정 이벤트 노드를 구현한 것은 아닙니다.

렌더 프레임률 / 고정 간격 요청실제 대조
100 FPS / 0.02초고정 호출 없는 렌더 프레임 포함
50 FPS / 0.02초시작 위상과 시간 0 호출 포함
30 FPS / 0.02초한 프레임의 여러 고정 호출
30 FPS / 0.01초한 프레임의 3~4회 고정 호출과 정수 경계

각 조합을 Unity 6000.0.83f1 원본 → Unreal 5.8 → 복원 Unity에서 실행한 실제 캡처 12개로 대조했습니다. 조합마다 24프레임·16개 값을 확인했고, 정수 상태·호출 순서 코드는 정확히 일치했습니다. 시간 누적 등 부동소수점 값은 0.000002 이내 허용 범위를 적용했습니다. 상속된 FixedUpdate, 초기 Start 선행, OnEnable/OnDisable, GameObject 활성 전환, 런타임 AddComponent·삭제를 포함합니다.

부동소수점 누적으로 일부 프레임의 호출이 달랐던 결과를 보존하고 정수 시계로 수정했습니다. 실제 Unity 기록에서 기본 시간 단위 141,120,000틱/초와 요청 0.01초의 실제 고정 간격 1,411,199틱을 확인했습니다. 시간 단위 API는 Unity 6.0 공식 RationalTime 문서를 함께 확인했습니다. 정수 시계 수정 후에도 복원 C# 4개 파일의 SHA-256이 실제 Unity 실행본과 같았습니다.

프로젝트의 고정 간격·틱 값을 스크립트 Actor에 전달하고, Unreal 장면 저장·다시 열기 후 컴포넌트 참조·실행 순서·설정값이 유지되는 것을 실제 어댑터로 확인했습니다. 잘못된 고정 간격 5종은 Actor 생성 전에 차단했습니다. 테스트 중 발견한 다른 컴포넌트 정수 필드 ++/--의 잘못된 네이티브 대입식도 수정했습니다. 내부 검사 319개가 통과했습니다. 기존 49개 스크립트의 생성 헤더·복원 결과는 이전 실제 검증본과 같음을 확인했으며, 이 단계에서 기존 전체 프로젝트 엔진 실행을 다시 수행했다는 뜻은 아닙니다. 사용자 원본 60개 파일을 보존했습니다.

남은 범위: 이번 단계는 단일 장면의 고정 스크립트 이벤트입니다. 장면 전환 중 고정 시계 연속성, 임의 가변 프레임률·긴 시간 실행, 시간 배율의 추가 범위(아래 시간 배율 검증 절 참고), 실행 중 fixedDeltaTime 변경, 물리 서브스텝과 스크립트의 완전한 교차 실행·Rigidbody API·궤적 동등성·모든 버전·전체 프로젝트 포팅 완료는 검증하지 않았습니다.

고정 이벤트 시계 — 3개 장면 실제 왕복 검증 완료

2026-10-24T04:41:56.497581+09:00. C++ Runtime Actor의 고정 업데이트 시계를 GameInstance 수명으로 유지하도록 수정했습니다. 장면 정리 때 Actor 등록은 해제하되 누적 시간은 이어집니다. 설치된 Unreal 5.8 TickTaskManager.cpp에서 초기 프레임 0의 Actor Tick 방문 값과 실행 제외 조건을 확인했고, 실제 실행에서 고정 콜백만 먼저 진행하던 초기 준비 프레임을 제외했습니다.

Unity 6000.0.83f1 원본 → Unreal 5.8 게임 실행 → 복원 Unity를 실제 실행해 100 FPS / 요청 고정 간격 0.02초, 30 FPS / 0.01초의 각 3장면·26프레임·7개 값을 대조했습니다. 별도로 고정 스크립트가 없는 중간 장면을 5프레임 거치는 왕복도 대조했습니다. 빈 장면에서 마지막 장면으로 이동하는 호출은 두 엔진의 테스트 관찰기가 수행하며, 이 호출 자체가 사용자 스크립트 변환 검증이라는 뜻은 아닙니다. 장면별 Start 선행·고정 호출 횟수·초기 위상·누적 시간이 일치했습니다. 시간 값 허용 오차는 0.000002이며 나머지 상태는 정확히 일치했습니다.

이전 단일 장면 4조건을 새 네이티브 빌드로 각각 재실행해 기존 Unity 캡처와 대조했습니다. 해당 Unity 원본·복원 캡처는 이전 단계의 실제 실행 증거를 재사용했습니다. 내부 검사 322개와 기존 49개 스크립트 생성·복원 대조가 통과했으며 사용자 원본 60개 파일의 해시를 확인했습니다. 구형 시계 헤더의 역변환을 유지하되 서로 다른 시계 버전이 섞인 번들은 명시적으로 거부합니다.

남은 검증: 임의 가변 프레임률·장시간 실행·비기본 timeScale·실행 중 fixedDeltaTime 변경·물리 서브스텝·Rigidbody 궤적 동등성·모든 엔진 버전 및 전체 프로젝트 포팅 완료는 검증하지 않았습니다.

실행 중 시간 배율·정지·재개 — 실제 왕복 검증 완료

2026-10-24T04:58:56.779659+09:00. C++ Runtime Actor에서 Time.timeScale 읽기와 단순 대입을 지원합니다. 변환된 프로젝트의 WorldSettings에 배율을 적용하고 최소 배율 0을 허용하여, 정지 중에도 일반 Update는 0의 deltaTime으로 계속 호출되며 고정 이벤트와 시간 누적은 멈춥니다. 음수 대입은 무시합니다. 설치된 Unreal 5.8의 WorldSettings.cpp·LevelTick.cpp를 확인했고, Unity 6.0 공식 문서의 다음 프레임 반영·정지·음수 처리 규칙을 실제 실행으로 대조했습니다.

적용: 지원 스크립트에 Time.timeScale = 0f; 또는 0.5f, 2f, 1f 같은 단순 대입이 있으면 네이티브 시간 배율 런타임을 포함합니다. 역변환 시 원래 Time.timeScale 읽기·대입으로 복원합니다. 프로젝트 초기 배율 지원은 아래 프로젝트 시간 설정 검증 절을 참고하세요. 실행 중 fixedDeltaTime 변경과 복합 대입은 아직 명시적으로 거부합니다.

Unity 6000.0.83f1 원본 → Unreal 5.8 게임 실행 → 복원 Unity를 100 FPS와 30 FPS에서 각각 실행했습니다. 두 스크립트가 1→0.5→0→2→1 배율과 음수 대입을 관찰하는 실제 캡처 6개·각 22프레임·13개 값을 대조했습니다. 변경 프레임의 deltaTime 유지와 다른 스크립트의 즉시 배율 읽기, 네 프레임 정지 중 고정 호출·시간 누적 중단, 재개 후 고정 호출을 확인했습니다. 정수·배율 상태는 정확히 일치했고 시간 허용 오차는 0.000002입니다. 실시간 진단용 unscaledDeltaTime 열은 캡처 방식이 달라 대조하지 않았으며, 이 API의 변환을 구현했다는 뜻은 아닙니다.

새 Unreal 모듈에서 기존 단일 장면 고정 이벤트 4조건과 장면 전환 3조건을 다시 실행해 기존 실제 Unity 캡처와 대조했습니다. 내부 검사 327개와 기존 49개 스크립트 생성·복원 대조가 통과했습니다. 전체 49개 프로젝트의 엔진 실행을 이번에 다시 수행했다는 뜻은 아닙니다. 원본 60개 파일의 해시를 확인했습니다.

남은 범위: 프로젝트 시간 설정의 추가 범위(아래 검증 절 참고)·배율을 바꾼 상태의 프리팹 자산 생성, 임의 가변 프레임·장시간 실행·극단 배율·비유한 값, 물리·애니메이션·오디오 동등성, 모든 엔진 버전과 전체 프로젝트 포팅 완료는 이번 단계에서 검증하지 않았습니다.

프로젝트 초기 시간 배율·정지 중 객체 수명·장면 전환 — 구현·실제 왕복 검증 완료

2026-10-24T05:35:49.731087+09:00. 프로젝트 초기 timeScale이 1이어야 한다는 제한을 제거했습니다. 초기 0·0.5·1과 실행 중 0·0.5·2·1을 Unity 6000.0.83f1 원본 → Unreal 5.8 게임 실행 → 복원 Unity에서 확인했습니다. 스크립트가 없는 장면에도 시간 설정을 적용하도록 공통 런타임 부트스트랩을 생성합니다. Unreal에서 실제 내보낸 시간 설정 JSON을 복원 Unity가 읽고 TimeManager.asset에 반영하는 경로를 검사했습니다.

Unity 항목Unreal 대응과 복원
프로젝트 m_TimeScale / Time.timeScale 초기값WorldSettings의 EMTimeScale 태그로 저장하고 맵 재열기 후 확인합니다. 월드 틱 시작 전에 시간 배율을 적용하며, 역변환 시 실제 저장값을 Unity 시간 설정에 복원합니다.
실행 중 Time.timeScale 대입게임 인스턴스 수명의 현재 배율로 유지합니다. 새 장면의 초기 콜백에서도 이전 배율을 읽습니다.
정지 중 new GameObject·AddComponent·Instantiate·Destroy객체·컴포넌트 생성과 복제, 시작 콜백, 참조 구분과 삭제를 진행하며 일반 업데이트의 deltaTime은 0입니다.
초기 0배속의 고정 이벤트이 테스트의 실제 Unity 시작 단계에서 시간 0 고정 콜백이 한 번 실행된 것을 확인했습니다. 해당 시작 위상을 보존하고 이후 정지 프레임에서는 고정 시간을 누적하지 않습니다.

동적 객체·세 장면 전환은 100 FPS와 30 FPS, 초기 배율 세 종류를 포함한 네 조건에서 각 32프레임·54개 값을 대조했습니다. 실제 캡처 12개에서 초기 Awake·Start 배율, 고정 호출, 정지 중 생성·복제·삭제·참조 무효화, 컴포넌트 필드와 업데이트 횟수가 일치했습니다. 사용자 스크립트가 없는 빈 장면은 초기 0·0.5의 실제 캡처 6개·각 5프레임으로 확인했습니다. 정수·배율 상태는 정확히 일치했고 시간 허용 오차는 0.000002입니다.

수정 전 초기 0배속의 두 프레임에서 고정 호출 수와 누적 시간 네 값이 달랐던 캡처를 보존했습니다. 고정 시계 버전 3으로 수정했으며 버전 1·2 헤더의 역변환도 유지합니다. 시간 배율 런타임은 버전 2를 사용하고 이전 배포본의 버전 1 역변환을 지원합니다. 서로 다른 실행 버전의 생성 헤더를 섞으면 명시적으로 거부하므로, 프로젝트의 생성 헤더는 같은 버전으로 갱신합니다.

잘못된 배율·고정 간격·최대 시간 설정 여섯 종류를 양쪽 실제 어댑터에서 설정 변경 전에 거부했습니다. 네 맵을 저장·재열어 초기 설정을 확인했습니다. 새 네이티브 빌드로 기존 고정 이벤트 4조건과 배율 변경 2조건을 다시 실행해 이전 실제 Unity 캡처와 대조했습니다. 내부 검사 332개와 기존 49개 스크립트 생성·복원 대조가 통과했고 사용자 원본 60개 파일의 해시를 확인했습니다.

검증 범위: 이번 테스트는 실제 어댑터 함수·생성 C++·게임 실행을 연결한 전용 복사본 검증입니다. 전체 프로젝트 CLI 파이프라인과 기존 49개 프로젝트의 엔진 실행을 이번 단계에 전부 다시 수행했다는 뜻은 아닙니다. 프리팹의 추가 범위(아래 프리팹 검증 절 참고)·물리 궤적·애니메이션·오디오 동등성, 극단 배율·임의 가변 프레임·긴 중단, 실행 중 fixedDeltaTime 변경·unscaledDeltaTime 변환·모든 버전 및 전체 프로젝트 포팅 완료는 남아 있습니다.

프리팹 자산 — 배율 변경·정지 상태의 실제 왕복 검증 완료

2026-10-24T06:11:53.268918+09:00. 활성·비활성 일반 프리팹 자산 두 개를 실제 Unity PrefabUtility로 저장하고, 제품의 자산 내보내기·런타임 프리팹 스테이징·스크립트 컴포넌트 연결 함수를 사용해 Unreal 프로토타입으로 가져왔습니다. 부모/자식의 두 컴포넌트가 자기 GameObject·서로의 컴포넌트·상대 GameObject를 가리키는 참조를 포함합니다. 저장한 Unreal 맵을 다시 열어 다섯 컴포넌트의 소유 객체와 직렬화 참조를 확인했습니다.

Unreal의 실제 필드·참조를 제품 내보내기 함수로 다시 읽어 프리팹 정의 패키지를 구성하고, 복원 Unity의 프로젝트 가져오기 함수로 프리팹 두 개와 장면을 실제 복원했습니다. 원본·복원 클래스가 한 개인 테스트 프로젝트에서 공존하도록 테스트에서 클래스명과 프리팹 자산 ID에 별도 접두사/접미사를 사용했습니다. 사용자 원본은 수정하지 않았습니다.

상황확인한 결과
활성 프리팹 두 인스턴스 생성Awake의 즉시 실행과 반환 시 Start 값, 내부 참조 재연결·인스턴스 분리
정지 중 프리팹 생성·실행 중 객체 복제객체 수명 콜백과 일반 업데이트 유지, 고정 시간 누적 중단
비활성 프리팹 생성 후 정지 중 활성화생성 시 Awake 보류, 활성화 시 자기·서로 참조가 연결된 상태로 초기화
비활성/재활성·삭제·배율 2로 재개각 인스턴스의 호출 횟수·상태·삭제된 참조 구분과 고정 업데이트 재개
Unreal의 숨겨진 프리팹 프로토타입원본 프리팹처럼 사용자 생명주기·업데이트를 실행하지 않음

Unity 6000.0.83f1 → Unreal 5.8 → 복원 Unity를 100/30 FPS의 초기 0.5배속과 100 FPS 초기 정지의 세 조건에서 실행했습니다. 실제 캡처 9개에서 각 24프레임·158개 값을 대조했습니다. 정수·배율·참조 상태는 정확히 일치했고 시간 허용 오차는 0.000002입니다. 기존 고정 이벤트 네 조건·시간 배율 두 조건·배율 변경 중 장면 전환 두 조건을 새 네이티브 빌드로 다시 실행해 이전 Unity 캡처와 대조했습니다.

검증 중 유효한 C# 지역 변수명 template을 C++ 예약어라는 이유로 거부하던 제한을 발견했습니다. 이미 EM_local_/EM_arg_ 접두사로 출력하는 지역 변수·인수에는 해당 C++ 예약어를 허용하도록 수정했습니다. 실제 프리팹 스크립트의 template 지역 변수를 네이티브로 컴파일했고, 인수·지역 변수의 원본/복원 C# 실행 결과도 대조했습니다. 필드·메서드·클래스 이름의 모든 예약어 충돌을 해결했다는 뜻은 아닙니다. 초기 정지에서 2배속으로 재개할 때 고정 콜백이 한 프레임 빨랐던 56개 상태/시간 차이도 보존했습니다. 실제 Unity 정수 시간에서 렌더 간격 1,411,199틱이 2배속에서 2,822,398틱으로 진행되는 것을 확인했습니다. 렌더 시간을 먼저 양자화한 뒤 이번 프레임 배율을 적용하는 고정 시계 버전 4로 수정했으며 이전 버전 1~3 헤더의 역변환을 유지합니다. 내부 검사 334개와 기존 49개 스크립트 생성·복원 대조가 통과했습니다. 원본 60개 파일의 해시를 확인했습니다.

범위: 두 일반 프리팹의 스크립트·계층 참조·활성 상태·수명과 시간 이벤트를 검증했습니다. 테스트용 패키지 분리/ID 정규화를 포함하며 전체 프로젝트 CLI 파이프라인을 이번에 전부 다시 실행한 것은 아닙니다. 배율 변경 중 물리·애니메이션·UI 프리팹의 완전한 동등성, Variant/Model·중첩 프리팹, 극단 배율·임의 가변 프레임·모든 엔진 버전 및 전체 프로젝트 포팅 완료는 남아 있습니다.

LateUpdate — 구현·실제 왕복 검증 완료

2026-10-24T06:28:06.500692+09:00. 지원하는 MonoBehaviour의 인수 없는 LateUpdate를 C++ Runtime Actor의 후기 업데이트로 변환합니다. 모든 Actor Update가 끝난 뒤 월드의 후기 실행 단계에서 호출하며, 스크립트 실행 순서와 상속·명시적 부모 호출을 유지합니다. 일반 Blueprint Custom Event로 생성해 호출되지 않는 상태를 막기 위해 네이티브 백엔드를 사용합니다. Blueprint 그래프의 LateUpdate 노드를 구현한 것은 아닙니다.

Unity 소스대응·확인한 동작
protected virtual void LateUpdate()이번 프레임의 deltaTime을 받는 EM_LateUpdate로 생성하고 실제 월드 후기 단계에서 호출
override LateUpdate / base.LateUpdate()가상 디스패치와 부모/자식 상태·호출 순서 보존
Update 중 enabled=true / SetActive(true)일반 Update는 다음 프레임부터 받는 경우에도 같은 프레임의 LateUpdate 실행
Update 중 AddComponentStart 뒤 첫 LateUpdate 실행, 일반 Update는 다음 프레임부터 실행
시간 배율 0 / 삭제·비활성정지 중 후기 콜백은 deltaTime 0으로 유지하고 비활성·삭제 대상은 제외

Unity 6000.0.83f1 원본 → Unreal 5.8 게임 실행 → 복원 Unity를 100/30 FPS에서 각각 실제 실행했습니다. 캡처 6개에서 각 24프레임·25개 값을 대조했고, 정수 상태·호출 순서 코드는 정확히 일치했습니다. deltaTime·누적 시간 허용 오차는 0.000002입니다. 서로 다른 실행 순서의 Actor를 함께 실행해 모든 일반 업데이트 뒤에 후기 업데이트가 배치되는 것을 확인했습니다.

새 네이티브 모듈로 기존 고정 이벤트 네 조건·시간 배율 두 조건·장면 전환 두 조건을 다시 실행하고 이전 실제 Unity 캡처와 대조했습니다. 내부 검사 338개와 기존 49개 스크립트의 생성 헤더·복원 C# 대조가 통과했습니다. LateUpdate를 사용하지 않는 기존 생성 헤더는 그대로 유지합니다. 후기 실행 코드나 메타데이터를 제거하거나 실행 단계를 바꾸면 역변환을 거부합니다. 사용자 원본 60개 파일의 해시를 확인했습니다.

남은 범위: 이번 검증은 단일 장면의 후기 이벤트·상속·추가·재활성·정지·삭제입니다. LateUpdate 안에서 추가/삭제/장면 전환을 요청하는 모든 조합, 프리팹·UI·애니메이션·물리와의 후기 실행 교차 동등성, 모든 버전 및 전체 프로젝트 포팅 완료는 검증하지 않았습니다. 전체 프로젝트 CLI와 기존 49개 프로젝트의 엔진 실행을 이번에 전부 다시 수행했다는 뜻은 아닙니다.

LateUpdate 내부 객체 변경·장면 전환 — 실제 왕복 검증

2026-10-24T06:53:39.331653+09:00. Unity 6000.0.83f1 → Unreal 5.8 네이티브 Actor → 복원 Unity를 100/30 FPS에서 실제 실행했습니다. 후기 이벤트의 생성·복제·활성 전환·삭제는 각 24프레임·24개 값, 세 장면 전환은 각 32프레임·57개 값을 대조했습니다. 두 시나리오군의 원본·네이티브·복원 캡처는 총 12개입니다. 정수 상태와 호출 순서 코드는 정확히, 부동소수 시간은 오차 0.000002 이내로 대조합니다.

요청 시점실제 대응
일반 Update에서 생성·재활성기존에 확인한 같은 프레임 LateUpdate 동작을 유지합니다.
LateUpdate에서 생성·복제새 객체의 Start와 일반 Update는 다음 프레임에 실행합니다. 복제된 직렬화 상태는 보존하며 Start 실행 여부와 구분합니다.
LateUpdate에서 다시 활성화후기 실행 시작 시 대상 목록을 고정해 같은 프레임에 추가 호출하지 않습니다. 실행 중 비활성·삭제한 대상은 제외합니다.
LateUpdate에서 DestroyOnDisable은 요청 시 반영하고, 다음 업데이트 전 삭제·OnDestroy를 처리합니다. 후기 관측 시 아직 유효한 참조와 다음 프레임의 무효 참조를 구분합니다.
LateUpdate에서 단일 장면 전환세 장면을 순서대로 이동하면서 생성·복제·삭제, 시간 배율 0·0.5·1·2와 고정 이벤트 상태를 비교했습니다.

첫 네이티브 비교에서 71개 상태 차이를 확인한 뒤, 후기 실행 대상 스냅샷과 다음 프레임 시작·삭제 예약을 수정했습니다. Windows 줄바꿈으로 판별 함수가 빠지는 생성 오류도 수정했습니다. 후기 런타임 버전 2를 기록하고, 기존 버전 1의 역변환은 유지하되 버전 혼합·알 수 없는 버전·예약 코드 변경을 거부합니다.

현재 네이티브 모듈로 고정 이벤트 4조건, 시간 배율 2조건, 일반 장면 전환 2조건, 이전 LateUpdate 2조건, 실제 프리팹 기반 실행 2조건 등 12개 회귀 캡처를 이전 실제 Unity 기준값과 대조했습니다. 내부 검사 345개와 기존 49개 스크립트 헤더·복원 대조도 통과했습니다. 사용자 원본 60개 파일은 변경하지 않았습니다.

범위와 남은 작업: 이번 단계는 지원 스크립트 문법의 후기 생명주기와 세 장면의 단일 로드 검증입니다. Blueprint 그래프의 후기 실행 노드, Additive·비동기 장면 로드, 모든 후기 이벤트의 UI·물리·애니메이션·프리팹 교차 조합, 모든 엔진 버전과 임의 프로젝트의 완전 자동 포팅은 완료되지 않았습니다. 전체 프로젝트 CLI 파이프라인 전체를 이번에 새로 실행한 결과로 표시하지 않습니다. 보안 실행 제한과 고정 경로·방화벽 사전 확인을 유지합니다.

Start·OnEnable 교차와 같은 후기 이벤트의 활성 토글 — 실제 왕복 검증

2026-10-24T07:20:43.064727+09:00. LateUpdate를 포함하는 지원 스크립트 묶음에서 Start·OnEnable 중 추가하는 객체와 같은 후기 이벤트 안의 enabled=false→true, SetActive(false)→true를 검증했습니다. Unity 6000.0.83f1 → Unreal 5.8 네이티브 Actor → 복원 Unity를 100/30 FPS에서 실제 실행하고, 총 6개 캡처의 각 24프레임·47개 정수 상태값과 공유 호출 순서 코드를 정확히 대조했습니다.

Unity 원본 동작변환 대응
같은 LateUpdate에서 껐다 켬활성화 시 현재 후기 실행 프레임을 표시해, 처음부터 대상 목록에 있던 컴포넌트도 그 프레임에 다시 호출하지 않습니다.
Update 중 생성한 부모의 Start가 자식을 추가업데이트 후 시작 대기열의 첫 묶음만 먼저 처리하고, 그 안에서 추가된 자식의 Start는 자신의 첫 후기 호출 직전에 실행합니다. 부모·자식의 콜백 순서를 보존합니다.
LateUpdate 중 생성한 부모의 다음 프레임 Start가 자식을 추가업데이트 전 시작 대기열을 처리해 자식의 초기화와 첫 일반 Update가 한 프레임 늦어지지 않도록 합니다. AddComponent 반환 시점에는 Start가 아직 실행되지 않은 상태를 유지합니다.
OnEnable에서 객체 추가·기존 객체 삭제요청한 실행 단계에 따라 시작·삭제를 예약하고 후기 관측 시 상태와 다음 프레임의 상태를 구분합니다.
뒤늦게 낮은 순서 Actor를 만든 뒤 다른 소유자를 삭제기존의 높은 순서 Actor에도 새 선행 조건을 연결해 일반 Update 순서가 바뀌지 않도록 합니다.

초기 비교의 64개 차이를 근거로 후기 런타임 버전 3을 구현했습니다. 횟수뿐 아니라 호출 순서 코드도 비교했고, 업데이트 후 시작 처리의 세대 구분과 기존 Actor의 실행 선행 조건 누락을 추가로 수정했습니다. 버전 1·2 헤더의 역변환을 유지하며 시작 대기열·재활성 표식·선행 조건 코드 변경과 실행 버전 혼합은 거부합니다.

새 네이티브 모듈로 고정 이벤트 4조건, 시간 배율 2조건, 일반 장면 전환 2조건, 이전 후기 이벤트 2조건, 프리팹 2조건, 후기 객체 변경 2조건, 후기 장면 전환 2조건 등 16개 회귀 캡처를 이전 실제 Unity 기준값과 대조했습니다. 내부 검사 349개와 기존 49개 스크립트 헤더·복원 대조가 통과했습니다. 실제 실행한 C# 및 빌드한 생성 헤더가 현재 변환기의 출력과 일치하는지 확인했고, 사용자 원본 60개 파일은 유지했습니다.

적용 범위와 남은 검증: 이 시작 대기열은 LateUpdate를 포함하는 네이티브 스크립트 묶음에 적용됩니다. 후기 이벤트 없는 묶음의 중첩 Start, 더 깊은 추가 연쇄, 높은 순서 스크립트에서 낮은 순서 대상의 활성 상태를 바꾸는 교차, UI·물리·애니메이션의 모든 조합과 임의 프로젝트·모든 버전의 완전 자동 포팅은 별도 검증이 남아 있습니다. 전체 프로젝트 CLI 파이프라인 전체를 이번 단계에 새로 실행한 것으로 표시하지 않습니다. 보안 실행 제한·원본 보존·독점 실행 대여를 유지합니다.

53개 스크립트 통합 프로젝트 — 실제 프로젝트 파이프라인 왕복 검증

2026-10-24T08:05:52.826994+09:00. 기존 49개 스크립트의 테스트 프로젝트에 후기 생명주기 사례 4개를 추가한 개인 복사본으로, 프로그램이 사용하는 ResourcePorting.RunAsync의 Unity → Unreal → Unity 프로젝트 경로를 실제 실행했습니다. 장면 20개·프리팹 정의 25개를 포함한 45개 단위와 53개 스크립트 클래스를 대상으로 가져오기·저장·재열기·참조 검사를 양방향으로 수행했습니다. 사용자 원본 프로젝트는 수정하지 않았습니다.

검사실행 근거
통합 스크립트프로젝트 전체에서 수집한 53개 클래스를 네이티브로 빌드했습니다. 실제 생성·빌드한 헤더와 복원 C#이 현재 변환기의 출력과 일치하는지 확인했습니다.
실제 게임 실행원본 Unity 55프레임, Unreal 56프레임, 복원 Unity 55프레임을 캡처했습니다. Unreal의 초기 준비 프레임은 사용자 스크립트 실행 프레임과 구분합니다.
후기 생명주기 교차통합 프로젝트 안에서 40프레임·47개 정수 상태 및 공유 호출 순서 코드를 원본·네이티브·복원 모두 정확히 대조했습니다.
프리팹·GC·장면 전환실제 프리팹 생성·삭제 8개 체크포인트, 내부 참조·공유 메시/재질·계층, 삭제 후/GC 후의 객체·Transform 정체성, 세 장면 실행 순서를 확인했습니다.
복원 자산 재내보내기복원 Unity를 다시 실제 내보내기하여 45개 단위·133개 노드, 텍스처 픽셀, 메시·재질 데이터, 프리팹 소속과 스크립트 GUID·실행 순서를 대조했습니다.
기존 동작 회귀기존 실제 Unity 250프레임 시간·클릭 입력으로 새 네이티브 프로젝트의 장면을 재실행하고, 상태·UI 콜백·애니메이션 및 물리 허용 범위를 검사했습니다. 내부 검사 354개도 통과했습니다.

이번 통합 경로에서 두 누락을 수정했습니다. 프로젝트 사전 검사도 스크립트 변환기가 이미 지원하던 LoadScene(계산된 int 인덱스)를 허용합니다. 알려진 상수는 상수 식·지역 상수·음수까지 의미 분석으로 빌드 장면 범위를 검사하며, 동적 식은 사전 검사에서 실행하지 않습니다. 실행 시 계산한 인덱스의 유효성은 런타임에서 확인해야 합니다. 또한 첫 프로젝트 단위에 스크립트가 없더라도 병합된 프로젝트 스크립트가 있으면 복원을 건너뛰지 않도록 수정했습니다. 빈 첫 단위의 GUID·실행 순서 복원은 엔진 없는 검사로 별도 검증했습니다.

범위: 이 결과는 위 테스트 프로젝트의 지원 데이터·53개 클래스의 생성/복원과 실제 실행 체크포인트를 검증한 것입니다. 모든 클래스의 모든 분기 실행, 임의의 사용자 게임, 모든 Unity/Unreal 버전, 화면 렌더링 동등성 및 물리 궤적 동등성의 완료를 뜻하지 않습니다. 관측 전용 플러그인은 테스트 도구이며 포팅 대상 게임 코드로 계산하지 않았습니다. 후기 이벤트 없는 묶음의 중첩 시작 대기열, 더 깊은 연쇄와 교차 활성 변경 등은 계속 검증할 항목입니다.

LateUpdate 없는 스크립트의 중첩 생성·시작 대기열

2026-10-24T09:09:59.323655+09:00. Start·OnEnable에서 자식과 손자를 생성하는 다섯 클래스 묶음을 Unity → 네이티브 Actor → 복원 Unity로 실행했습니다. 100/30 FPS 각각 24프레임·65개 상태 값을 정확히 대조했습니다. 첫 고정 업데이트 횟수에 따른 시작 단계, Update 뒤 시작된 부모가 생성한 자식의 프레임 끝 시작, 재활성화와 부모 삭제 후 상태를 확인했습니다.

이벤트 순서 검사는 클래스 간 Update 순서와 개별 Start·활성 변경을 구분합니다. 동일 클래스 인스턴스들의 Update 순서에는 의존하지 않으며, 객체별 호출 횟수와 참조·상태는 별도로 정확히 대조합니다. 이는 Unity 6.0이 같은 실행 순서 값 사이의 순서를 보장하지 않는 계약에 따른 것입니다. 같은 클래스 객체 사이의 미정의 호출 순서에 의존하는 게임 로직까지 동일한 실행 순서를 보장하지 않습니다. 과거 전체 인스턴스 순서 체크섬의 차이와 진단 로그는 테스트 결과에 보존했습니다.

고정 업데이트·시간 배율·프리팹·후기 이벤트·장면 전환의 기존 사례 18개를 새 모듈로 실행해 회귀 검사했습니다. 추가로 LateUpdate 없는 49개 스크립트와 20장면·25프리팹이 포함된 별도 프로젝트 복사본을 빌드하고 원본/Unreal/복원 Unity의 생성·삭제·참조·GC·세 장면 전환 및 기존 250프레임 상태·UI·애니메이션·물리 허용 범위를 대조했습니다. 내부 검사 368개가 통과했으며, 이전 시작 방식의 헤더 역변환도 유지됩니다.

제한: 이 검증은 위 사례의 지원 동작에 해당합니다. 임의 API·스켈레탈 애니메이션·복잡한 UI·모든 엔진 버전·전체 렌더링·물리 궤적 동등성 및 모든 게임의 완전 자동 포팅은 미완료입니다. 관측 전용 LateUpdate는 테스트 도구이며 변환된 다섯 클래스에는 LateUpdate가 없습니다. 원본 Unity의 LateUpdate와 Unreal의 actor 업데이트 직후를 같은 관측 경계로 사용하며, 그 뒤의 시작 처리는 다음 관측 상태와 호출 순서에 반영됩니다.

FixedUpdate 안의 생성·복제·재활성화·삭제

2026-10-24T10:18:37.521804+09:00. 고정 단계에서 생성한 객체가 다음 고정 단계와 같은 프레임의 Update를 올바르게 받도록 시작 경계를 추가했습니다. 고정 단계 중 재활성화한 객체는 현재 단계를 건너뛴 뒤 다음 고정 단계와 Update를 받을 수 있습니다. 이전에 발행한 고정 시계 형식 1~4의 역변환을 보존하고, 새 동작은 형식 5로 구분합니다.

실제 왕복 실행100/50/30 FPS와 고정 간격 0.02/0.01초의 네 조건에서 원본 Unity·Unreal·복원 Unity를 실행했습니다. 12개 캡처의 실제 프레임 델타와 24프레임·97개 상태 값을 대조했습니다.
검증 동작상속된 FixedUpdate의 명시적인 부모 호출, 살아 있는 객체의 복제된 카운터와 외부 컴포넌트 참조, Start에서의 자식·손자 생성, enabled/SetActive 변경, 고정 단계의 삭제와 별도 소유 자식의 생존을 검사했습니다.
전체 프로젝트 파이프라인기존 49개와 새 6개를 함께 수집한 55개 클래스를 프로그램의 실제 프로젝트 경로로 양방향 변환했습니다. 20장면·25프리팹과 저장·재열기·참조 검사를 수행하고, 복원 Unity를 다시 내보내 133개 노드와 자산 데이터·스크립트 GUID·실행 순서를 대조했습니다.
통합 실행원본·네이티브·복원 프로젝트 안에서 고정 단계 사례 40프레임·97개 값을 대조했습니다. 프리팹 8개 체크포인트, GC 후 객체/Transform 정체성, 세 장면 순서와 기존 250프레임 UI·애니메이션·물리 허용 범위도 확인했습니다.
회귀 검사최신 생성 코드와 빌드 모듈로 기존 사례 20개를 실행했습니다. 내부 검사 372개와 실제 이전 형식 4 헤더의 사용자 코드 복원도 통과했습니다.

범위와 제한: Unity 6000.0.83f1 / Unreal 5.8의 개인 테스트 복사본으로 검증했습니다. 동일 클래스 인스턴스의 미정의 실행 순서는 보장하지 않으며, 이벤트 순서 코드는 클래스 간 호출과 구분 가능한 생명주기 이벤트를 검사합니다. 임의 사용자 게임·모든 API·모든 버전·전체 렌더링 및 물리 궤적의 동등성은 미완료입니다. 관측 전용 코드는 게임 변환 대상과 구분하며 사용자 원본은 보존했습니다.

2026-10-29 · QA 수정 배포

부분 코드 생성도 원본·대상 프로젝트 내부에 결과를 쓰지 못하도록 수정했습니다. 잘못된 플러그인 Name·Enabled 설명자는 예외로 검사를 종료하지 않고 해당 파일의 검사 차단으로 표시합니다. Assets/bin 같은 사용자 폴더를 이름만으로 누락하지 않도록 조사 조건을 수정했습니다.

의존성 동의는 코드/API 경계에서도 한 번의 작업에만 사용할 수 있습니다. 이미 사용한 동의로 다음 작업을 시작하면 다시 직접 선택하도록 중단합니다. 한 작업 안에서 하는 반복적인 변경 검사는 허용합니다. 바이너리·플랫폼 번들의 Unity .meta, Unreal Binaries의 모듈·라이브러리와 .modules/.target 변경도 지문에 포함합니다. 프로젝트 자체 모듈도 후보에 포함될 수 있으며 라이선스를 판정한 것은 아닙니다.

최소 크기 경고창의 버튼 잘림을 수정했습니다. 검사 중 중복 경로 조회를 줄이고 큰 파일 해시 처리 중 취소를 확인하도록 개선했습니다. 실제 Unity 입력의 읽기 전용 검사에서 후보 목록과 지문을 유지하는지 대조했습니다. 파일 시스템 캐시에 따라 시간은 달라집니다.

이번 QA는 이전 배포 Core의 재현 검사, 수정 후 별도 QA 18개·기존 내부 검사 403개, UI 오프스크린 렌더링과 WinForms 클릭 처리, 실제 입력 읽기 전용 검사와 방화벽 사전 조회를 포함합니다. 이번 버전의 실제 Unity/Unreal 왕복 실행은 수행하지 않았으며, 보안창 재발 여부·모든 프로젝트 포팅 성공을 검증한 결과가 아닙니다.