Python+编辑器扩展
mainMenu = menus.find_menu('LevelEditor.MainMenu') // 找到主菜单
ownerName = mainMenu.get_name()
# 该名称用于标识一个菜单下的分区名,如果menu的sectionName一致,它们会被放在一起
sectionName = 'PythonTools'
subMenuName = 'MenuTest'
subMenuLabel = 'MenuTest1'
subMenuTip = 'This is menutest1'
menus.add_sub_menu(ownerName, sectionName, subMenuName, subMenuLabel, subMenuTip)
# 刷新窗口
menus.refresh_all_widgets()
想要查看ue编辑器内的各个sectionname,可以在EditorPreference中的Misc中打开相应配置,打开一个菜单时会刷新对应的widget,如果想要窗口全部刷新则可以执行如下python命令
py unreal.ToolMenus.get().refresh_all_widgets()
menus = unreal.ToolMenus.get()
# 根据上面的subMenuName找到目标菜单
targetMenu = menus.find_menu('LevelEditor.MainMenu.MenuTest')
menuEntry = unreal.ToolMenuEntry(type=unreal.MultiBlockType.MENU_ENTRY)
menuEntry.set_label('Test Button 1')
menuEntry.set_string_command(unreal.ToolMenuStringCommandType.PYTHON, '', 'print('this is button 1')')
sectionname = ''
targetMenu.add_menu_entry(sectionname, menuEntry)
menus.refresh_all_widgets()
按钮的命令:
unreal.ToolMenuStringCommandType.PYTHON,后面的字符串为python代码;
unreal.ToolMenuStringCommandType.COMMAND,后面的字符串为cmd命令,如使用py xxx.py执行脚本;
等同于输出日志中的python控制台和cmd控制台的py命令;
# 和上面的两个区别,首先是targetMenu,然后是Entry的类型
targetMenu = menus.find_menu('LevelEditor.ToolEditorToolBar')
menuEntry = unreal.ToolMenuEntry(type=unreal.MultiBlockType.TOOL_BAR_BUTTON)
targetMenu = unreal.ToolMenus.get('ContentBrowser.FolderContextMenu')
entry = unreal.ToolMenuEntry(type=unreal.MultiBlockType,MENU_ENTRY)
# 选中的资源
unreal.ContentBrowserAssetContextMenuContext.get_selected_objects()
可以用如下方式获取选中的actor,但是无法像蓝图一样将actor强转到相应的派生类,因此也就无法获取到实例actor的属性以及不能调用相应的函数;目前的python是不支持这个的,可参考:https://answers.unrealengine.com/questions/938515/casting-a-blueprint-in-python.html;
只能调用actor类已有的内置函数,如set_actor_location()等;
assets = unreal.EditorLevelLibrary.get_selected_level_actors()
for actor in assets:
但是可以修改bp的默认值,如下所示:
我们需要调用unreal.get_default_object来获取CDO(Class Default Object),然后使用set_editor_property来完成功能;
bp_class = unreal.load_class(None, '/Game/NewBlueprint.NewBlueprint_C')
cdo = unreal.get_default_object(bp_class)
cdo.set_editor_property('var', 102)
cdo.call_method('TestFunc', (actor,))
上述列出的问题虽然python内不能解决,但是能够通过蓝图扩展来完成;
基于python的扩展依然还只是在pie中使用;
如果需要在项目中处理资源,必须使用Unreal Python API来完成,而不能使用Python内置模块来处理磁盘资源文件,比如资源的移动,如果不适用unreal的api则会导致引用失效,所以要尽量使用unreal.EditorAssetLibrary或unreal.AssetTools
尽可能使用虚幻类型
比如数学类等,要尽可能使用Unreal API提供的类型,如unreal.Vector()
os.open/read/write
import json
json.dumps/loads
资源相关的api都在这个库里:unreal.EditorAssetLibrary
资源的保存:save_asset()
系统库:unreal.SystemLibrary
获取项目路径:get_project_directory()
本想使用ue4的api来打开一个文件对话框,但是没有找到,网上有一些使用C++的扩展;
因此就想到了pyqt5也可以完成,而且ue4也可以调用python,这样就不用在C++层处理了,但是这只能用于编辑器模式下;
import unreal
import os
import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QToolTip, QPushButton, QMessageBox, QDesktopWidget, QFileDialog, QLabel)
class Example(QFileDialog):
def __init__(self):
super().__init__()
self.open_folder()
def open_folder(self):
path = QFileDialog.getExistingDirectory(self, u'选择文件夹', unreal.SystemLibrary.get_project_directory())
print(path)
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.quit())
一些模块没有找到是因为我们需要安装对应的插件
我们可以使用如下方式可以遍历到unreal下所有的子模块
import unreal
moduels = dir(unreal)
for module in modules:
print(module)