데이터스미스 임포트 프로세스 커스터마이징

블루프린트 또는 Python 을 사용해서 데이터스미스 및 CAD 파일을 임포트하는 방법, 씬을 언리얼 애셋 및 액터로 변환하는 방식을 바꾸는 방법을 설명합니다.

Windows
MacOS
Linux

데이터스미스 임포트 프로세스의 목표는 외부 콘텐츠 제작 툴에서 구성한 3D 오브젝트 세트를 언리얼 에디터로 부드럽게 가져오는 것입니다. 그러기 위해 메시, 라이트, 카메라, 표면 머티리얼의 원래 의도를 잘 살려 언리얼 엔진에서 그에 해당하는 오브젝트로 자동 변환하고, 그 애셋의 인스턴스를 레벨에 자동으로 채웁니다. 자세한 내용은 데이터스미스 개요 문서를 참고하세요.

하지만 가끔 임포트 프로세스 내부로 들어가 원본 씬을 언리얼 엔진 애셋으로 변환하는 방법이나, 그 애셋에 실제 하는 작업을 변경하고 싶을 때가 있습니다. 예를 들어 원본 씬 중 언리얼 엔진 프로젝트에 필요치 않은 부분을 알고 있으면, 그 오브젝트는 필터로 걸러낸 뒤 애셋을 만드는 것이 좋습니다. 그러면 언리얼 에디터에서 처리해야 하는 콘텐츠 조각 수를 줄이고, 큰 씬의 임포트 속도를 높일 수 있습니다.

여기서는 데이터스미스 임포트 프로세스를 제어하기 위해 블루프린트와 Python 스크립트를 사용하는 법을 살펴봅니다.

임포트 프로세스의 이해

언리얼 에디터 툴바의 데이터스미스 임포터 중 하나로 씬을 씬을 임포트할 때, 데이터스미스 콘텐츠를 언리얼 엔진 4 에 임포트 문서의 설명대로 임포터는 내부적으로 2 단계 과정을 거쳐 디스크의 .udatasmith, CAD, 다른 소스 파일에 있는 데이터를 가져와 언리얼 에디터의 애셋과 액터로 변환합니다.

  1. 임포터는 파일의 콘텐츠를 읽어 Datasmith Scene (데이터스미스 씬)이라는 메모리 내 데이터 구조체로 만듭니다. 여기에는 씬의 3D 오브젝트 표현, 그 관계, 데이터스미스가 원본 씬에서 추출할 수 있었던 그 오브젝트의 프로퍼티 전부가 들어갑니다.

  2. 데이터스미스 씬이 메모리에 준비되면, 임포트 프로세스의 두 번째 단계에서 씬 엘리먼트를 마무리하여 콘텐츠 브라우저의 언리얼 엔진 애셋으로 저장합니다. 데이터스미스 씬 애셋이 준비되면, 임포트 프로세스는 현재 레벨에 스폰합니다. 그리고 이어서 액터, 스태틱 메시 액터, 라이트, 카메라 등 그 자손 전부를 스폰합니다.

Two-step Datasmith import process

임포트 프로세스 커스터마이징 옵션

블루프린트 또는 Python 스크립트를 사용하여 데이터스미스 임포트 프로세스를 실행할 때, 위 프로세스를 두 단계로 나눠 별도로 실행할 수 있습니다. 그러면 데이터스미스 씬을 메모리에 구성한 이후, 하지만 그 씬을 마무리하여 애셋과 액터로 저장하기 전에 별도의 프로세스를 삽입할 수 있습니다.

전반적은 프로세스는 블루프린트와 Python 둘 다 똑같습니다.

  1. 디스크 상의 .udatasmith, CAD, 또는 지원하는 다른 파일 유형 위치에서 메모리 내 데이터스미스 씬 표현을 새로 생성합니다.

  2. 씬을 언리얼 애셋으로 변환하는 방식에 영향을 주고자 하는 씬 수정사항을 추가합니다.

    변경해야 하는 오브젝트를 알아내기 쉬운 방법 한 가지는 씬의 오브젝트 관련 메타데이터를 활용하는 것입니다. 데이터스미스 씬의 메타데이터에 액세스하는 방법 관련 자세한 내용은 데이터스미스 메타데이터 사용법 문서를 참고하세요.

  3. 임포트 프로세스의 옵션을 설정합니다. 이 옵션은 기본적으로 데이터스미스 임포트 버튼을 눌러 임포트를 시작할 때 언리얼 에디터 UI 에서 설정하는 옵션에 해당하는 것입니다. 예를 들어 임포트한 애셋을 프로젝트 어디에 저장할지, 데이터스미스 씬에서 어떤 오브젝트 유형을 생성할지, 파라미터형 CAD 포맷의 테셀레이션 세팅은 어떻게 할지 등을 설정합니다.

  4. 임포트 프로세스를 완료하여 데이터스미스 씬을 마무리하고 언리얼 애셋으로 저장합니다.

  5. 위에서 생성한 데이터스미스 씬이 더이상 필요치 않으면, 씬을 소멸해야 그 메모리 리소스를 확보할 수 있습니다.

  6. 임포트 프로세스가 완료되었으니, 콘텐츠 브라우저에 새로운 애셋을 사용하고 현재 레벨에 새 액터를 사용할 수 있을 것입니다 (임포트 옵션에 추가하도록 요청한 경우입니다). 생성된 언리얼 애셋에 콜리전 데이터 또는 LOD 를 자동 생성하는 등의 후처리 작업을 추가하려는 경우, 바로 여기서 하면 됩니다. 에디터 자동화 및 스크립트 작성 문서도 참고하세요.

임포트 프로세스 커스터마이징은 데이터스미스 리임포트 워크플로에 대하여 문서에 설명된 리임포트 프로세스에 영향을 줄 확률이 매우 높습니다. 예를 들어 임포트 프로세스를 완료하기 전 스크립트를 사용하여 데이터스미스 씬에서 메시나 라이트같은 엘리먼트를 제거한 경우, 데이터스미스 씬 애셋을 리임포트할 때 그 전처리 스크립트는 리임포트 도중 생략됩니다. 그 결과 원래 씬에서 필터로 거른 오브젝트가 새로 추가된 것으로 감지되어, 프로젝트 또는 레벨에 추가됩니다.

현재 대부분의 수정은 임포트 이후, 에디터 자동화 및 스크립트 작성 문서에 설명한 툴과 기법을 사용할 것을 권장합니다. 임포트 도중 데이터스미스 씬을 수정하는 것은 임포트 마무리 이후 애셋과 액터를 수정해서는 할 수 없는 작업이 있을 때, 예를 들면 특정 애셋의 생성을 막고자 하는 경우입니다.

시작하기 전에

예제

블루프린트 및 Python 을 사용하여 .udatasmith 및 CAD 파일을 언리얼 에디터로 임포트하는 프로세스를 커스터마이징하는 방법 예제는 다음과 같습니다.

구현 방법 선택

블루프린트

Python

블루프린트를 사용하여 임포트 프로세스를 커스터마이징하려면, 주로 Editor Scripting > Datasmith, Datasmith > SceneDatasmith > Element 카테고리의 노드를 사용하면 됩니다.

필요한 노드를 찾기 위해서는 에디터 유틸리티 위젯, 그리고 에디터 유틸리티 블루프린트를 사용하거나, EditorUtilityActor 와 같은 Editor-only 베이스 클래스 기반으로 블루프린트 클래스를 만들어야 합니다. 아래 예제는 에디터 유틸리티 위젯의 버튼에서 트리거되는 블루프린트 그래프를 보여줍니다.

대상 폴더는 /Game/ 으로 시작해야 합니다.

.udatasmith 파일 임포트하기

이 예제에서, Get Options 노드는 DatasmithImportOptions 클래스를 요청하며, 여기에는 그 Base Options 변수 안에 기초적인 임포트 세팅이 들어 있습니다.

Copy Node Graph

customized-DS-import.png

이미지 우상단을 클릭하면 노드 그래프를 복사합니다.

CAD 파일 임포트하기

이 예제에서, 첫 번째 Get Options 호출은 이전 예제와 동일한 DatasmithImportOptions 클래스를 요청합니다. 두 번째 호출은 DatasmithCommonTessellationOptions 클래스를 요청하며, 여기에는 그 Options 변수 안에 테셀레이션 세팅이 들어 있습니다. 세 번째 호출은 DatasmithCADImportOptions 클래스를 요청하며, 일반적으로 특수 상황에서 쓰이는 CAD 전용 추가 세팅이 들어 있습니다.

Copy Node Graph

customized-CAD-import.png

이미지 우상단을 클릭하면 노드 그래프를 복사합니다.

Python 을 사용하여 임포트 프로세스를 사용자 정의할 때 시작하기 좋은 곳은 unreal.DatasmithSceneElement 클래스입니다. 이 클래스에는 파일에서 씬을 생성하고 그 씬의 엘리먼트를 (unreal.DatasmithSceneElementBase 베이스 클래스에 정의된 함수를 통해) 작업한 뒤, 임포트를 마무리하기 위해 필요한 모든 함수가 들어있습니다.

.udatasmith 파일 임포트하기

import unreal

ds_file_on_disk = "C:\\scenes\\building.udatasmith"
ds_scene_in_memory = unreal.DatasmithSceneElement.construct_datasmith_scene_from_file(ds_file_on_disk)

if ds_scene_in_memory is None:
    print "Scene loading failed."
    quit()

# 씬의 데이터를 필터로 걸러내거나 엘리먼트를 합치도록 수정합니다...

# 이름에 특정 키워드가 포함된 메시를 제거합니다.
remove_keyword = "exterior"      # 이름에 이 스트링이 포함된 액터는 제거합니다.
meshes_to_skip = set([])         # 이 세트에 필요치 않은 메시를 임시 저장합니다.

# 이름이 위에 설정한 스트링에 일치하는 메시 액터를 씬에서 제거합니다.
for mesh_actor in ds_scene_in_memory.get_all_mesh_actors():
    actor_label = mesh_actor.get_label()
    if remove_keyword in actor_label:
        print("removing actor named: " + actor_label)
        # 이 액터의 메시 애셋을 생략할 메시 목록에 추가합니다.
        mesh = mesh_actor.get_mesh_element()
        meshes_to_skip.add(mesh)
        ds_scene_in_memory.remove_mesh_actor(mesh_actor)

# 임포트할 필요 없는 모든 메시를 제거합니다.
for mesh in meshes_to_skip:
    mesh_name = mesh.get_element_name()
    print("removing mesh named " + mesh_name)
    ds_scene_in_memory.remove_mesh(mesh)

# 임포트 옵션을 설정합니다.
import_options = ds_scene_in_memory.get_options(unreal.DatasmithImportOptions)
import_options.base_options.scene_handling = unreal.DatasmithImportScene.NEW_LEVEL

# 애셋과 액터를 생성하는 것으로 프로세스를 마무리합니다.

# 대상 폴더는 /Game/ 으로 시작해야 합니다.
result = ds_scene_in_memory.import_scene("/Game/MyStudioScene")

if not result.import_succeed:
    print "Importing failed."
    quit()

# 데이터스미스 씬을 정리합니다.
ds_scene_in_memory.destroy_scene()
print "Custom import process complete!"

CAD 파일 임포트하기

import unreal

# 디스크의 파일에서 데이터스미스 CAD 씬을 생성합니다.
# 대상 폴더는 /Game/ 로 시작해야 합니다.
ds_file_on_disk = "C:\\designs\\Clutch assembly.SLDASM"
ds_scene_in_memory = unreal.DatasmithSceneElement.construct_datasmith_scene_from_file(ds_file_on_disk)

if ds_scene_in_memory is None:
    print "Scene loading failed."
    quit()

# 씬의 데이터를 필터로 걸러내거나 엘리먼트를 합치도록 수정합니다.
remove_keyword = "_BODY"         # 이름에 이 문자열이 있는 액터는 제거합니다.
meshes_to_skip = set([])         # 이 세트를 사용하여 필요치 않은 메시를 임시 저장합니다.

# 이름이 위에 설정한 문자열에 일치하지 않는 메시 액터를 씬에서 제거합니다.
for mesh_actor in ds_scene_in_memory.get_all_mesh_actors():
    actor_label = mesh_actor.get_label()
    if remove_keyword in actor_label:
        print("removing actor named: " + actor_label)
        # 이 액터의 메시 애셋을 생략할 메시 목록에 추가합니다.
        mesh = mesh_actor.get_mesh_element()
        meshes_to_skip.add(mesh)
        ds_scene_in_memory.remove_mesh_actor(mesh_actor)

# 임포트할 필요가 없는 모든 메시를 제거합니다.
for mesh in meshes_to_skip:
    mesh_name = mesh.get_element_name()
    print("removing mesh named " + mesh_name)
    ds_scene_in_memory.remove_mesh(mesh)

# 임포트 옵션을 설정합니다.

# 메인 임포트 옵션입니다:
import_options = ds_scene_in_memory.get_options(unreal.DatasmithImportOptions)
import_options.base_options.scene_handling = unreal.DatasmithImportScene.NEW_LEVEL

# CAD 전용 표면 테셀레이션 옵션입니다:
tessellation_options = ds_scene_in_memory.get_options(unreal.DatasmithCommonTessellationOptions)
tessellation_options.options.chord_tolerance = 0.1
tessellation_options.options.max_edge_length = 0
tessellation_options.options.normal_tolerance = 30
tessellation_options.options.stitching_technique = unreal.DatasmithCADStitchingTechnique.STITCHING_SEW

# 추가 CAD 전용 옵션입니다:
cad_import_options = ds_scene_in_memory.get_options(unreal.DatasmithCADImportOptions)
cad_import_options.uv_generation = unreal.CADUVGeneration.KEEP
cad_import_options.num_threads = 8

# 애셋 및 액터를 생성하여 프로세스를 마무리합니다.
ds_scene_in_memory.import_scene("/Game/MyCADScene")

# 데이터스미스 씬을 정리합니다.
ds_scene_in_memory.destroy_scene()
print "Custom import process complete!"

임포트 옵션 액세스

여러 유형의 데이터스미스 소스 파일 작업을 할 때, API 에서의 유일한 차이점은 여러 파일 유형마다 임포트 동작을 제어하는 옵션이 다르다는 점입니다.

  • .udatasmith 파일의 경우, 위의 첫 번째 예제는 대상 애셋 및 경로명, 임포트하려는 데이터 유형, 라이트맵 해상도 세팅 등에 대한 액세스를 제공하는 DatasmithImportOptions 오브젝트에 액세스하는 법을 보여줍니다. 데이터스미스로 임포트할 수 있는 모든 파일 유형에 대해 작동합니다.

  • CAD 파일의 경우, 두 번째 예제는 테셀레이션 프로세스에 사용되는 세팅을 제어하는 DatasmithCommonTessellationOptions, 유용할 수 있는 다른 내부 디버그 세팅 액세스를 제공하는 DatasmithCADImportOptions 오브젝트에 액세스하는 방법을 보여줍니다.

  • 데이터스미스에 지원되는 다른 파일 유형은 다른 클래스의 임포트 세팅을 캡슐화하며, 예를 들면 Cinema 4D 의 경우 DatasmithC4DImportOptions 입니다.

이 임포트 옵션 액세스와 별도로, 데이터스미스 씬 및 씬 안의 엘리먼트 작업용 스크립트 나머지는 정확히 똑같습니다.

이 임포트 옵션 클래스 및 제공되는 세팅 관련 자세한 내용은, Python API Reference 또는 Blueprint API Reference 의 해당 항목을 참고하세요.

Python 의 DatasmithSceneElement.get_options() 또는 블루프린트의 Get Options 노드를 사용할 때, 구성해 둔 소스 파일 유형에 적용되지 않는 데이터스미스 옵션 클래스를 지정한 경우, null 이 반환됩니다. Python 에서는 None 반환을 테스트하면 되며, 블루프린트에서는 반환된 값을 Utilities > IsValid 노드에 전달하여 요청한 클래스의 유효 인스턴스인지 검사하면 됩니다.

Python 의 DatasmithSceneElement.get_options() 또는 블루프린트의 Datasmith > Scene > Get Options 에 대한 대안으로는, DatasmithSceneElement.get_all_options() 또는 Datasmith > Scene > Get All Options 를 사용해 단일 맵에 구성했던 데이터스미스 씬에 대한 옵션 모든 클래스를 얻을 수 있습니다. 맵의 각 항목에 대한 키(key)는 파일에서 구성한 데이터스미스 씬 엘리먼트에 소유된 옵션들의 클래스이며, 값(value)은 데이터스미스 씬 엘리먼트에 소유된 해당 클래스의 인스턴스입니다. 스크립트가 처리하게 될 파일 유형을 몰라서 DatasmithSceneElement 에 포함시킬 옵션 유형을 알 수 없는 경우, 이 접근법으로 전부 얻어 반복처리하면 됩니다.

데이터스미스 씬에 대하여

임포트 전 단계 도중 데이터스미스로 어떤 작업을 할 수 있는지 살펴보려면, 씬 생성 방식에 대해 약간 알아두면 도움이 됩니다.

씬 콘텐츠

데이터스미스 씬은 대부분 여러가지 엘리먼트 유형의 컨테이너입니다. 이 엘리먼트 각각은 임포트 후 콘텐츠 브라우저에 생성할 애셋, 또는 별도의 3D 공간 트랜스폼 정보로 레벨에 스폰할 액터 를 나타냅니다.

주요 애셋 엘리먼트 유형은 다음과 같습니다.

  • 메시: 각 메시 엘리먼트는 3D 지오메트리 블록을 나타냅니다. 임포트를 완료하면, 각 메시 엘리먼트는 Geometry 폴더 아래 별도의 스태틱 메시 오브젝트가 됩니다. 각 메시 엘리먼트에는 머티리얼 슬롯이 다수 있으며, 각각 머티리얼 엘리먼트 이름으로 연관되어 있습니다.

  • 머티리얼: 각 머티리얼 엘리먼트는 지오메트리에 필요한 표면 별개 유형을 나타냅니다. 임포트를 완료하면, 각 머티리얼 엘리먼트는 Materials 폴더 아래 별도의 머티리얼 오브젝트가 됩니다.

  • 텍스처: 각 텍스처 엘리먼트는 최소 하나의 머티리얼이 사용하는 2D 이미지를 나타냅니다. 임포트를 완료하면, 각 텍스처 엘리먼트는 Textures 폴더 아래 별도의 텍스처 오브젝트가 됩니다.

주요 액터 엘리먼트 유형은 다음과 같습니다.

  • 메시 액터: 각 메시 액터 엘리먼트는 레벨의 메시 지오메트리 인스턴스를 나타냅니다. 임포트를 완료하면, 각 메시 액터 엘리먼트는 월드 아웃라이너에 Static Mesh Actor 로 나타납니다.

  • 라이트 액터: 각 라이트 액터 엘리먼트는 씬의 라이트 이미터를 나타냅니다. 임포트를 완료하면, 각 라이트 액터 엘리먼트는 레벨에 기본 언리얼 라이트 유형의 인스턴스가 됩니다. 즉 포인트 라이트나 스포트 라이트, 또는 에어리어 라이트를 시뮬레이션하는 커스텀 데이터스미스 액터가 됩니다. 이 라이트의 프로퍼티 값 중 강도, 색, IES 프로파일 텍스처 파일 등 다수를 얻고 설정할 수 있습니다.

  • 카메라 액터: 각 카메라는 소스 씬에 설정한 시점을 나타냅니다. 임포트를 완료하면 각 카메라 액터 엘리먼트는 레벨에 CineCameraActor 가 됩니다. 카메라 액터의 기본 프로퍼티 중 종횡비와 같은 것을 얻고 설정할 수 있습니다.

메모리의 데이터스미스 씬에 저장된 데이터는 .udatasmith 파일을 열었을 때 보이는 것과 매우 비슷합니다. 3ds Max 또는 Sketchup 을 사용하는 경우, 익스포트한 .udatasmith 파일을 열어 보면 데이터스미스 씬 생성 방식을 파악할 수 있습니다.

데이터스미스 파일 XML 콘텐츠

데이터스미스 씬 작업

주로 데이터스미스 씬을 통해 위에 설명한 엘리먼트 목록을 얻을 것입니다. 그 작업을 Python 에서 하려면, DatasmithSceneElement 를 파생한 DatasmithSceneElementBase 클래스에 정의된 함수를 사용하게 됩니다. 블루프린트에서는 위 예제에서처럼 Datasmith > Scene 노드를 사용하게 됩니다.

엘리먼트 목록을 얻었으면, 그 목록을 반복 처리하여 특정 엘리먼트 값을 얻을 수 있습니다. 그런 다음 그 엘리먼트에 대해 (DatasmithMeshActorElement 같은) Python API, 또는 블루프린트의 Datasmith > Element 노드를 사용하여 해당 엘리먼트 관련 정보를 얻고 설정하면 됩니다. 엘리먼트가 액터 유형인 경우, 그 자손 액터 엘리먼트도 얻을 수 있으며, 그러면 씬 계층구조를 탐색해 내려갈 수 있습니다.

씬에서 기존 엘리먼트를 (위 예제에서 본 것처럼) 제거하거나, 새 엘리먼트를 추가하려면, 같은 곳에 노출된 함수를 통해서도 할 수 있습니다. 예를 들어 액터를 제거하고 다른 부모 아래 다시 추가하여 액터 계층구조를 다시 섞으려면 Python 의 DatasmithSceneElement 클래스, 블루프린트의 Datasmith > Scene 카테고리 아래 노드를 사용하면 됩니다.

Select Skin
Light
Dark

새로운 언리얼 엔진 4 문서 사이트에 오신 것을 환영합니다!

문서 사이트에 대한 의견을 모을 수 있는 피드백 시스템을 포함해서 여러가지 새로운 기능을 준비하고 있습니다. 아래 Documentation Feedback 포럼(영문) 또는 언리얼 엔진 네이버 공식 카페(한글) 중 편하신 곳에 의견이나 문제점을 알려 주세요.

새 시스템이 준비되면 알려 드리겠습니다.

네이버 카페
공식 포럼