文档:https://dev.epicgames.com/documentation/zh-cn/unreal-engine/scripting-the-unreal-editor-using-python?application_version=5.4

只能写编辑器工具,不能运行时使用。

配置

UE中设置

UE插件开启Editor Scripting Utilities和Python Editor Script Plugin;

项目设置中(最好是在编辑器偏好设置中)Python分类下打开开发者模式,不然无法代码补全;

VS Code

安装Unreal Engine Python扩展

安装Python扩展,打开扩展设置,点击在settings.json中编辑,添加以下配置:

1
2
3
4
5
6
"python.autoComplete.extraPaths": [
"YOUR_PROJECT_PATH/Intermediate/PythonStub"
],
"python.analysis.extraPaths": [
"YOUR_PROJECT_PATH/Intermediate/PythonStub"
],

其中YOUR_PROJECT_PATHYOUR_ENGINE_PATH替换为自己的工程路径与引擎路径。

若本地找不到PythonStub文件夹,则是工程未打开开发者模式,或是打开后没有重启导致的。

在内容浏览器中显示Python文件

在编辑器偏好设置中Python分类下打开启用内容浏览器整合,在Content文件夹下新建Python文件夹,在其中的py文件都可以显示可以运行。

远程执行

UE项目设置中python分类下打开远程执行,并在下面设置组播相关参数。

在VSC的Unreal Engine Python扩展设置中,设置对应的Multicast参数。

写完代码后Ctrl+Enter即可远程执行。

使用

可以从蓝图往过抄

设置编辑器属性

要使用set_editor_property,不能直接设置不然会出问题。如设置Actor位置要:

1
2
pos = act.get_actor_location()
act.root_component.set_editor_property("relative_location", pos + unreal.Vector(0, 0, 10))

每个类的Editor Properties可以在API文档每个类的介绍文件中找到;

获取Actor

使用Get All Actor Of Class需要传入World Context Object,可以使用下面的方法:

1
2
3
actor_sub = unreal.get_editor_subsystem(unreal.EditorActorSubsystem) 
all_actors = unreal.EditorFilterLibrary.by_class(actor_sub.get_all_level_actors(), unreal.Actor)
select_actors = unreal.EditorFilterLibrary.by_class(actor_sub.get_selected_level_actors(), unreal.StaticMeshActor)

进度条

1
2
3
4
5
6
7
8
9
import unreal 
total_frames = 100
text_label = "Working!"
with unreal.ScopedSlowTask(total_frames, text_label) as slow_task:
slow_task.make_dialog(True) # 如果对话不可见,使其可见
for i in range(total_frames):
if slow_task.should_cancel(): break # 如果用户已在UI中按了"取消(Cancel)"则为True
slow_task.enter_progress_frame(1) # 使进度前进一帧。 # 如果希望,也可以更新本调用中的对话文本。
# 在此处执行针对当前帧的工作!

创建结构体与枚举值

Python in Unreal Engine — The undocumented parts

1
2
3
4
5
6
7
8
9
10
@unreal.ustruct()
class STestStruct(unreal.StructBase):
value = unreal.uproperty(float)
texture = unreal.uproperty(unreal.Texture2D)
material = unreal.uproperty(unreal.MaterialInterface)

@unreal.uenum()
class ETestEnum(unreal.EnumBase):
ENUM_0 = unreal.uvalue(0)
ENUM_1 = unreal.uvalue(1)

Python函数库

1
2
3
4
5
6
7
8
@unreal.uclass()
class PythonTestClass(unreal.BlueprintFunctionLibrary):

@unreal.ufunction(static = True, params = [int], ret = STestStruct)
def MyPythonFunction(integer_argument1):
struct = STestStruct()
struct.value = 5
return struct

打开资产编辑器、编辑器工具控件

1
2
3
asset = unreal.EditorAssetLibrary.load_asset("/EditorExtensionTools/WBP_YOUR_TOOL")
subsystem: unreal.AssetEditorSubsystem = unreal.get_editor_subsystem(unreal.AssetEditorSubsystem)
subsystem.open_editor_for_assets([asset], unreal.AssetTypeActivationOpenedMethod.EDIT)
1
2
3
asset = unreal.EditorAssetLibrary.load_asset("/EditorExtensionTools/WBP_YOUR_TOOL")
subsystem: unreal.EditorUtilitySubsystem = unreal.get_editor_subsystem(unreal.EditorUtilitySubsystem)
subsystem.spawn_and_register_tab(asset)

绑定事件

https://dev.epicgames.com/documentation/en-us/unreal-engine/python-api/class/MulticastDelegateBase?application_version=5.4#unreal.MulticastDelegateBase

1
2
3
4
5
6
import_sub: unreal.ImportSubsystem = unreal.get_editor_subsystem(unreal.ImportSubsystem)
def bind_reimport_event(bind: bool = True):
if(bind):
import_sub.on_asset_reimport.add_callable_unique(rebuild_sm_lod)
else:
import_sub.on_asset_reimport.remove_callable(rebuild_sm_lod)

API

https://docs.unrealengine.com/5.4/en-US/PythonAPI/