언리얼 엔진 에서 IK 리타기터 에셋을 생성하고 사용하여 IK 릭으로 캐릭터 및 오브젝트에 대한 애니메이션을 리타기팅할 때, 커스텀 Python 스크립팅을 사용하여 IK 리타기터 에셋 워크플로를 제어하고 자동화할 수 있습니다.
이 문서에서는 IK 리타기터 에셋을 편집하고 인터페이스하기 위해 참조하고 사용할 수 있는 Python 스크립트를 간략하게 살펴보고 그 예시를 보여줍니다.
개요
IK 리타기터 에셋은 다음과 같은 여러 부분으로 구성됩니다.
-
리타깃 관계를 정의하는 소스(Source) 및 타깃 IK 릭(IK Rig)
-
소스 및 타깃 IK 릭에서 오버라이드되는 소스 및 타깃 스켈레탈 메시(Skeletal Mesh)
-
각 체인 간의 관계를 정의하는 소스와 타깃 간의 리타깃 체인(Retarget Chain) 매핑
-
리타깃이 솔브할 시작 포즈를 정의하는 소스 또는 타깃에 대한 리타깃 포즈(Retarget Poses) 목록
-
글로벌(Global), 리타깃 루트(Retarget Root) 및 각 리타깃 체인 에 대한 프로퍼티 목록
-
에디터 프리뷰 전용으로 사용되는 프리뷰 씬
IK 리타기터 데이터 모델에 사용되는 용어는 다음과 같습니다.
-
소스 및 타깃 IK 릭 : 소스에서 타깃으로 모션을 전달하기 위해 리타깃 체인을 서로 매핑하는 데 사용할 IK 릭입니다.
-
소스 및 타깃 메시 : 리타깃에 대한 소스 및 타깃 비율을 정의하기 위해, 그리고 프리뷰할 소스 애니메이션에 액세스하기 위해 사용하려는 스켈레탈 메시입니다.
-
소스 및 타깃 리타깃 포즈 : 소스나 타깃이 모션 전달에 사용할 포즈입니다. 타깃이 소스의 포즈에 일치하는 것이 이상적입니다.
-
글로벌 세팅 : 전체 리타깃에 영향을 주는 매크로 레벨 세팅입니다.
-
루트 세팅 : 리타깃 루트에 영향을 주는 세팅입니다.
-
체인 세팅 : 지정된 리타깃 세팅에 영향을 주는 세팅입니다.
IK 리타기터 액세스하기
IK 리타기터 에셋에 대한 스크립팅 시 첫 번째 단계는 상호작용할 주 오브젝트인 IKRetargeter 에 대한 액세스 권한을 획득하는 것입니다. 프로젝트에 따라 여러 가지 방식으로 오브젝트에 대한 액세스 권한을 획득할 수 있습니다.
기존 RTG 에셋 로드하기
기존 IK 리타기터 에셋(rtg)에 액세스하려면 다음 예시 스크립트를 사용하여 해당 에셋을 로드하면 됩니다.
import unreal
# 프로젝트에서 에셋 위치의 파일 경로가 정확한지 확인합니다.
rtg = unreal.load_asset(name = '/Game/Characters/Mannequins/Rigs/RTG_Mannequin', outer = None)
새 RTG 에셋 생성하기
다음 팩토리를 사용하여 새 IK 리타기터 에셋을 생성할 수 있습니다.
# 에셋 툴을 가져옵니다.
asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
# 파일 경로에 의해 정의된 위치에 IK 리타기터 에셋을 생성합니다. `.../Game/RTG_Mannequin` 을 예로 들면 다음과 같습니다.
rtg = asset_tools.create_asset(asset_name='RTG_Mannequin', package_path='/Game/', asset_class=unreal.IKRetargeter, factory=unreal.IKRetargetFactory())
IK 리타기터 편집하기
컨트롤러에 액세스하여 편집 준비하기
컨트롤러는 IK 리타기터 변경에 사용할 수 있는 중심적인 오브젝트입니다. 컨트롤러에는 편집에 사용할 수 있는 많은 함수가 있습니다. 다음 예시는 Python 스크립팅을 사용하여 IK 리타기터 에셋을 편집할 수 있는 메서드의 서브셋입니다.
# IK 리타기터 컨트롤러를 가져옵니다.
rtg_controller = unreal.IKRetargeterController.get_controller(rtg)
소스 및 타깃 IK 릭 및 메시를 새 에셋에 할당하기
리타깃을 실행하려면 소스 및 타깃 IK 릭을 제공해야 합니다. 이 경우, IK 리타기터 에셋을 생성하여 매니 캐릭터(Manny Character)에서 퀸 캐릭터(Quinn Character)로 애니메이션을 리타기팅할 것입니다. 즉, IK_Mannequin 을 소스와 타깃 둘 다로 할당할 수 있습니다.
삼인칭 템플릿 프로젝트를 사용하여 매니 및 퀸 스켈레탈 메시 캐릭터와 IK_Mannequin IK 릭 에셋에 액세스할 수 있습니다.
# 소스 및 타깃 IK 릭을 로드합니다.
source_ik_rig = unreal.load_asset(name = '/Game/Characters/Mannequins/Rigs/IK_Mannequin', outer = None)
target_ik_rig = unreal.load_asset(name = '/Game/Characters/Mannequins/Rigs/IK_Mannequin', outer = None)
# 소스 및 타깃 IK 릭을 할당합니다.
rtg_controller.set_ik_rig(unreal.RetargetSourceOrTarget.SOURCE, source_ik_rig)
rtg_controller.set_ik_rig(unreal.RetargetSourceOrTarget.TARGET, target_ik_rig)
소스 또는 타깃 IK 릭을 가져올 수도 있으며, 이는 리타깃 체인을 쿼리하는 데 유용합니다.
# IK 리타기터 에셋에 할당된 소스 및 타깃 IK 릭을 가져옵니다.
rtg_controller.get_ik_rig(unreal.RetargetSourceOrTarget.SOURCE)
rtg_controller.get_ik_rig(unreal.RetargetSourceOrTarget.TARGET)
소스 또는 타깃 IK 릭을 설정할 수 있을 뿐 아니라, 소스/타깃 프리뷰 메시에 대한 오버라이드를 제공할 수도 있습니다. 이 경우 IK 릭에서 제공하는 기본 프리뷰 메시가 오버라이드됩니다.
# 스켈레탈 메시를 로드합니다.
source_skel_mesh = unreal.load_asset(name = '/Game/Characters/Mannequins/Meshes/SKM_Manny_Simple.SKM_Manny_Simple')
target_skel_mesh = unreal.load_asset(name = '/Game/Characters/Mannequins/Meshes/SKM_Quinn_Simple.SKM_Quinn_Simple')
# 소스 및 타깃 스켈레탈 메시를 할당합니다.
rtg_controller.set_preview_mesh(unreal.RetargetSourceOrTarget.SOURCE, source_skel_mesh)
rtg_controller.set_preview_mesh(unreal.RetargetSourceOrTarget.TARGET, target_skel_mesh)
# IK 리타기터 에셋에 할당된 소스 및 타깃 스켈레탈 메시를 가져옵니다.
rtg_controller.get_preview_mesh(unreal.RetargetSourceOrTarget.SOURCE)
rtg_controller.get_preview_mesh(unreal.RetargetSourceOrTarget.TARGET)
리타깃 체인 매핑 편집 및 쿼리하기
에디터와 비슷하게, Python을 사용하여 리타깃 체인을 자동 매핑할 수 있습니다. 또한, 퍼지 문자열 일치(fuzzy string match) , 정확한 문자열 일치(exact string match) 또는 전체 맵 지우기(clear maps) 같은 자동 매핑 옵션을 사용할 수도 있습니다.
# 퍼지 문자열 일치를 사용하여 체인을 매핑하며, 강제 리매핑됩니다.
rtg_controller.auto_map_chains(unreal.AutoMapChainType.FUZZY, True)
# 정확한 문자열 일치를 사용하여 체인을 매핑하며, 강제 리매핑됩니다.
rtg_controller.auto_map_chains(unreal.AutoMapChainType.EXACT, True)
# 모든 매핑을 지웁니다.
rtg_controller.auto_map_chains(unreal.AutoMapChainType.CLEAR, True)
자동 매핑을 원치 않는다면, 각 타깃 체인의 매핑을 설정하거나 가져올 수 있습니다.
# 주어진 타깃 체인에 매핑된 소스 체인을 가져옵니다.
source_mapped_chain_name = rtg_controller.get_source_chain("Spine")
# 타깃이 매핑되는 소스 체인을 설정합니다. Python 스크립트에서 ("소스", "타깃") 형식으로 설정합니다.
rtg_controller.set_source_chain("Spine", "Spine")
리타깃 포즈 추가, 편집 및 쿼리하기
리타깃 포즈는 소스 또는 타깃이 리타깃해야 하는 베이스 포즈를 결정하는 데 사용됩니다. 타깃 캐릭터의 포즈가 소스와 다르거나 소스가 적절한 정면 축을 향해야 하는 경우 유용합니다.
다음 명령을 사용하여 소스 또는 타깃에 대한 리타깃 포즈를 쿼리할 수 있습니다.
# 타깃에 대한 모든 리타깃 포즈를 가져옵니다.
all_target_poses = rtg_controller.get_retarget_poses(unreal.RetargetSourceOrTarget.TARGET)
리타깃 포즈의 이름을 제공하고 리타깃 포즈가 소스인지 타깃인지 지정하기만 하면, 리타깃 포즈를 생성하거나 복제하거나 이름을 변경하거나 제거할 수 있습니다.
# 새 리타깃 포즈를 생성합니다.
rtg_controller.create_retarget_pose("my_new_pose", unreal.RetargetSourceOrTarget.TARGET)
# 새 포즈를 복제합니다.
rtg_controller.duplicate_retarget_pose("my_new_pose", "duplicated_pose", unreal.RetargetSourceOrTarget.TARGET)
# 복제 포즈의 이름을 변경합니다.
rtg_controller.rename_retarget_pose("duplicated_pose", "renamed_pose", unreal.RetargetSourceOrTarget.TARGET)
# 복제 포즈를 제거합니다.
rtg_controller.remove_retarget_pose("renamed_pose", unreal.RetargetSourceOrTarget.TARGET)
이제 현재 리타깃 포즈를 새로 생성된 포즈로 설정할 수 있습니다.
rtg_controller.set_current_retarget_pose("my_new_pose", unreal.RetargetSourceOrTarget.TARGET)
print(rtg_controller.get_current_retarget_pose_name(unreal.RetargetSourceOrTarget.TARGET))
이제 새 리타깃 포즈가 생겼으니 Python 스크립트를 사용하여 이 포즈를 편집할 수 있습니다. 리타깃 루트는 리타깃 포즈에서 이동 및 회전 오프셋 델타 값을 가질 수 있는 유일한 본입니다. 다른 모든 본의 경우, 리타깃 포즈는 관련 회전 오프셋 델타 값만 저장합니다.
예를 들어, 타깃의 리타깃 루트를 올바른 방향으로 올리거나 뒤집어야 하는 경우, 다음 Python 스크립트를 사용하면 위로 15 유닛 올리고 90도 회전합니다.
# 이동에 대한 벡터를 생성합니다.
translation_offset = unreal.Vector()
translation_offset.z = 15
# 리타깃 루트의 이동 오프셋을 설정합니다.
rtg_controller.set_root_offset_in_retarget_pose(translation_offset, unreal.RetargetSourceOrTarget.TARGET)
print(rtg_controller.get_root_offset_in_retarget_pose(unreal.RetargetSourceOrTarget.TARGET))
# 회전에 대한 로테이터를 생성합니다.
rotation_offset = unreal.Rotator()
rotation_offset.roll = 90
# 리타깃 루트의 회전 오프셋을 설정합니다. 모든 본에 작동하므로, 본 이름을 정의해야 합니다.
rtg_controller.set_rotation_offset_for_retarget_pose_bone("pelvis", rotation_offset.quaternion(), unreal.RetargetSourceOrTarget.TARGET)
print(rtg_controller.get_rotation_offset_for_retarget_pose_bone("pelvis", unreal.RetargetSourceOrTarget.TARGET))
마지막으로, 본 목록을 원래 트랜스폼으로 리셋할 수 있습니다.
rtg_controller.reset_retarget_pose("my_new_pose", ["pelvis"], unreal.RetargetSourceOrTarget.TARGET)
글로벌 세팅 편집 및 쿼리하기
리타기터의 글로벌 세팅에서는 리타깃 루트, FK 및 IK 같은 리타깃의 여러 페이즈나 스트라이드 조정 프로퍼티를 편집할 수 있습니다. 다음 Python 스크립트로 이러한 페이즈를 쿼리하고 편집할 수 있습니다.
# 글로벌 세팅을 가져오고 IK를 변경하고 글로벌 세팅을 설정합니다.
global_settings = rtg_controller.get_global_settings()
global_settings.set_editor_property("enable_ik", False)
rtg_controller.set_global_settings(global_settings)
루트 세팅 편집 및 쿼리하기
리타기터의 루트 세팅에서는 리타깃 루트에 관련된 프로퍼티를 편집할 수 있습니다. 이를 통해 둔부에 대한 이동 또는 회전 오프셋이나, 수직 또는 수평 모션 스케일링, 수직 또는 수평 평면에서 IK 목표가 영향을 받는 방식을 편집할 수 있습니다. 다음 Python 스크립트로 이러한 프로퍼티를 쿼리하고 편집할 수 있습니다.
# 루트 세팅을 가져오고 둔부를 10 유닛만큼 올리고 루트 세팅을 설정합니다.
root_settings = rtg_controller.get_root_settings()
root_settings.translation_offset = unreal.Vector(0,0,10)
rtg_controller.set_root_settings(root_settings)
체인 세팅 편집 및 쿼리하기
리타기터의 체인 세팅에서는 각 리타깃 체인에 관련된 프로퍼티를 편집할 수 있습니다. FK 체인의 경우에는 여기에서 회전 리타깃 모드를 변경할 수 있으며, IK 체인의 경우에는 IK 목표를 소스 위치에 고정하거나, 오프셋을 IK에 추가하거나, IK를 수직으로 스케일링하려면 여기에서 편집할 수 있습니다. 다음 Python 스크립트로 이러한 프로퍼티를 쿼리하고 편집할 수 있습니다.
# 구체적으로 왼쪽 다리 체인을 가져옵니다.
left_leg_chain_settings = rtg_controller.get_retarget_chain_settings("LeftLeg")
# 아니면 모든 체인에서 쿼리하고 루프 조건문을 사용하여 체인을 가져올 수 있습니다.
chains = rtg_controller.get_all_chain_settings()
left_leg_chain_settings = next((chain.settings for chain in chains if chain.source_chain == "LeftLeg"), None)
# FK 세팅을 편집합니다.
left_leg_chain_settings.fk.rotation_mode = unreal.RetargetRotationMode.INTERPOLATED
left_leg_chain_settings.fk.pole_vector_matching = 1
# IK 세팅을 편집합니다.
left_leg_chain_settings.ik.blend_to_source = 1
left_leg_chain_settings.ik.static_offset = unreal.Vector(0,5,0)
# 스피드 플랜트 세팅을 편집합니다.
left_leg_chain_settings.speed_planting.enable_speed_planting = True
left_leg_chain_settings.speed_planting.speed_curve_name = "ball_l_translation_speed_XYZ"
# 리타깃 체인 세팅을 설정합니다.
rtg_controller.set_retarget_chain_settings("LeftLeg", left_leg_chain_settings)
복제 및 리타깃으로 리타깃 애니메이션 배치 처리
리타기팅된 애니메이션을 배치 처리하려면 Python에서 복제 및 리타깃과 동일한 명령을 실행하면 됩니다.
# 에셋 서브시스템을 사용하여 에셋 데이터를 가져옵니다.
asset_subsystem = unreal.get_editor_subsystem(unreal.EditorAssetSubsystem)
# 애님 시퀀스, 애님 블루프린트, 포즈 에셋 등에 사용할 수 있는 에셋 데이터 목록을 가져옵니다.
assets_to_retarget = [
asset_subsystem.find_asset_data("/Game/Characters/Mannequins/Animations/Manny/MM_Fall_Loop"),
asset_subsystem.find_asset_data("/Game/Characters/Mannequins/Animations/Manny/MM_Idle")]
retarget_asset = unreal.load_asset(name = '/Game/Characters/Mannequins/Rigs/RTG_Mannequin')
source_mesh = None # will use mesh from source ik rig
target_mesh = None # will use mesh from target ik rig
batch_op = unreal.IKRetargetBatchOperation.duplicate_and_retarget(
assets_to_retarget,
source_mesh,
target_mesh,
retarget_asset,
search = "",
replace = "",
prefix = "",
suffix = "",
remap_referenced_assets = True)