Unreal Pythonを使ったオブジェクトの配置とマテリアルの設定まで
UEでpython使ってみた。という記事はヒットするけれど、その先のちょっとした使い方までとなると検索力不足のためか中々見つからなかった。『UE5で星空を作る』の前段階としてUnreal Pythonの始め方からオブジェクトの配置・マテリアルの設定までを記録しておく
0. Unreal Pythonの始め方
ハローワールド
Output Log
のドロップダウンメニューからPython
を選択すると使える
ファイルを実行する準備
pythonスクリプトを作成するディレクトリを適当な場所に作成してAdditional Paths
へパスを追加する。この時Developer Mode
にチェックを入れてstubファイルを生成するとTextエディタのオートコンプリートに使用できる
VScodeの設定
VScodeの設定でpythonオートコンプリートにUE5が生成したstubのpathを指定する
ファイルのimportとreload
import [ファイル名(py抜き)]
でインポートとスクリプトの実行がされる。ファイルを編集を反映させるにはimportlib
のreload
が必要になる
1. 目標
- コンテンツブラウザからアセットを選択
- 選択したアクターをワールドに配置
- 配置したアクターのマテリアルを設定
2. 結果
3.ソース
import unreal def get_Basic_ShapeData(shape:str) -> unreal.AssetData: """ベーシックシェイプの名前からAssetDataを返す shape : 'Cube', 'Sphere', 'Plane' .. """ EAL = unreal.EditorAssetLibrary shapeList = EAL.list_assets('/Engine//BasicShapes') for shapePath in shapeList: if(shape in shapePath): shapeData = EAL.find_asset_data(shapePath) return shapeData def create_StaticMeshActor_from_BasicShapeData(assetData:unreal.AssetData, x:float, y:float, z:float) -> unreal.StaticMeshActor: """StaticMeshActorをワールドにスポーン、生成したアクターを返す assetData: ベーシックシェイプのアセットデータ return: 生成したアクター """ EAS = unreal.EditorActorSubsystem() return EAS.spawn_actor_from_object(assetData.get_asset(), location=[x, y, z]) def set_New_Material(actor:unreal.Actor, materialName:str): """アクターに新しいマテリアルをセットする actor: ワールド内に配置されているアクター materialName: Content下に保存されているアセット名 """ materialObj = None EAL = unreal.EditorAssetLibrary assetList = EAL.list_assets('/Game') for path in assetList: if(materialName in path): materialObj = EAL.find_asset_data(path).get_asset() smc = get_Static_Mesh_Component(actor) smc.set_material(0, materialObj) def get_Static_Mesh_Component(actor:unreal.StaticMeshActor) -> unreal.StaticMeshComponent: """インテリセンスが効かないので get_editor_propertyをラップした関数 """ return actor.get_editor_property("static_mesh_component") def set_position(actor:unreal.StaticMeshActor, x:float, y:float, z:float): newlocation = unreal.Vector(x, y, z) actor.set_actor_location(newlocation, False, False) def resize_actor(actor:unreal.StaticMeshActor, size:float): newSize = unreal.Vector(size,size,size) actor.set_actor_scale3d(newSize) def rename_actor(actor:unreal.StaticMeshActor, label:str): actor.set_actor_label(label) # サンプル用の処理 def test(): shape = get_Basic_ShapeData('Cone') newActor = create_StaticMeshActor_from_BasicShapeData(shape, 0, 0, 100) set_New_Material(newActor, 'M_Ground_Moss') rename_actor(newActor,'HappyCone') resize_actor(newActor, 2.5)
4. ソースのメモ
基本は以下の2つのクラスを使用していく
EditorAssetLibrary
: コンテンツブラウザを操作するEditorActorSubsystem
:アウトライナーを操作する感じ?
アセットpathのリストの取得
EAL = unreal.EditorAssetLibrary shapeList = EAL.list_assets('/Engine//BasicShapes')
たまたまベーシックシェイプの場所はEngineディレクトリ下だったので問題はなかったが、Content
ディレクトリの場合は/Game
とする必要がある
インテリセンスが効いたり効かなかったり
smc = get_Static_Mesh_Component(actor) smc.set_material(0, materialObj) def get_Static_Mesh_Component(actor:unreal.StaticMeshActor) -> unreal.StaticMeshComponent: return actor.get_editor_property("static_mesh_component")
もともとこの部分はactor.get_editor_property("static_mesh_component").set_material(0, materialObj)
とまとめて書いてたが、プロパティ部分の操作でインテリセンスが効かないのが不安なので戻り値のクラスを指定する関数でラップした。
5. 感想
記事にするまでpythonの戻り値の型指定を知らなかったレベルの素人がいうのもなんだけどプロパティをドキュメントで調べないと指定できなかったりクラスを継承しまくりで使いづらいなぁという印象。使いこなすうちに慣れるはず・・・