找回密码
 立即注册
查看: 439|回复: 0

搭建Python开发Unreal Engine编辑器工具环境

[复制链接]
发表于 2022-1-6 17:07 | 显示全部楼层 |阅读模式
PRE:工作环境准备



  • UE环境:新建UE4项目【PythonToolStudy.uproject】用于测试
  • Python环境:在python官网下载安装python 3.7.9环境
https://www.python.org/

  • 好用的IDE环境:推荐 VSCode 或者 Pycharm
一、为项目配置Python插件环境


打开项目,在插件管理器中启用Python编辑器脚本插件(Python Editor Script Plugin)





Python编辑器脚本插件(Python Editor Script Plugin)包含Python 3.7.7 的嵌入式版本
这意味着无需在计算机上单独安装Python
默认情况下虚幻编辑器使用Python 3.7.7,因为它是当前VFX参考平台的重要组成部分。引擎仍然支持Python 2.7,但你需要在引擎中更改版本才能使用。
如果需要更改Python版本,你可以在操作系统中将`UE_PYTHON_DIR`环境变量设置为指向要嵌入的安装程序,然后从源代码重新编译虚幻引擎。

二、运行Python的方式



1. 按照国际惯例我们先写一个测试脚本和世界打个招呼~


2. 在编辑器中运行这个脚本有两种方式:

    • 点击【文件】→【执行Python脚本】,选择对应的文件即可执行



    2. 点击【窗口】→【开发者工具】→【输出日志】,将下方的输入框切换为【Cmd】模式
输入:py "F:/ljx/UnrealProjects/PythonScripts/HelloWorld.py"

3. 在编辑器中调试Python语句的方式:

    • 将输入框切换为【Python】模式,直接输入需要调试的语句
    • 通过使用 Shift+Enter 来分隔每一行或者通过粘贴从文本编辑器复制的多行代码块可以一次运行多行代码



  • 在Python中使用print函数,输出会重定向到UE编辑器输出日志中,如下图。



  • 配置初始化脚本
如果编辑器在任何已配置其使用的路径中检测到名称为`init_unreal.py`的脚本文件(请参阅下面的"虚幻编辑器中的Python路径"),编辑器会立即运行该脚本。
如果你的脚本也需要随编辑器自启,可以在项目设置中进行配置。




  • 虚幻编辑器会自动向该`sys.path`列表中添加几个路径:
项目文件夹下的 Content/Python 子文件夹。
主虚幻引擎安装文件夹中的 Content/Python 子文件夹。
每个启用的插件的文件夹下的 Content/Python 子文件夹。
用户目录中的 Documents/UnrealEngine/Python 文件夹。例如,在Windows 10中,该路径是`C:/Users/Username/Documents/UnrealEngine/Python`


三、在编辑器脚本中执行Python脚本



如何使用编辑器脚本可参考下文:
https://docs.unrealengine.com/4.26/zh-CN/ProductionPipelines/ScriptingAndAutomation/Blueprints/ScriptedActions/

本文只提及如何在编辑器脚本中执行Python脚本,实际上只涉及三个蓝图节点。
知道名字就好了,后面的介绍官方文档都有,嘿嘿。
稍微讲一下:

  • Execute Script是用来运行Python代码的
  • Execute Command可以运行代码也可以运行文件,系统智能判断是python代码还是文件,文件路径可以是绝对路径也可以是系统路径(上面提到过有哪些)
  • Execute Script(Advanced)是可以指定填入的字符串是代码还是文件,可以拿到命令结果和运行返回值,还可以打Log(毕竟高级)






四、以资源导入功能为例



import unreal

def build_static_mesh_import_options():
    """
    构建导入静态网格选项
    :return :options 导入静态网格选项
    """
    options = unreal.FbxImportUI()

    options.set_editor_property('import_mesh', True)
    options.set_editor_property('import_materials', True)
    #是否当成骨骼网格体导入
    options.set_editor_property('import_as_skeletal', False)
    options.static_mesh_import_data.set_editor_property('import_translation', unreal.Vector(0.0, 0.0, 0.0))
    options.static_mesh_import_data.set_editor_property('import_rotation', unreal.Rotator(0, 0, 0))
    options.static_mesh_import_data.set_editor_property('import_uniform_scale', 1.0)

    options.static_mesh_import_data.set_editor_property('combine_meshes', True)
    options.static_mesh_import_data.set_editor_property('generate_lightmap_u_vs', True)
    options.static_mesh_import_data.set_editor_property('auto_generate_collision', True)

    return options

def creatImportTask(filename, destination_path, options=None):
    """
        :param filename: 导入的文件的路径  eg: 'F:\ljx\plugins\export\C_ChengshiYX-BDF_SKM+1P.fbx'
        :param destination_path: 导出后资产要放在什么位置 eg: '/GAME/Meshs'
        :param options: 导入资产属性,静态属性可由函数build_static_mesh_import_options获得
                        骨骼属性可由build_skeletal_mesh_import_options获得
        :return: Task 返回一个导入任务
    """
    importtask = unreal.AssetImportTask()
    importtask.set_editor_property("automated", True)
    importtask.set_editor_property('destination_name', '')
    importtask.set_editor_property('destination_path', destination_path)
    importtask.set_editor_property('filename', filename)
    importtask.set_editor_property('replace_existing', False)  # 是否覆盖现有文件
    importtask.set_editor_property('options', options)  # 覆盖现有文件
    importtask.set_editor_property('save', False)
    return importtask

def execute_import_tasks(tasks):
    """
    执行导入任务
    :param tasks: array 任务池
    :return: True
    """
    asset_tools = unreal.AssetToolsHelpers.get_asset_tools()  # 创建一个资产工具
    asset_tools.import_asset_tasks([tasks])  # 导入资产


import_files = "F:\\ljx\\plugins\\export\\C_ChengshiYX-BDF_SKM+1P.fbx"

destination_path = "/Game/Meshs"
options = build_static_mesh_import_options()

import_task = creatImportTask(import_files ,  destination_path , options )
execute_import_tasks(import_task )

  • 上面的代码就干了一件事:  把"F:\\ljx\\plugins\\export\\C_ChengshiYX-BDF_SKM+1P.fbx" 作为静态网格体导入"/Game/Meshs"  注:在UE编辑器中/Game = /Content
  • result:


具体的不解释了,都在API里,顺便吐槽一下Unreal Python API这个页面风格是不是过于老旧了。。

五、python生成蓝图动态节点库



按照上面的方法在python内获取用户输入是比较困难的,只能通过执行python脚本的命名*args添加参数,找到一个神仙写法,就是在python里写ue函数节点,这个节点还可以自定义输入和输入,甚至可以以params传参,params是可以自定义参数结构的。

  • Use unreal.log() for information messages. For your convenience, the Python print() function has also been implemented to pass through unreal.log() internally.
  • Use unreal.log_warning() to alert users of potential problems.
  • Use unreal.log_error() for severe problems that prevent your script from running as expected.
import unreal
import os
import tkinter as tk
from tkinter import filedialog


@unreal.uclass()
class library(unreal.BlueprintFunctionLibrary):
    #打开文件对话框
    @unreal.ufunction(ret = str, static = True, meta = dict(Category="PythonFunctions"))
    def OpenFileDialog():
        root = tk.Tk()
        root.withdraw()
        filePath = filedialog.askopenfilename()
        return filePath.replace('/','\\')
    #带返回值和参数的函数这样写     
    @Unreal.ufunction(ret = [str], params = [str], static = True, meta = dict(Category="KControlRigTools|Python"))

运行这个脚本,在编辑器蓝图中就可以找到【OpenFileDialog】这个节点。


参考文档

https://docs.unrealengine.com/4.26/zh-CN/ProductionPipelines/ScriptingAndAutomation/Python/
https://docs.unrealengine.com/4.26/en-US/PythonAPI/

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-6-9 09:14 , Processed in 0.106227 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表