1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Unreal Engine (UE)Advent Calendar 2024

Day 3

Pythonからジオメトリキャッシュを登録する

Last updated at Posted at 2024-12-02

この記事は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にそのままコピペして使用してもらえれば、動きます。

ジオメトリキャッシュは、事前にプロジェクト内に作成しておいてください。

geometrycache_examples.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』には、ジオメトリキャッシュのオブジェクトを渡してください。

ブループリントの設定.png

ブループリントの全体だと以下のようなになります。
『CacheGeometryCache』は、ジオメトリキャッシュタイプです。

サンプルのブループリント.png

上の写真は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

明日は、alweiさんです。よろしくお願いいたします!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?