Python スクリプティング は、シーケンサー での コントロール リグ のアニメーション化のさまざまな部分を自動化および制御するために使用することができます。このドキュメントでは、コントロール リグ、アニメーション モード、その他のさまざまなアニメーション ワークフローで Python を使用する主な方法の概要を説明します。
前提条件
- Unreal Engine での Python スクリプティング および シーケンサーでのスクリプティング の経験があること。
- コントロール リグ の作成および使用方法を理解していること。
FK コントロール リグ トラックを作成する
コントロール リグ トラックの作成方法は、通常の シーケンサーでトラックを作成する 方法と若干異なります。コントロール リグ トラックには、作成するコントロール リグ クラスを定義する必要があります。コントロール リグ トラックを作成するには、次のコマンドを使用します。
# エディタのワールドを取得する
editor_system = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem)
world = editor_system.get_editor_world()
# リグ クラスを取得する
rig_class = unreal.FKControlRig.static_class()
# レベル シーケンスおよびアクタのバインディングを使用すると、クラスからコントロール リグ トラックを見つける、または作成することができる
rig_track = unreal.ControlRigSequencerLibrary.find_or_create_control_rig_track(world, level_sequence, rig_class, actor_binding)
# デフォルト メッシュから actor_binding を取得する
level_sequence = unreal.LevelSequenceEditorBlueprintLibrary.get_focused_level_sequence()
skeletal_mesh_component = rig.get_preview_mesh()
actor_binding = level_sequence.add_spawnable_from_instance(skeletal_mesh_component)
# スケルタルメッシュ パスから actor_binding を取得する
skeletal_mesh_component = unreal.load_asset(skeletal_mesh_path)
actor_binding = level_sequence.add_spawnable_from_instance(skeletal_mesh_component)
コントロール リグ トラックを作成する
FK コントロール リグ トラックと同様に、特定のコントロール リグ クラスを以下のとおり取得する必要があります。
# エディタのワールドを取得する
world = unreal.EditorLevelLibrary.get_editor_world()
# コントロール リグ アセットを取得する
rig = unreal.load_asset("/Game/Animation/ControlRig/Mannequin_ControlRig")
# リグ クラスを取得する
rig_class = rig.get_control_rig_class()
# レベル シーケンスおよびアクタのバインディングを使用すると、クラスからコントロール リグ トラックを見つける、または作成することができる
rig_track = unreal.ControlRigSequencerLibrary.find_or_create_control_rig_track(world,level_sequence, rig_class, actor_binding)
レイヤー化コントロール リグ
レイヤー化コントロール リグ トラックを作成する
レイヤー化コントロール リグ トラックの作成は、通常のコントロール リグ トラックの追加と同じですが、is_layered
キーワード引数 find_or_create_control_rig_track
を使用します。
# エディタのワールドを取得する
editor_system = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem)
world = editor_system.get_editor_world()
# コントロール リグ アセットを取得する
rig = unreal.load_asset("/Game/Animation/ControlRig/Mannequin_ControlRig")
# リグ クラスを取得する
rig_class = rig.get_control_rig_class()
# レベル シーケンスおよびアクタのバインディングを使用すると、クラスからコントロール リグ トラックを見つける、または作成することができる
rig_track = unreal.ControlRigSequencerLibrary.find_or_create_control_rig_track(world, level_sequence, rig_class, actor_binding, is_layered_control_rig = True)
コントロール リグがレイヤー化されているか確認する
コントロール リグがレイヤー化されているかどうかを判断する必要がある場合、ControlRigSequencerBindingProxy
インスタンスのコントロール リグ オブジェクトから確認できます。
# シーケンサーの最初のコントロール リグを取得し、次にリグ オブジェクトを取得する
rig_proxy = unreal.ControlRigSequencerLibrary.get_control_rigs(level_sequence)[0]
rig = rig_proxy.control_rig
print(unreal.ControlRigSequencerLibrary.is_layered_control_rig(rig))
リグ評価の順序を変更する
複数のコントロール リグをレイヤー化し、優先順位を変更することができます。サブシーケンスの階層的バイアスと同様に、レイヤー化されたコントロール リグは、大きな番号から順に評価します。たとえば、FKControlRig
が 100
に設定され、CR_Mannequin_Body
が 99
に設定される場合、FKControlRig
が最初に評価されます。
# シーケンサーの内のリグを取得する
rigs = unreal.ControlRigSequencerLibrary.get_control_rigs(level_sequence)
# 各リグをループする
for rig in rigs:
rig_track = rig.track
rig_obj = rig.control_rig
# 優先順位を取得し、設定する
print(unreal.ControlRigSequencerLibrary.get_control_rig_priority_order(rig_track))
unreal.ControlRigSequencerLibrary.set_control_rig_priority_order(rig_track, 200)
レイヤー化モードを変更する
以下のとおり、リグ トラックで変更することによってもモードを変更できます。
unreal.ControlRigSequencerLibrary.set_control_rig_layered_mode(rig_track, True)
セクションをマスキングする
一部の制御のみを表示したいセクションでは、以下のとおり、Python 内でマスキングを設定できます。
# コントロール リグ トラックおよびキー設定するセクションを取得
ls = unreal.LevelSequenceEditorBlueprintLibrary.get_current_level_sequence()
rig = unreal.ControlRigSequencerLibrary.get_control_rigs(ls)[0]
rig_track = rig.track
keyed_section = rig_track.get_section_to_key()
# キー設定されたセクションでこれらの特定の制御を非表示にする
ctrls = ["thigh_l_fk_ctrl", "calf_l_fk_ctrl", "foot_l_fk_ctrl", "ball_l_fk_ctrl"]
unreal.ControlRigSequencerLibrary.set_controls_mask(keyed_section, ctrls, False)
# すべてのコントロールを表示する
unreal.ControlRigSequencerLibrary.show_all_controls(keyed_section)
コントロールをアニメーション化する
次の例では、コントロールを編集およびアニメーション化するさまざまな方法について説明します。
コントロールの選択
これらのコマンドを使用して、コントロールを選択し、コントロールの選択をクエリできます。
# シーケンサーのコントロール リグを取得し、ControlRigSequencerBindingProxy のリストを返す
rig_proxies = unreal.ControlRigSequencerLibrary.get_control_rigs(level_sequence)
# Mannequin_ControlRig であることを想定し、最初のプロキシを取得する
rig_proxy = rig_proxies[0]
# ControlRigSequencerBindingProxy から ControlRig オブジェクトを取得できる
rig = rig_proxy.control_rig
# 指定されたコントロールを選択する
rig.select_control("body_ctrl")
# 現在のコントロールの選択内容を取得する
selected_controls = rig.current_control_selection()
print(selected_controls)
# コントロールの選択内容をクリアする
rig.clear_control_selection()
コントロール値を取得および設定する
次のコマンドを使用して、任意のフレーム番号の任意のコントロールから特定の値を取得できます。
# シーケンサーのコントロール リグを取得し、ControlRigSequencerBindingProxy のリストを返す
rig_proxies = unreal.ControlRigSequencerLibrary.get_control_rigs(level_sequence)
# フレーム 0 を取得する
frame_num = unreal.FrameNumber(0)
# 最初のプロキシを取得 - プロキシは Mannequin_ControlRig と想定
rig_proxy = rig_proxies[0]
# ControlRigSequencerBindingProxy から ControlRig オブジェクトを取得できる
rig = rig_proxy.control_rig
# ローカルのコントロール値を取得し、コントロールの型はそれぞれ独自の型の関数を持つようにする
transform = unreal.ControlRigSequencerLibrary.get_local_control_rig_transform(level_sequence, rig, "body_ctrl", frame_num)
bool = unreal.ControlRigSequencerLibrary.get_local_control_rig_bool(level_sequence, rig, "twist_ctrl_vis", frame_num)
print(transform)
print(bool)
次のコマンドを使用して、任意のフレーム番号で任意のコントロールに特定の値を設定することもできます。
# シーケンサーのコントロール リグを取得し、ControlRigSequencerBindingProxy のリストを返す
rig_proxies = unreal.ControlRigSequencerLibrary.get_control_rigs(level_sequence)
# 最初のプロキシを取得 - プロキシは Mannequin_ControlRig と想定
rig_proxy = rig_proxies[0]
# ControlRigSequencerBindingProxy から ControlRig オブジェクトを取得できる
rig = rig_proxy.control_rig
# 現在の時間を取得する
current_time = unreal.LevelSequenceEditorBlueprintLibrary.get_current_time()
# 現在の時間を FrameNumber オブジェクトに変換する
current_frame = unreal.FrameNumber(current_time)
# コントロールに適切な値のオブジェクトを作成する
transform_value = unreal.Transform(location=[0, 10, 20], rotation=[0,30,0], scale=[1,1,1])
bool_value = True
# ローカルのコントロール値を設定し、コントロールの型はそれぞれ独自の型の関数を持つようにする
# 型が設定された関数はそれぞれ、デフォルトでは True の set_key フラグも持つ
unreal.ControlRigSequencerLibrary.set_local_control_rig_transform(level_sequence, rig, "body_ctrl", frame_num, transform_value)
unreal.ControlRigSequencerLibrary.set_local_control_rig_bool(level_sequence, rig, "twist_ctrl_vis", frame_num, bool_value, set_key = False)
キーフレーム
選択したキーフレームをクエリする
# 選択項目があると仮定し、選択されたキーからチャンネルを取得する
keyed_channels = unreal.LevelSequenceEditorBlueprintLibrary.get_channels_with_selected_keys()
# 選択したキーを取得する
selected_keys = unreal.LevelSequenceEditorBlueprintLibrary.get_selected_keys(keyed_channels[0])
# チャンネル オブジェクトを取得中
channel_obj = keyed_channels[0].section.get_channel(keyed_channels[0].channel_name)
# キー インデックスをキー オブジェクトに変換する
key_objs = channel_obj.get_keys_by_index(selected_keys)
# 選択したキーからすべての時間値を出力する
for key_obj in key_objs: print(key_obj.get_time().frame_number.value)
キーフレーム選択項目を編集する
以下の例では、hand_l_fk_ctrl
のキーでマネキン/MH コントロール リグを使用するレベル シーケンスがあると仮定します。
ls = unreal.LevelSequenceEditorBlueprintLibrary.get_current_level_sequence()
start_frame = ls.get_playback_start()
end_frame = ls.get_playback_end()
# コントロール リグを取得する
rig = unreal.ControlRigSequencerLibrary.get_control_rigs(ls)[0]
rig_track = rig.track
keyed_section = rig_track.get_section_to_key()
# シンプルなチャンネル名を提供し、チャンネル プロキシを取得中
sc = unreal.SequencerChannelProxy()
sc.section = keyed_section
sc.channel_name = 'hand_l_fk_ctrl.Location.X'
# チャンネル オブジェクトを取得し、すべてのキー オブジェクトを取得する
channel_obj = keyed_section.get_channel('hand_l_fk_ctrl.Location.X')
keys = channel_obj.get_keys()
# 選択するキーのために配列を空にする
timed_keys = []
# すべてのキーをループする
for key in keys:
# キー時間を取得する
key_time = key.get_time().frame_number.value
# キーの時間が開始フレーム直後と終了フレーム直前かどうかを確認する
if key_time >= start_frame+1 and key_time <= end_frame-1:
# 配列にキーを追加する
timed_keys.append(keys.index(key))
# キーを選択する
unreal.LevelSequenceEditorBlueprintLibrary.select_keys(sc, timed_keys)
カーブ エディタ
# カーブ エディタを取得中
ses = unreal.get_editor_subsystem(unreal.LevelSequenceEditorSubsystem)
curve_editor = ses.get_curve_editor()
if not curve_editor.is_curve_editor_open(): curve_editor.open_curve_editor()
# 選択したキーとチャンネルを取得する
keyed_channels = curve_editor.get_channels_with_selected_keys()
selected_keys = curve_editor.get_selected_keys(keyed_channels[0])
curve_editor.empty_selection()
# すべてのキーを再選択する
curve_editor.select_keys(selected_keys)
# チャンネル オブジェクトを取得中
channel_obj = keyed_channels[0].section.get_channel(keyed_channels[0].channel_name)
# キー インデックスをキー オブジェクトに変換する
key_objs = channel_obj.get_keys_by_index(selected_keys)
# 選択したキーのすべての時間を出力する
for key_obj in key_objs: print(key_obj.get_time())
# カーブ エディタを閉じる
curve_editor.close_curve_editor()
コントロール リグ セクションにアニメーション シーケンスを読み込む
level_sequence = unreal.LevelSequenceEditorBlueprintLibrary.get_focused_level_sequence()
rig_proxies = unreal.ControlRigSequencerLibrary.get_control_rigs(level_sequence)
rig_proxy = rig_proxies[0]
sequencer_binding_proxy = rig_proxy.proxy
# アニメーションを挿入するフレーム
start_frame = unreal.FrameNumber(0)
# コントロール リグからムービーシーン セクションを集める
cr_tracks = sequencer_binding_proxy.find_tracks_by_type(unreal.MovieSceneControlRigParameterTrack)
cr_movie_scene_section = cr_tracks[0].get_section_to_key()
# 適用するアニメーションを取り込む
anim_sequence = "/Game/Characters/Mannequins/Animations/Manny/MM_Walk_Fwd"
anim_sequence = unreal.load_asset(anim_sequence)
# スケルタルメッシュ コンポーネントを取得する
seq_bindings = level_sequence.get_bindings()
playback_range = level_sequence.get_playback_range()
editor_system = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem)
world = editor_system.get_editor_world()
bound_objects = unreal.SequencerTools.get_bound_objects(world, level_sequence, seq_bindings, playback_range)
# 注:最初のバウンド オブジェクトにスケルタルメッシュがあると仮定する
skel_mesh_comp = bound_objects[0].bound_objects[0].skeletal_mesh_component
# アニメーションを CR に読み込む (内部のバックワード ソルブ グラフを使用する)
unreal.ControlRigSequencerLibrary.load_anim_sequence_into_control_rig_section(cr_movie_scene_section, anim_sequence, skel_mesh_comp, start_frame, reset_controls = True)
アニメーション モード
アニメーション モードのツール には、Python スクリプトの影響も反映されます。次の例が用意されています。
Tween ツール
次のコマンドは Tween ツール に使用することができます。
# -1 から 1 のトゥイーン値を設定する
# -1 は前のフレームにブレンドする
# 1 は次のフレームにブレンドする
tween_value = -1
unreal.ControlRigSequencerLibrary.tween_control_rig(level_sequence, rig, tween_value)
Snapper ツール
次のコマンドは Snapper ツール に使用することができます。ドライバ オブジェクトがアニメーション化されている場合は、ドライバ オブジェクトをアクティブ シーケンスに追加する必要があります。
# シーケンサーのコントロール リグを取得し、ControlRigSequencerBindingProxy のリストを返す
rig_proxies = unreal.ControlRigSequencerLibrary.get_control_rigs(level_sequence)
# 最初のプロキシを取得 - プロキシは Mannequin_ControlRig と想定
rig_proxy = rig_proxies[0]
# ControlRigSequencerBindingProxy から ControlRig オブジェクトを取得できる
rig = rig_proxy.control_rig
# エディタのアクタ サブシステムを取得し、アクタを追加する
editor_actor_subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
# キューブをエディタのワールドに追加し、位置を設定する
cube_mesh = unreal.load_asset("/Engine/BasicShapes/Cube")
cube_location = unreal.Vector(0, 10, 20)
cube_actor = editor_actor_subsystem.spawn_actor_from_object(cube_mesh, cube_location)
# 開始および終了フレームの範囲を設定する
start_frame = unreal.FrameNumber(0)
end_frame = unreal.FrameNumber(5)
# 親および子の ControlRigSnapperSelection オブジェクトを作成する
parent = unreal.ControlRigSnapperSelection()
children = unreal.ControlRigSnapperSelection()
# ActorForWorldTransforms オブジェクトを作成する
# キューブ アクタを親として設定する
parent_actor = unreal.ActorForWorldTransforms()
parent_actor.actor = cube_actor
# ControlRigForWorldTransforms オブジェクトを作成する
# 適切なコントロール リグを設定し、左手コントロールをコントロールとして設定する
# ここでは、複数のコントロール名を使用可能
child_control_rig = unreal.ControlRigForWorldTransforms()
child_control_rig.control_rig = rig
child_control_rig.control_names = ["hand_l_ctrl"]
# ActorForWorldTransforms オブジェクトを取得し、親 ControlRigSnapperSelection として設定する
# ControlRigForWorldTransforms オブジェクトを取得し、子 ControlRigSnapperSelection として設定する
parent.actors = [parent_actor]
children.control_rigs = [child_control_rig]
# スナップ設定を作成および設定する
snap_settings = unreal.ControlRigSnapSettings()
snap_settings.keep_offset = False
snap_settings.snap_position = True
snap_settings.snap_rotation = True
snap_settings.snap_scale = False
# 続いて、フレーム 0 から 5 のキューブに左手コントロールをスナップする
unreal.ControlRigSequencerLibrary.snap_control_rig(level_sequence, start_frame, end_frame, children, parent, snap_settings)
空間の切り替え
次のコマンドと例は、空間の切り替え に使用することができます。
空間の切り替えを開始するには、空間のキーフレームを作成する必要があります。コントロールの空間は、デフォルトの親、ワールド空間、または任意のフレーム番号での別のコントロールに設定できます。
# シーケンサーのコントロール リグを取得し、ControlRigSequencerBindingProxy のリストを返す
rig_proxies = unreal.ControlRigSequencerLibrary.get_control_rigs(level_sequence)
# 最初のプロキシを取得 - プロキシは Mannequin_ControlRig と想定
rig_proxy = rig_proxies[0]
# ControlRigSequencerBindingProxy から ControlRig オブジェクトを取得できる
rig = rig_proxy.control_rig
# 左手コントロールの空間をワールド空間のフレーム 0 に設定する
control_name = "hand_l_ctrl"
space = unreal.ControlRigSequencerLibrary.get_world_space_reference_key()
time = unreal.FrameNumber(value = 0)
unreal.ControlRigSequencerLibrary.set_control_rig_space(level_sequence, rig, control_name, space, time)
# その後、空間の切り替えをフレーム 30 で頭のコントロールに設定する
space = unreal.RigElementKey(type = unreal.RigElementType.CONTROL, name = "head_ctrl")
time = unreal.FrameNumber(value = 30)
unreal.ControlRigSequencerLibrary.set_control_rig_space(level_sequence, rig, control_name, space, time)
# 最後に、空間の切り替えをフレーム 60 でデフォルトの親に設定する
space = unreal.ControlRigSequencerLibrary.get_default_parent_key()
time = unreal.FrameNumber(value = 60)
unreal.ControlRigSequencerLibrary.set_control_rig_space(level_sequence, rig, control_name, space, time)
空間のキーフレームを作成したら、以下のコマンドを使用して任意のフレーム番号に移動可能
# シーケンサーのコントロール リグを取得し、ControlRigSequencerBindingProxy のリストを返す
rig_proxies = unreal.ControlRigSequencerLibrary.get_control_rigs(level_sequence)
# 最初のプロキシを取得 - プロキシは Mannequin_ControlRig と想定
rig_proxy = rig_proxies[0]
# ControlRigSequencerBindingProxy から ControlRig オブジェクトを取得できる
rig = rig_proxy.control_rig
# Set Space Key の例から、空間のキーは左手コントロールの 0、30、および 60 に
# あると想定しましょう。空間のキーをフレーム 30 から 45 に移動しましょう
control_name = "hand_l_ctrl"
old_time = unreal.FrameNumber(value = 30)
new_time = unreal.FrameNumber(value = 45)
unreal.ControlRigSequencerLibrary.move_control_rig_space(level_sequence, rig, control_name, old_time, new_time)
空間のキーフレームは、以下のコマンドを使用して削除可能
# シーケンサーのコントロール リグを取得し、ControlRigSequencerBindingProxy のリストを返す
rig_proxies = unreal.ControlRigSequencerLibrary.get_control_rigs(level_sequence)
# 最初のプロキシを取得 - プロキシは Mannequin_ControlRig と想定
rig_proxy = rig_proxies[0]
# ControlRigSequencerBindingProxy から ControlRig オブジェクトを取得できる
rig = rig_proxy.control_rig
# Move Space Key の例から、空間のキーは左手コントロールの 0、345、および 60 に
# あると想定しましょう。空間のキーをフレーム 45 から削除しましょう
control_name = "hand_l_ctrl"
time = unreal.FrameNumber(value = 45)
unreal.ControlRigSequencerLibrary.delete_control_rig_space(level_sequence, rig, control_name, time)
次のコマンドを使用して、最終的なアニメーションを特定の空間にベイク処理できます。
# シーケンサーのコントロール リグを取得し、ControlRigSequencerBindingProxy のリストを返す
rig_proxies = unreal.ControlRigSequencerLibrary.get_control_rigs(level_sequence)
# 最初のプロキシを取得 - プロキシは Mannequin_ControlRig と想定
rig_proxy = rig_proxies[0]
# ControlRigSequencerBindingProxy から ControlRig オブジェクトを取得できる
rig = rig_proxy.control_rig
# 選択済みのすべてのリグ コントロールを取得する
control_names = rig.current_control_selection()
# レベル シーケンスの開始および終了フレームを取得し、ベイク設定用に FrameNumber オブジェクトを設定する
start_frame_num = level_sequence.get_playback_start()
end_frame_num = level_sequence.get_playback_end()
start_frame = unreal.FrameNumber(value = start_frame_num)
end_frame = unreal.FrameNumber(value = end_frame_num)
# 空間のベイク設定を行い、デフォルトの親空間にベイクする
space_bake_settings = unreal.RigSpacePickerBakeSettings()
space_bake_settings.target_space = unreal.ControlRigSequencerLibrary.get_default_parent_key()
space_bake_settings.start_frame = start_frame
space_bake_settings.end_frame = end_frame
space_bake_settings.reduce_keys = False
space_bake_settings.tolerance = 0
unreal.ControlRigSequencerLibrary.bake_control_rig_space(level_sequence, rig, control_names, space_bake_settings)
アニメーション モードの設定
Python スクリプトを使って アニメーション モードの設定 を編集することができます。各プロパティは次の用語を使用します。
名前 | 説明 |
---|---|
bDisplayHierarchy | キャラクターにボーンを描画します。 |
bDisplayNulls | キャラクターに Null を描画します。 |
bHideManipulators | ビューポートですべてのコントロールを非表示にします。[Display Hierarchy] または [Display Nulls] をオンにしている場合、ボーンと Null も非表示にします。 |
bCoordSystemPerWidgetMode | ビューポート内でギズモ モードを変更すると座標空間が復元されます。 |
bOnlySelectRigControls | これを有効にすると、ビューポート内でコントロール リグ コントロールのみが選択可能になります。キャラクターを含む他のすべてのオブジェクトは選択できません。 |
bLocalTransformsInEachLocalSpace | オンにすると、トランスフォーム ギズモがローカル座標に設定されている場合、選択した各コントロールをそれぞれのローカル トランスフォーム空間を基準にトランスフォームします。 |
GizmoScale | ギズモ スケールを大きくまたは小さくします。 |
以下のコマンドを使用することができます。
# モード設定クラスをロードし、デフォルトのオブジェクトを取得する
ControlRigSettingsClass = unreal.load_class(None, '/Script/ControlRigEditor.ControlRigEditModeSettings')
ControlRigSettings = unreal.get_default_object(ControlRigSettingsClass)
# クエリされたデータを出力する
print(ControlRigSettings.get_editor_property('bDisplayHierarchy'))
print(ControlRigSettings.get_editor_property('bDisplayNulls'))
print(ControlRigSettings.get_editor_property(GizmoScale))
# プロパティを設定する
ControlRigSettings.set_editor_property('bDisplayHierarchy', True)
ControlRigSettings.set_editor_property('bDisplayNulls', True)
ControlRigSettings.set_editor_property('GizmoScale', 5)
コンストレイント
コンストレイントは、あるオブジェクトと別のオブジェクト間の関係を作成するために使用します。これは、アニメーション オーサリングに役立ちます。コンストレイントは、アニメーションおよび非アニメーション シナリオに追加できます。
シーケンサーなしのキューブに Camera Look At 制約を持たせる
import unreal
# カメラを作成する
camera_location = unreal.Vector(0.0,0.0,200.0)
camera_actor = unreal.EditorLevelLibrary().spawn_actor_from_class(unreal.CineCameraActor, camera_location)
camera_actor.set_actor_label('CineCameraActor')
# キューブを作成する
obj = unreal.load_asset("/Engine/BasicShapes/Cube")
cube_location = unreal.Vector(400.0,0.0,200.0)
cube_actor = unreal.EditorLevelLibrary().spawn_actor_from_object(obj, cube_location)
cube_actor.set_actor_label('CubeActor')
# エディタのワールドを取得する
world = unreal.EditorLevelLibrary().get_editor_world()
# コンストレイント ライブラリを作成する
constraints_lib = unreal.ConstraintsScriptingLibrary()
# カメラに子ハンドルを作成する
child_handle = constraints_lib.create_transformable_component_handle(world, camera_actor.root_component, "")
# キューブに親ハンドルを作成する
parent_handle = constraints_lib.create_transformable_component_handle(world, cube_actor.root_component, "")
# コンストレイントを作成し、追加する (これは、必要に応じてコンストレイント マネージャーを作成することに留意してください)
look_at_constraint = constraints_lib.create_from_type(world, unreal.TransformConstraintType.LOOK_AT)
constraints_lib.add_constraint(world, parent_handle, child_handle, look_at_constraint, True)
シーケンサーありのキューブに Control Rig Control Parent 制約を持たせる
# 現在のレベル シーケンスを取得する
level_sequence = unreal.LevelSequenceEditorBlueprintLibrary.get_current_level_sequence()
# シーケンサーのコントロール リグを取得し、ControlRigSequencerBindingProxy のリストを返す
rig_proxies = unreal.ControlRigSequencerLibrary.get_control_rigs(level_sequence)
# 最初のプロキシを取得 - プロキシは Mannequin_ControlRig と想定
rig_proxy = rig_proxies[0]
# ControlRigSequencerBindingProxy から ControlRig オブジェクトを取得できる
rig = rig_proxy.control_rig
# 最初に選択された制御を取得する
selected_ctrl = rig.current_control_selection()[0]
# 制御を駆動するキューブを作成する
obj = unreal.load_asset("/Engine/BasicShapes/Cube")
cube_location = unreal.Vector(400.0,0.0,200.0)
cube_actor = unreal.EditorLevelLibrary().spawn_actor_from_object(obj, cube_location)
# ワールド位置を取得する
world = unreal.EditorLevelLibrary().get_editor_world()
# コンストレイント スクリプト ライブラリ オブジェクトを作成する
constraints_lib = unreal.ConstraintsScriptingLibrary()
# コントロール リグ制御の子ハンドルを作成する
child_handle = rig.create_transformable_control_handle(selected_ctrl)
# キューブの親ハンドルを作成する
parent_handle = constraints_lib.create_transformable_component_handle(world, cube_actor.root_component, "")
# 親コンストレイント オブジェクトを作成する
parent_constraint = constraints_lib.create_from_type(world, unreal.TransformConstraintType.PARENT)
# ハンドルで制約を追加し、オフセットを維持をオフにする
constraints_lib.add_constraint(world, parent_handle, child_handle, parent_constraint, False)
ベイクとマージ
コントロール リグへベイクする
シーケンサーのアクタにすでにアニメーション シーケンスがある場合は、現在のアニメーションをコントロール リグにベイク処理することで、Control Rig トラックを作成できます。これを行うには、次のコマンドを使用します。
# 現在のエディタ レベルを取得する
editor_system = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem)
world = editor_system.get_editor_world()
# アニメーション シーケンスのエクスポート オプションを取得する
anim_seq_export_options = unreal.AnimSeqExportOption()
anim_seq_export_options.export_transforms = True
anim_seq_export_options.export_curves = True
# キーの許容範囲の番号およびキー削減のステートを取得する
tolerance = 0.01
reduce_keys = False
# コントロール リグへベイクする
unreal.ControlRigSequencerLibrary.bake_to_control_rig(world, level_sequence, rig_class, anim_seq_export_options, False, tolerance, actor_binding)
アニメーション シーケンスへベイクする
コントロール リグ アニメーションが完了したら、次のコマンドを使用して、アニメーションをアニメーション シーケンスとしてエクスポートし、Unreal Engine の他の領域で使用できます。
# 現在のレベル シーケンスを取得する
level_sequence = unreal.LevelSequenceEditorBlueprintLibrary.get_current_level_sequence()
# SK Mannequin という名前の SkeletaMeshActor バインディングを取得する
# これは、Mannequin_ControlRig をレベル エディタにドラッグした際のデフォルトの名前です
binding = level_sequence.find_binding_by_name("SK Mannequin")
# レベル エディタのワールドを取得する
editor_subsystem = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem)
world = editor_subsystem.get_editor_world()
# アニメーション シーケンスのエクスポート オプションを作成する
anim_seq_export_options = unreal.AnimSeqExportOption()
anim_seq_export_options.export_transforms = True
anim_seq_export_options.export_morph_targets = True
# アセット ツールを取得する
# 空の AnimSequence を作成する - /Game/Test_Anim
asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
anim_sequence = unreal.AssetTools.create_asset(asset_tools, asset_name = "Test_Anim", package_path = "/Game/", asset_class = unreal.AnimSequence, factory = unreal.AnimSequenceFactory())
# 作成した AnimSequence へベイクする
unreal.SequencerTools.export_anim_sequence(world, level_sequence, anim_sequence, anim_seq_export_options, binding, False)
# リンクされたアニメーション シーケンスを作成する場合は、単純に最後の引数を True に変更する
unreal.SequencerTools.export_anim_sequence(world, level_sequence, anim_sequence, anim_seq_export_options, binding, True)
アニメーション レイヤーをマージする
Control Rig トラック内で複数のセクションとレイヤーを使用している場合は、次の折りたたみコマンドを使用して、アニメーションをベイク処理して 1 つのレイヤーにマージできます。
# シーケンサーのコントロール リグを取得し、ControlRigSequencerBindingProxy のリストを返す
rig_proxies = unreal.ControlRigSequencerLibrary.get_control_rigs(level_sequence)
# 最初のプロキシを取得 - プロキシは Mannequin_ControlRig と想定
rig_proxy = rig_proxies[0]
# ControlRigSequencerBindingProxy から MovieSceneControlRigParameterTrack オブジェクトを取得できる
# このトラックを使用し、トラック内のすべてのセクションを 1 つのセクションに折りたたむことができる
rig_track = rig_proxy.track
unreal.ControlRigSequencerLibrary.collapse_control_rig_anim_layers
(level_sequence, rig_track, key_reduce = False, tolerance = 0.001)
レベル シーケンスからリンク済みアニメーション シーケンスにアクセスする
# まず、現在のレベル シーケンスを取得します
level_sequence = unreal.LevelSequenceEditorBlueprintLibrary.get_current_level_sequence()
# それから、アニメーション シーケンスへのリンクがあるか確認します
link_check = unreal.SequencerTools.get_anim_sequence_link_from_level_sequence(level_sequence)
# ある場合
if link_check:
# リンクを取得する
links = link_check.anim_sequence_links
# 各リンクをループする
for link in links:
# ソフト オブジェクト パスを取得する
anim_seq_soft_path = link.path_to_anim_sequence
# アセットを取得するため解決する
anim_seq = unreal.SystemLibrary.conv_soft_obj_path_to_soft_obj_ref(anim_seq_soft_path)
アニメーション シーケンスからリンク済みレベル シーケンスにアクセスする
# 「Content」フォルダに Test_Anim というリンク済みアニメーション シーケンスがあると仮定します
anim_seq = unreal.load_object("/Game/Test_Anim")
# リンクがあるか確認します
link = unreal.SequencerTools.get_level_sequence_link_from_anim_sequence(anim_seq)
# ある場合
if link:
# ソフト オブジェクト パスを取得する
level_seq_soft_path = link.path_to_level_sequence
# アセットを取得するため解決する
level_seq = unreal.SystemLibrary.conv_soft_obj_path_to_soft_obj_ref(level_seq_soft_path)
FBX エクスポートとインポート
FBX エクスポート
# レベル シーケンスとリグ セクションを取得する
ls = unreal.LevelSequenceEditorBlueprintLibrary.get_current_level_sequence()
rig = unreal.ControlRigSequencerLibrary.get_control_rigs(ls)[0]
rig_track = rig.track
keyed_section = rig_track.get_section_to_key()
filename = "D:/test.fbx"
# ファイル名でエクスポート FBX 設定を作成する
export_fbx_settings = unreal.MovieSceneUserExportFBXControlRigSettings()
export_fbx_settings.set_editor_property("ascii", True)
export_fbx_settings.set_editor_property("export_file_name", filename)
# コントロール リグ FBX をエクスポートする
unreal.ControlRigSequencerLibrary.export_fbx_from_control_rig_section(ls, keyed_section, export_fbx_settings)
FBX のインポート
# レベル シーケンス、リグ トラックとリグ セクション、エディタ ワールドを取得する
ls = unreal.LevelSequenceEditorBlueprintLibrary.get_current_level_sequence()
rig = unreal.ControlRigSequencerLibrary.get_control_rigs(ls)[0]
rig_track = rig.track
keyed_section = rig_track.get_section_to_key()
editor_system = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem)
world = editor_system.get_editor_world()
# import_onto_selected_controls が True に設定されているときのみ機能する、選択済み制御のリストを作成する
selected_ctrls = ["thigh_l_fk_ctrl", "calf_l_fk_ctrl", "foot_l_fk_ctrl", "ball_l_fk_ctrl"]
# インポート設定オブジェクトを作成し、設定とファイル名を割り当てる
import_fbx_settings = unreal.MovieSceneUserImportFBXControlRigSettings()
import_fbx_settings.set_editor_property("import_onto_selected_controls", True)
import_fbx_settings.set_editor_property("insert_animation", True)
fbx_file = "D:/test.fbx"
# コントロール リグ FBX をインポートする
unreal.ControlRigSequencerLibrary.import_fbx_to_control_rig_track(world, ls, rig_track, keyed_section, selected_ctrls, import_fbx_settings, fbx_file)
アニメーション モード ウィンドウを編集する
レベル エディタおよびシーケンサーでコントロール リグをアニメートする場合、[Animation Mode (アニメーション モード)] ウィンドウが開き、アニメーターが必要なツールとオプションが表示されます。これらのオプションは Python でも編集可能です。
[Animation Mode] ウィンドウには次のプロパティが含まれます。
- bDisplayHierarchy:コントロール リグの各制御とボーンにラインとドットを描きます
- bDisplayNulls:コントロール リグの各 null にラインとドットを描きます
- bHideManipulators:すべての制御を非表示にし、コントロール リグで表示します
- bCoordSystemPerWidgetMode:平行移動、回転、縮尺モードごとのローカル/グローバル空間マニピュレータ状態を維持するオプション
- bOnlySelectRigControls:コントロール リグ制御のビューポート セレクションのみを許可します
- bLocalTransformsInEachLocalSpace:複数の選択した制御をトランスフォームする場合、各制御はそれぞれのローカル空間でトランスフォームします
- GizmoScale:ビューポート ギズモ マニピュレータの縮尺を変更します
# モード設定クラスをロードし、デフォルトのオブジェクトを取得する
ControlRigSettingsClass = unreal.load_class(None, '/Script/ControlRigEditor.ControlRigEditModeSettings')
ControlRigSettings = unreal.get_default_object(ControlRigSettingsClass)
# クエリされたデータを出力する
print(ControlRigSettings.get_editor_property('bDisplayHierarchy'))
print(ControlRigSettings.get_editor_property('bDisplayNulls'))
print(ControlRigSettings.get_editor_property(GizmoScale))
# プロパティを設定する
ControlRigSettings.set_editor_property('bDisplayHierarchy', True)
ControlRigSettings.set_editor_property('bDisplayNulls', True)
ControlRigSettings.set_editor_property('GizmoScale', 5)