Bootstrap Chameleon Logo

欢迎来到UE Python 脚本工具TAPython的主页

TA Python Tools

一款努力让“开发虚幻引擎编辑器工具”如同“开发Max脚本工具”一样简单的插件

Widgets Gallery

Extended Python Editor interfaces

Overview

TAPython是一个虚幻引擎的工程插件,通过TAPython,可以快速为Python工具创建菜单、基于UE原生Slate的界面,同时该插件提供了160+个常用的编辑器工具接口,使得开发UE编辑器工具变得非常简单和高效。

Tools Preview

功能特色

  • 使用UE4原生Python
  • 动态创建UE Slate控件窗口,支持39+控件类型
  • 可配置的主菜单/工具栏/Content Brower 菜单
  • 类Slate语法的界面描述文件,动态实时预览界面效果
  • 不改引擎,无需Editor UMG支持,兼容低版本UE4
  • 160+ 额外的编辑器常用接口

Sketch Editing Gif

如何安装

依赖

本插件使用UE 内置Python插件:官方文档 Scripting the Editor using Python

Python plugin

安装步骤

  1. TAPython release repo @github 页面右侧的release中下载对应版本的插件,并解压到<Your_UE_Project>\Plugins

release

    Your_UE_Project
    ├── Content                         
    ├── ...
    └── Plugins                        
        └── TAPython       # <--- 插件放这里
            ├── Binaries                     
            ├── Config                     
            └── Content                   
            └─ ...

  1. 启动工程, 打开项目设置 - 插件 python - additional path, 将 <Your_UE_Project>/TA/TAPython/Python 添加到addition path. 重启编辑器 Project Setting Image
  2. 当点击主菜单上的Sketch或者Gallery工具后,点击:

SketchIconOnMainBar

正确情况应该能看到如下图的绿色标志,和“Python Path Ready” 字样 Python Path Is Ready

如看到红色叉叉,请检查上面的设置项。正确的情况下,看到的是应是如下绿色的提示

Python Path Is not Ready

快速开始

在插件包中,默认包含了若干菜单项和4个演示用的工具

最新的DefaultResource也可以在DefaultResources@github 下载

菜单项

  • 右键选中目录或空白处时 Content Browser 中的右键菜单
  • 右键选中资源时 Content Browser 中的右键菜单
  • 主菜单项
  • 工具栏上的图标

menu gifs

Sketch Tool 工具

005_sketch_icon_on_mainbar

Sketch Tool 是一个特别的界面草稿工具,当 <Your_UE_Project&gt\TA\TAPython\Python\ChameleonSketch\ChameleonSketch.json 这个文件被修改时,界面的内容会实时更新。这个在编写工具界面时候会非常有用,它把调整界面布局和参数的时间降低到最小。

G000_SketchEditing

默认的Sketch Tools 长成这样,打开ChameleonSketch.json 修改其中的内容试试,不用担心json中的语法和关键字。json和slate的语法关系在下文会由介绍

012_default_sketch


范例工具

以下所有的范例工具都是用这个插件TAPython的功能和Python编写的

013_Chameleon_menu

Tool 1: MinimalExample 最小范例

MinimalExample

这是工具演示了,创建标准的UE Slate界面,界面调用Python代码,Python代码中完成计数,并将结果反馈给界面。

这个工具的一共包括了一个30行的.json文件,一个一个15行的python文件

在下文中,我们将这种通过本插件创建Slate的界面的工具统称为Chameleon Tools

MinimalExample.json:

    {
        "TabLabel": "Example",
        "InitTabSize": [200, 123],
        "InitTabPosition": [680, 150],
        "InitPyCmd": "import Example; chameleon_example = Example.MinimalExample.MinimalExample(%JsonPath)",
        "Root":
        {
            "SVerticalBox":
            {
                "Slots": [
                    {
                        "SButton": {
                            "Text": "Click Me",
                            "HAlign": "Center",
                            "VAlign": "Center",
                            "OnClick": "chameleon_example.on_button_click()"
                        }
                    },
                    {
                        "SEditableTextBox":
                        {
                            "IsReadOnly": true,
                            "Aka": "InfoOutput",
                            "Text": ""
                        }
                    }
                ]
            }
        }
    }

MinimalExample.py

    # -*- coding: utf-8 -*-
    import unreal
    from Utilities.Utils import Singleton


    class MinimalExample(metaclass=Singleton):
        def __init__(self, jsonPath:str):
            self.jsonPath = jsonPath
            self.data = unreal.PythonBPLib.get_chameleon_data(self.jsonPath)
            self.ui_output = "InfoOutput"
            self.clickCount = 0

        def on_button_click(self):
            self.clickCount += 1
            self.data.set_text(self.ui_output, "Clicked {} time(s)".format(self.clickCount))

Tools 2 Shelf 工具栏

Shelf 是一个快捷栏工具演示,类似于Maya的shelf工具。

用户可以把多种类型的内容拖拽到工具栏中,点击按钮,可以执行对应的功能

shelf gif

Type Action
asset 在content Brower中选中该资源
folder 在Content Brower中进入该目录
actors 在场景中选中这些actors
text(python snippet) execute as python code
chamelon工具的json文件 打开Chameleon 工具

当然你也可以修改点击的这些按钮的行为,做出更丰富的工具


Tool 2 Object Detail Viewer 物体详细信息查看工具

Object Detail Viewer

Object Detail Viewer 是一个快速现实物体内属性及其数值的工具,双击可以进入其子属性查看子属性的数值。并且支持两个物体之间的比较,这对快速熟悉UE UObject对象是很有帮助的。该工具主要演示SListView的使用

Object Detail Viewer use

Gallery 工具演示了常用的控件及其在json文件中的写法,其他具体支持的控件和API可以参考here

Gallery Gif

使用文档

Entry 入口

所有菜单项和菜单的配置入口在 <Your_UE_Project>\TA\TAPython\UI\MenuConfig.json 这个文件中。

添加菜单项

下面这个MenuConfig.json中的片段将在主菜单中创建过一个按钮

```
"OnMainMenu":
{
    "name": "Python Menu On Main Menu",
    "items":
    [
        {
            "name": "TA Python Example",
            "items": [
                {
                    "name": "Example (4): Waiting for your tools",
                    "command": "print('Hello world')"
                }
            ]
        }
    ]
},
```

menu_main_small

Keywords in MenuConfig.json:

"OnSelectFolderMenu": ContentBrower中选中目录,或点击空白区域时右键菜单入口

"OnSelectAssetsMenu": ContentBrower中选中资源时右键菜单入口

"OnMainMenu": 主菜单中的菜单项入口

"OnToolbar": 主工具栏菜单入口,图标为Python,通常只在其中放置没有界面的python 工具

"OnToolBarChameleon": Chameleon 工具图标入口,图标是个绿色的变色龙,通常在其中放置有界面的Chameon 工具

"items": Array 类型,其中的各元素为子菜单项,可嵌套成树状

"name": 菜单项显示名

"command": 绑定到菜单项的python代码,支持import文件,并调用其中的函数

"ChameleonTools" 需要调用的Chameleon Tools是json文件相对路径

    "ChameleonTools": "../Python/Example/MinimalExample.json"

"enabled": 是否启用该菜单项,设置为false时会隐藏该菜单项

"canExecuteAction": Python Code,该菜单项是否可被执行,用于对根据上下文(例如选中不同的资源),设置菜单项是否可被执行

"tooltip": 鼠标悬停时的工具提示

创建Chameleon Tools

该功能可以根据UI文件(.json)动态创建使用原生Slate代码的UE4编辑器界面。并将界面于Python工具代码绑定,实现数据的双向互通。无需编译,可实时预览。

支持的控件

当前支持41个常用控件,后续还在持续添加中。

C++ Slate链式编程语法转Json Slate的方法

简单来说有以下几条规则:

  1. 省略SNew,直接写控件名,SAssignNew(ButtonPicture, SImage); 转换成"SImage":{"Aka": "ButtonPicture"}

  2. 对于通过 "SAssignNew"来赋值的控件,使用"Aka" 关键字来替代。例如:SAssignNew(ButtonPicture, SImage) 将变成 "SImage":{"Aka": "ButtonPicture"}

  3. Slate中支持单个子组件的Widget中的 [] 转换成 "Content":{ }

  4. 支持多个Slots的Widget中的 +SSomewidget::Slot 转换成 "Slots": [{...}, {...} ...], 每个Slot中的子控件为Slots数组中的一个JsonObjectValue

  5. 从Style中获取Brush的写法,将转换成Style和Brush两个值

  6. Vector2, Vector4 转换成数组形式 如[1,2,3,4]

例如:

C++ code:

SNew(SBorder)
.BorderImage(FEditorStyle::Get().GetBrush("ToolPanel.DarkGroupBorder"))
[
    SNew(SSpacer)
    .Size(FVector2D(100, 50))
]

等同于 json code:

"SBorder":{
    "BorderImage":
    {
        "Style": "FEditorStyle",
        "Brush": "ToolPanel.DarkGroupBorder"
    },
    "Content": 
    {
        "SSpacer": { "Size": [100, 50] }
    }
}

另一个例子, c++ Slate code:

    SNew(SGridPanel)
        .FillColumn(0, 0.5f)
        .FillColumn(1, 0.5f)
        + SGridPanel::Slot(0, 0)
        [
            SNew(STextBlock)
            .Text(LOCTEXT("SBorderLabel", "SBorder"))

        ]
        + SGridPanel::Slot(1, 0)
        .Padding(0.0f, 4.0f)
        [
            SNew(SBorder)
            [
                SNew(SSpacer)
                .Size(FVector2D(100, 50))
            ]
        ]

等同于:

    "SGridPanel":
    {
        "FillColumn": [[0,0.5],[1,0.5]],
        "Slots":
        [
            {
                "Column_Row": [0,0],
                "STextBlock": { "Text": "SBorder" }
            },
            {
               "Column_Row": [1,0],
               "SBorder":
                {
                   "Content":
                    {
                        "SSpacer": { "Size": [100, 50] }
                    }
                }
            }
        ]
    }

其他具体可参见 控件大全 中的示例及范例中的实际应用,当然也可以联系我

Slate 控件与Python之间的通信

以MinimalExample 为例,来看下具体是如何实现的 MinimalExample

  1. 在MenuConfig.json中,添加了一个名为"Minimal Example"的菜单项,点击它是会调用 "../Python/Example/MinimalExample.json" 中定义的工具
     "OnToolBarChameleon": {
         "name": "Python Chameleon on toolbar",
         "items": [
             {
                 "name": "Minimal Example",
                 "ChameleonTools": "../Python/Example/MinimalExample.json"
             }
         ]
     }
  1. 当点击步骤1中的菜单项时,在 MinimalExample.json 中,"InitPyCmd"中的内容将被当作python代码来执行。此时会创建一个 python 类:MinimalExample的实例,并将它保存在变量chameleon_example中。注意这个变量现在在python的全局空间中,所以不同的工具要使用独特的,不容易与其他全局变量重名的变量名
    "InitPyCmd": "import Example; chameleon_example = Example.MinimalExample.MinimalExample(%JsonPath)",
  1. Chameleon Tool的基类,为 Utilities.Utils中的Singleton 单例。并在构造函数获取传入的Json文件的路径。该路径会作为该工具的唯一标识符,用于获取该工具的ChameleonData实例。同时该ChameleonData会保存在工具的变量"self.data"中, "self.data" 是重要的中介,用于和界面控件的通信,包括获取和设置控件属性等。
    from Utilities.Utils import Singleton
    class MinimalExample(metaclass=Singleton):
        def __init__(self, jsonPath:str):
            self.jsonPath = jsonPath
            self.data = unreal.PythonBPLib.get_chameleon_data(self.jsonPath)
  1. 在按钮被点击是,"OnClick"中的内容,会被执行。此时 MinimalExample 中的 on_button_click会被调用。
    "OnClick": "chameleon_example.on_button_click()"
  1. "on_button_click" 函数中,会完成按键计数,并将结果通过步骤2中提到的 "self.data" 返回给界面
    def on_button_click(self):
        self.clickCount += 1
        self.data.set_text(self.ui_output, "Clicked {} time(s)".format(self.clickCount))

在这个例子中,我们通过"self.data.set_text"修改了界面中的文字,用类似的方法,也可以获取和设置界面上的其他内容。其他更多的API可以参看 ChemeleonDataAPI

扩展的编辑器Python接口

本插件扩展了 100+ python 可调用的接口, 包括各种消息窗口,资源修改,编辑器命令等的.

完整的文档在这里

使用快捷键

  1. 修改HotkeyConfig.json中配置的内容,将ChameleonTools,或者一段Python代码绑定到快捷键上

../TA/TAPython/UI/HotkeyConfig.json

    {
        "Hotkeys":
        {
            "HotkeyA": {
                "ChameleonTools": "../Python/ChameleonGallery/ChameleonGallery.json"
            },
            "HotkeyB": {
                "command": "unreal.EditorLevelLibrary.set_selected_level_actors([actor for actor in unreal.EditorLevelLibrary.get_all_level_actors() if len(str(actor.get_name())) > 60])"
            },
            "HotkeyC": {
                "command": "print('Hotkey C')"
            },
            "HotkeyD": {
                "command": "print('Hotkey D')"
            },
            "HotkeyE": {
                "command": "print('Hotkey E')"
            }
        }
    }
  1. 在ProjectSetting - Keyboard Shortcuts 中的TAPython Plugin中指定快捷键 short cut settings

在这个例子中,当按下 "Alt + Shift + G"时,就会打开"ChameleonGallery" 工具

Configs

<Your_UE_Project>TA\TAPython\Config\config.ini

    [Settings]
    MenuConfigFilePath=/TA/TAPython/UI/MenuConfig.json
    ChameleonDataFolder=/Game/TA/ChameleonTools

    [Advanced]
    MainbarExtensionHookName=Game
    MainMenuExtensionHookName=WindowLayout
    MenusOnToolbarEnabled=True
    SketchToolsEnabled=True
名称 用途
MenuConfigFilePath 工具配置文件的总入口
ChameleonDataFolder 废弃了
MainbarExtensionHookName 主工具栏图标位置
MainMenuExtensionHookName 主菜单项创建的位置
MenusOnToolbarEnabled 是否显示主工具栏上的菜单项
SketchToolsEnabled 是否启用Sketch工具,谁会想要关掉这么好的功能呢?Doge

<Your_UE_Project>\Plugins\TAPython\Config\Plugin_Config.ini

    [Advanced]
    CopyInitialResource=True
名称 用途
CopyInitialResource 是否将初始内容包拷贝到工程目录

当插件启动时,如果在工程目录中找不到"TA"目录,就会将<Your_UE_Project>\Plugins\TAPython\Resources\DefaultPythonSource 目录中的初始资源拷贝到工程目录下,以确保插件能够有基本的功能和正常运行

强烈建议不要修改这个选项,除非你是高手,使用初始包作为开始,然后修改和添加i自己的工具,是快速熟悉这个插件最快的方法。

FAQ

Q0. 支持UE4吗?

A: 支持, 事实上这个插件是从4.21开始开发的. 如果不出意外,很快将放出4.26和4.27版本的插件.

Q1. 打开工程时遇到如下弹窗提示

MissingModule

这是因为本地工程使用的引擎的BuidID,与我发布这个插件时使用的引擎不同。

可以通过修改插件中的BuildId来避免弹窗,前提是引擎的大版本与发布的插件版本相同。

具体步骤步骤来处理(当然,如果你的引擎改了很多的底层代码,比如修改了CreatePackage的函数签名,那就无法用这个方式来解决了) 1. 在上面的弹出对话框中选"否" 2. 找到当前使用的引擎的BuildId,具体做法:用文本工具打开\Engine\Binaries\Win64 目录中的UnrealEditor.modules(如果是UE4,那么文件名是UE4Editor.modules),找到 "BuildId", 以下文为例:16433597 就是 BuildId.

    {
        "BuildId": "16433597",
        "Modules": 
        {
            ...
        }
        ...
    }
    ```

3. 打开&lt;Your_UE_Project&gt;\Plugins\TAPython\Binaries\Win64\UnrealEditor.modules(UE4 工程的话是UE4Editor.modules).将其中**BuildId**项中的内容指定为步骤3 中获取的**BuildId**,保存文件. 重新打开工程即可
```json
    {
        "BuildId": "16433597",
        "Modules": 
        {
            "TAPython": "UE4Editor-TAPython.dll"
        }
        ...
    }

问题2. 执行菜单项后,没有反应

检查Project Setting - Plugin Pyhton 确保当前工程 <Your_UE_Project>/TA/TAPython/Python 目录已经被添加到了additional python path中 Steps 这里

检查方法:

  • 打开Chameleon Gallery,在窗口的最上方应该能看到绿色对勾和Python Path Ready的字样
  • 在Python console窗口中,执行import Example后,应没有任何报错

018_import_example

Q3. 这个插件是否包含引擎内的python编辑器?

A: 不包含. Pycharm 社区版和 VS Code 已经非常强大了, 用它们可以搞定开发中的一切需求

Q4. 如何调试

A: 可以通过这个帖子中的方法和使用VSCode进行调试 HowToDebugChameleon.

Q5. 其他还有那些文档?

下面这些应该会有帮助

提供支持和反馈

本插件,现在为免费试用。其中DefaultResources为开源内容。这个仓库的使用 MIT license

  • 任何建议,意见都是受欢迎的
  • 如果在使用过程中,遇到困难,或者问题,请将问题描述,截图,log一并发送给我
  • 如果你在浏览本网页的英文版内容的时,如果发现任何英文的歧义或者语病,也非常欢迎联系我