Unreal Engine で IK リターゲッタ アセットを作成して使用し、IK リグ を使用するキャラクターおよびオブジェクトのアニメーションをターゲットする場合、カスタム仕様の Python スクリプト を使用することで、IK リターゲッタのアセットのワークフローを制御および自動化することができます。
このドキュメントでは、IK リターゲッタ アセットを編集および操作するために参照および使用することができる Python スクリプトの概要と例を提供します。
概要
IK リターゲッタ アセットは次の複数のパーツで構成されています。
-
ターゲット関係を定義する ソース IK リグと ターゲット IK リグ。
-
ソース IK リグとターゲット IK リグからの ソース スケルタルメッシュおよび ターゲット スケルタルメッシュ のオーバーライド。
-
ソースとターゲット間の ターゲット チェーン。各チェーン間の関係を定義します。
-
ソースとターゲットのどちらかの ターゲット ポーズ のリスト。ターゲットが解決する開始ポーズを定義します。
-
グローバル、ターゲット ルート、および各 ターゲット チェーン のプロパティのリスト。
-
エディタ内のプレビュー専用のプレビュー シーン。
IK リターゲッタ データ モデルでは、次の用語を使用します。
-
ソース IK リグ および ターゲット IK リグ:ソースからターゲットにモーションを転送するために、ターゲット チェーンをまとめてマッピングするために使用される IK リグです。
-
ソース メッシュおよび ターゲット メッシュ:ターゲットのソースおよびターゲットのプロポーションを定義し、ソース アニメーションをプレビューするためにアクセスするスケルタルメッシュ。
-
ソースのターゲット ポーズ および ターゲットのターゲット ポーズ:ソースまたはターゲットのどちらかがモーションを転送するために使用するポーズ。理想的なのは、ターゲットがソース ポーズに一致していることです。
-
Global Settings (グローバル設定):ターゲット全体に影響するマクロ レベルの設定。
-
Root Settings (ルート設定):ターゲット ルートに影響する設定。
-
Chain Settings (チェーン設定):指定したターゲット チェーンに影響する設定。
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 リグおよびターゲット IK リグを指定する必要があります。ここでは、Manny キャラクターから Quinn キャラクターへのアニメーションをターゲットするために、IK リターゲッタ アセットを作成しようとしているため、ソースとターゲットの両方として IK_Mannequin を割り当てることができます。
Manny と Quinn のスケルタルメッシュ キャラクターと IK_Mannequin IK リグ アセットには、サードパーソン テンプレート プロジェクト を使用してアクセスすることができます。
# ソース 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 リグとターゲット 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 リターゲッタ アセットに割り当てられたソース 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 を使用してターゲット チェーンの自動マッピングを実行することができます。また、文字列のあいまい一致、文字列の完全一致、または全体の マッピングのクリア などの自動マッピングのオプションも使用できます。
# 文字列のあいまい一致を使用してチェーンをマッピングします。これにより、強制的に再マッピングされます。
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 スクリプトの形式 ("Source", "Target") で、ターゲットのマッピング先のソース チェーンを設定します。
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")
# または、すべてのチェーンからのクエリにより、1 行の for ループ条件を使用してチェーンを取得することができます。
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)
# Anim シーケンス、Anim ブループリント、Pose アセットなどに使用できるアセット データのリストを取得します。
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)