この記事はUnreal Engine (UE) Advent Calendar 2024の3日目の記事です。
UnrialEngineでPythonをさわる機会があり、少し勉強してみました。
折角なので、何かテーマを決めようと思い、レベルシーケンスにスケルタルメッシュを登録するサンプルはありますが、ジオメトリキャッシュを登録するサンプルは無かった為、今回は、それを作成してみました。
確認環境
Windows 11 Pro
UnrealEngine 5.3.2
Pythonサンプル
Pythonサンプルは、以下のフォルダにあります。
\エンジンルート\Engine\Plugins\MovieScene\SequencerScripting\Content\Python
サンプルは以下のものが用意されています。
Pythonの書き方やクラスの使い方の雰囲気は、読み取れると思います。
- sequencer_anim_examples.py
- sequencer_examples.py
- sequencer_fbx_examples.py
- sequencer_key_examples.py
- sequencer_tools_examples.py
作成したスクリプト
ここからが、本題です。
サンプルとして作成したものは以下のスクリプトです。
.pyにそのままコピペして使用してもらえれば、動きます。
ジオメトリキャッシュは、事前にプロジェクト内に作成しておいてください。
import unreal
# Name : bind_geometrycache
# Param1 : level_sequence // LevelSequence class
# Param1 : geometry_cache_asset // GeometryCache class
def bind_geometrycache(level_sequence, geometry_cache_asset):
unreal.log(unreal.SystemLibrary.get_display_name(level_sequence))
unreal.log(unreal.SystemLibrary.get_display_name(geometry_cache_asset))
# check LevelSeqeunce
if level_sequence != None:
level_sequence = unreal.LevelSequenceEditorBlueprintLibrary.get_current_level_sequence()
# LevelSequence framerate
fps_rate = 24
# main
if level_sequence != None:
unreal.log(unreal.SystemLibrary.get_display_name(level_sequence))
# levelsequence param
level_sequence.set_display_rate(unreal.FrameRate(fps_rate,1))
# Bind Class
if geometry_cache_asset != None:
possessable = level_sequence.add_spawnable_from_instance(geometry_cache_asset)
#
# Add geometrycache track
#
geometrycache_track = possessable.add_track(unreal.MovieSceneGeometryCacheTrack)
start_frame = geometry_cache_asset.get_editor_property('start_frame')
end_frame = geometry_cache_asset.get_editor_property('end_frame')
geometrycache_section = geometrycache_track.add_section()
# MovieSceneGeometryCacheParams Document
# https://dev.epicgames.com/documentation/en-us/unreal-engine/python-api/class/MovieSceneGeometryCacheParams?application_version=5.4#unreal.MovieSceneGeometryCacheParams
params = unreal.MovieSceneGeometryCacheParams()
# The animation this section plays
params.set_editor_property("geometry_cache_asset",geometry_cache_asset)
# The offset for the first loop of the animation clip
# params.set_editor_property("first_loop_start_frame_offset ", unreal.FrameNumber(0)) # 5.3 runtime error
params.first_loop_start_frame_offset = unreal.FrameNumber(0)
# The offset into the beginning of the animation clip
# params.set_editor_property("start_frame_offset ", unreal.FrameNumber(0)) # 5.3 runtime error
params.start_frame_offset = unreal.FrameNumber(0)
# The offset into the end of the animation clip
# params.set_editor_property("end_frame_offset ", unreal.FrameNumber(0)) # 5.3 runtime error
params.end_frame_offset = unreal.FrameNumber(0)
# The playback rate of the animation clip
# params.set_editor_property("play_rate ", 1) # 5.3 runtime error
params.play_rate = 1
# Reverse the playback of the animation clip
# params.set_editor_property("reverse ", False) # 5.3 runtime error
params.reverse = False
geometrycache_section.set_editor_property("Params", params)
geometrycache_section.set_range(start_frame, end_frame)
#
# Add transform track
#
transform_track = possessable.add_track(unreal.MovieScene3DTransformTrack)
transform_section = transform_track.add_section()
transform_section.set_range(start_frame, end_frame)
# refresh levelsequence
unreal.LevelSequenceEditorBlueprintLibrary.refresh_current_level_sequence()
説明
- 基本的には、『Spawnable ➡ トラックの追加 ➡ セクションの追加 ➡ パラメータの設定』という流れです
- スケルタルメッシュにしろ、ジオメトリキャッシュにしろ、他のトラックにしろ、流れは変わらないですが、設定する『トラック』と『セクション』と『パラメータ』が変わってきます
- 一つ注意して欲しい点は、『トラックの追加関数は、トラックの追加しかされない』『セクションの追加は、セクションの追加関数しかされない』されません。何気なく行っているドラック&ドロップでレベルシーケンスにアクターを配置する事を再現するだけでも、結構コードを書く必要があります。
スクリプトの動かし方
スクリプトの呼び出しは、『ExecutePythonScript』で行っています。
『level_sequence』には、レベルシーケンスを、『geometry_cache_asset』には、ジオメトリキャッシュのオブジェクトを渡してください。
ブループリントの全体だと以下のようなになります。
『CacheGeometryCache』は、ジオメトリキャッシュタイプです。
上の写真はWidgetのブループリントになります。
注意点
UnrealPythonをさわる上での注意点です。
-
プラグインの追加
プラグインの追加に関しては、こちらの記事を参考にしてください。 -
Pythonを認識させ方
デフォルトのパスについては、こちらの記事を見てもらうのが良いかと思います。
『.py』をパスのフォルダにおいても、認識されず、以下のエラーが発生します。
LogScript: Error: Script Msg: Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'ActasPython'
LogScript: Error: Script call stack:
/Game/Test.Test_C.ExecuteUbergraph_Test <---
/Game/Test.Test_C.BndEvt__Test_EditorUtilityButton_0_K2Node_ComponentBoundEvent_0_OnButtonClickedEvent__DelegateSignature
LogBlueprintUserMessages: [Test_C_10] @@@ Success
その為、一度、エディタを再起動してください。再起動すると、.pycが作成され、スクリプトが認識されます。
-
スクリプトの修正
スクリプトを修正したのに、反映されていないと思ったら、エディタを立ち上げ直してください。
私が詳しくないだけですが、ホットリロードができるかも知れません。 -
名前の取得
私は、デバッグで、ログに名前をよく出力するのですが、『GetDisyplayName』『GetObjectName』を取るのか最初分かりませんでした。
-
親子関係
クラスの親子関係は、以下のようになっており、ほとんどのクラスの基底クラスは『_ObjectBase』となっているようです。
#基底クラスは、_ObjectBase
_ObjectBase → Object → StreamableRenderAsset → SkinnedAsset → SkeletalMesh
_ObjectBase → ActorComponent → SceneComponent → PrimitiveComponent → MeshComponent → SkinnedMeshComponent → SkeletalMeshComponent
_ObjectBase → Object → AnimationAsset → AnimSequenceBase → AnimSequence
_ObjectBase → Object → Actor
_ObjectBase → Object → MovieSceneSignedObject → MovieSceneSequence
#これだけ違う
object → _WrapperBase → StructBase → MovieSceneBindingProxy
最後に
Pythonを丁度さわっていたので、今回はUnrealPythonの記事を投稿してみました。
シリーズ3の5日目の記事にブループリントで同じことをやる場合の記事を投稿します。興味ある方は、そちらも見て、Pythonとブループリントでの書き方の違いを比較してください。
参考URL
- [UE4] Pythonを使って、開発を自動化してみよう!
- 【UE4】【Python】4.26からPythonPluginがPython3.7.7に対応したので色々まとめてみた 【★★~★★★★】
- UE4 Sequencer Python Cookbook
- Python を使用した Unreal Editor のスクリプティング
- Python Scripting in Sequencer
- Unreal Python API Documentation
明日は、alweiさんです。よろしくお願いいたします!