検証バージョン:UE4.26.2, UE4.27.2
#1. 概要
Pythonを利用してEngineクラスにアクセスする方法は以下のドキュメントにあります。
https://docs.unrealengine.com/4.27/ja/ProductionPipelines/ScriptingAndAutomation/Python/
本記事ではプロジェクトに作成したC++クラスの変数や関数にアクセスする例を示します。
#2. 目標
最終的にやりたいことは**「コンテンツブラウザから選択した"C++クラス (AMyActor) を継承したBlueprintクラス (BP_MyActor) "に対してPython経由で変数をセットしたりネイティブ関数の呼び出しを行う」**です。
【BP_MyActorの親クラスの内容】
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
USTRUCT(BlueprintType)
struct FMyStruct
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TArray<FVector> VecArray;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool BoolValue;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float FloatValue;
};
UCLASS()
class MYPROJECT_API AMyActor : public AActor
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UStaticMesh* MyStaticMesh;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FMyStruct MyStruct;
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
void TestFunction();
};
#include "MyActor.h"
void AMyActor::TestFunction_Implementation()
{
UE_LOG(LogTemp, Warning, TEXT("Call TestFunction"));
}
最終的にBlueprintの変数は以下のようになることを期待するとします。
#3. Python実装
Pythonの実装は以下のようになります。
【前提】
・Plugin: Python Editor Script Pluginを有効にする
・Plugin: Editor Scripting Utilitiesを有効にする
import unreal
import sys
import os
@unreal.uclass()
class MyEditorUtility(unreal.EditorUtilityLibrary):
pass
# Content Browserで選択したアセットを検索
selected_assets = MyEditorUtility().get_selected_assets()
for i, selected_asset in enumerate(selected_assets):
# アセットパス取得 (target_path="/Game/BP_MyActor.BP_MyActor")
target_path = selected_asset.get_path_name()
# アセットのロード
load_asset = unreal.EditorAssetLibrary.load_asset(target_path)
# Blueprint GC(generated class)取得
# (Blueprintの場合は"_C"を付与 path="/Game/BP_MyActor.BP_MyActor_C")
bp_gc = unreal.load_object(None, target_path + "_C")
# Blueprint CDO(class default object)取得
bp_cdo = unreal.get_default_object(bp_gc)
# 元の構造体を取得
my_struct = bp_cdo.get_editor_property("MyStruct")
# 構造体のbool型変数に設定
my_struct.set_editor_property("BoolValue", True)
# 構造体のfloat型変数に設定
my_struct.set_editor_property("FloatValue", 100.0)
# 構造体のVector配列に要素1追加
points = my_struct.get_editor_property("VecArray")
point = unreal.Vector(1.0,1.0,1.0)
points.append(point)
# StaticMeshにアセット/Game/Coneを設定
static_mesh_path = "/Game/Cone"
# Coneをロード
static_mesh = unreal.EditorAssetLibrary.load_asset(static_mesh_path)
# StaticMeshの変数にアセットを設定
bp_cdo.set_editor_property("MyStaticMesh", static_mesh)
# TestFunction関数の呼び出し
bp_cdo.test_function()
# 構造体をCDOに設定
bp_cdo.set_editor_property("MyStruct", my_struct)
# アセットを保存
unreal.EditorAssetLibrary.save_loaded_asset(load_asset)
ポイントはBlueprintアセットを扱う場合"_C"を付与することや、構造体や関数にアクセスする場合はGC/CDOを経由する必要があるということです。これらに注意しておけばEngineクラスと同様に容易にアクセスすることが可能です。