Giter VIP home page Giter VIP logo

ue_tapython_plugin_release's Introduction

TA Python Tools

This is a plugin which tries hard to make Unreal Editor Tools As Easy As Possible.

TAPython WebSite

TAPython Documentation

Overview

TAPython is an editor plugin for Unreal Engine. It provides a framework for creating python editor tools in Unreal Engine, and live Slate editing for developers, which makes creating menus and UE native Slate UI much easier and faster(without any compiling time or restart editor). The plugin also provides 200+ editor tool interfaces to use, making developing UE editor tools very simple and efficient.

Tools Preview

Thank you, TAPython's stargazers✨.πŸ˜„

Star History Chart

What's New

In latest v1.2.1

New Features

Define menu entry directly in Chameleon Tool's Json file

Add Define menu entry directly in Chameleon Tool's Json file feature. (In contrast, previous versions required defining menu entries in MenuConfig.json)

This feature is similar to the way Unity's MenuItem works, eliminating the need to define menu entries in MenuConfig.json. It is undoubtedly a great help for the migration and merging of tools.

How to use

Add menu entries for the tool through the MenuEntries field in the ChameleonTools json file. For example, in the following example, a menu entry Tools/Image Compare is defined for "Chameleon Tool". Clicking this menu entry will open the Image Compare tool.

138_ChameleonAutoMenu

{
	"TabLabel": "Image Compare",
	"InitTabSize": [1000, 650],
	"InitTabPosition": [200, 100],
    "MenuEntries": ["Tools/Image Compare"],
    "Icon": {"style": "ChameleonStyle", "name": "Picture" },
    "InitPyCmd": "..."
}

139_image_compare

This tool has been added to Default Python Source and can be used directly.

Notes on menu

The menu items are separated by /, for example Tools/Image Comparison, which means that Tools is a menu group and Image Compare is a menu item under the menu group.

The MenuEntries field supports multiple menu entries, although in most cases, a tool only needs one menu entry. Currently, this feature supports adding menu items to the blue Chameleon button in the toolbar, and will support adding menu items to other locations in the future.

Add icon

The Icon field can be used to add icons to menu items, and the specific method is similar to the method of adding icons to menu items in MenuConfig.json.

Feature enable switch

A new configuration item MenuFromToolsJsonEnabled has been added to Config.ini to control whether to enable the function of reading menu entries from Json files. The default value is True.

Slate
Added support for SDPIScaler.

The SDPIScaler widget can control the scaling ratio of its child components. The usage is as follows:

    "SDPIScaler": 
    {
        "Aka": "Scaler",
        "DPIScaler": 1.0,
        "Content": {
            ...
        }
}
  • SDIPScaler is similar to widgets such as SBox that have a child widget, and also has a Content field to specify its child widget.

  • Within ChameleonData, the scaling ratio of the SDPIScaler widget can be set through the newly added set_dpi_scale method.

Other widgets
  • SDropTarget adds the OverrideBackgroundImagePadding field to set the Padding of the SDropTarget background image.

  • SComboBox adds the keyword: InitiallySelectedItem, which specifies the initially selected item of the SCoboBox.

  • SEditableText, SEditableTextBox adds the IsPassword field to specify whether it is a password input box.

  • SImage adds support for the Tile field to specify the SImage in repeat mode. The optional values are:

    • NoTile no repeat, default behavior
    • Horizontal horizontal repeat
    • Vertical vertical repeat
    • Both horizontal and vertical repeat
ChameleonData
  • Add set_image_data_base64 Set the SImage's image data from base64 string

  • Add set_image_data_from_memory Set the SImage's image data from memory

  • Optimize the performance of set_image_data in UE5

  • set_image_data, set_image_data_from_memory, set_image_from_path, set_image_from and other methods add two new parameters: Tint and Tiling, used to set the color and repeat mode of SImage

  • Add set_image_data_from_texture2d to directly set the image of the SImage in the UI through the Texture2D in the project

  • Added set_desired_size_override to set the desired size of SImage

  • Added get_chameleon_desired_size to get the desired size of the entire interface of Chameleon Tool.

PythonRBFLib (Experimental)

A new module has been added to use RBF (Radial Basis Function) interpolation in Python

  • unreal.PythonBPLib.rbf
  • unreal.PythonBPLib.set_rbf_params_deminsion
  • unreal.PythonBPLib.rbf_fun
  • Added UObject: unreal.PythonRBFTarget
  • Added UObject: unreal.PythonRBFFunction
  • Added UObject: unreal.UPythonRBFValues
PythonTextureLib
  • Add get_texture2d_content to get the content of the 8-bit texture and return a byte array
Console Command

Add debug command TAPython.OverrideEnable 1

Enter this command in the CMD debug window, and the contents of the DefaultResource directory in the default resource of the plugin will replace the contents of the TA/TAPython directory in the current project.

CAUTION
This command will overwrite the contents of the TA/Python directory and will not delete the contents of the directory. Please make a backup before using it. {: .alert .alert-warning}

Default Python Source
Add example tool Image Compare

139_image_compare

Compare the differences between two images, such as comparing the rendering content of the scene and the rendering content of the wireframe mode

G41_image_compare_scene

Or compare two different textures

G42_image_compare_texture

The Widget Gallery adds examples of SSplitter and SDPI widgets

Add icons

  • BackgroundGrid.png
  • BackgroundGridRed.png

Changes

Config.ini

Set LogOnTickWarnings of config.ini default value to False

Fixed

  • Fix potential issues with SImage in SetColorAndOpacity
  • Fix the problem that json is not imported in Utilities/Utils.py
  • Fix the error of ResizeWindow when the interface cannot be found

In latest v1.2.0

Add Support for UE 5.3

ChameleonData

  • set_image_data The first parameter raw_data of set_image_data supports compressed data in Zlib format

For example, the code used to fill SImage before is:

self.data.set_image_data(self.ui_image, img.data.tobytes(), width, height, channel_num)

change to:

self.data.set_image_data(self.ui_image, zlib.compress(img.data.tobytes()), w, h, channel_num)

with the same result, you will get a faster execution speed, which will be 1/3~20 times faster, depending on the image content.

Note:

  • Use the compressed data, you need to specify the number of channels of the image.
  • It is recommended to use a lower compression rate to avoid the negative benefits caused by the increase in time consumption during the compression process.
    compressor = zlib.compressobj(level=1)  # use fast compression or use zlib.compress()
    compressed_data = compressor.compress(im.tobytes()) + compressor.flush()
    self.data.set_image_data(self.ui_image, compressed_data, w, h, channel_num)

PythonBPLib

Add more viewport and projection matrix related interfaces

  • Add set_level_viewport_camera_fov Set the fov of level viewport camera
  • Add get_level_viewport_camera_aspect Get the aspect of level viewport camera
  • Add get_level_viewport_size Get the size of level viewport
  • Add get_viewport_pixels_as_texture Get the content of first active viewport as Texture2D. UE5 only.
  • Add get_viewport_pixels_as_data Get the raw pixels from first active viewport as RawData
  • Add calculate_projection_matrix Calculate the Projection Matrix by fov and near plane
  • Add calculate_view_matrix Calculate the View Matrix by ViewLocation and ViewRotation.
  • Add calculate_vp_matrix Calculate the ViewProjection Matrix by ViewLocation, ViewRotation, fov and near plane.
  • Add calculate_inv_view_projection_matrix Calculate the inverse ViewProjection Matrix by ViewLocation, ViewRotation, fov and near plane.
  • Add project_world_to_view Project world position to view position.
  • Add frustum_trace Trace rays against the world using a specific profile in a gird in Frustum and return the hits. UE5 only.
Add Struct: TAPythonPrimitiveHitResult

unreal.TAPythonPrimitiveHitResult is used to add more return data for HitResult.

  • component (PrimitiveComponent): [Read-Write]
  • hit_locations (Array[Vector]): [Read-Write]
  • hit_normals (Array[Vector]): [Read-Write]
  • is_this_triangles_vertex_all_visible (Array[bool]): [Read-Write]
  • screen_normals (Array[Vector]): [Read-Write]
  • screen_positions (Array[Vector2D]): [Read-Write]
  • transform (Transform): [Read-Write]
  • triangle_ids (Array[int32]): [Read-Write] The index of output in the expression

PythonMeshLib

Add more interfaces for DynamicMesh

  • Add set_uvs_from_camera_projection Project the DynamicMesh to specified UVSet in current view. UE5 only.
  • Add get_visible_triangles Get the visible triangles of DynamicMesh in current view. UE5 only.
  • Add rasterize_and_trace_triangles_uv Trace the visibility of DynamicMesh in current view.(Experimental). UE5 only.
  • Add trace_dynamic_mesh_triangles_visibility Trace the visibility of DynamicMesh's triangles in current view. UE5 only.
  • Add get_triangles_face_normal_in_view Get the face normal of DynamicMesh in current view. (Experimental). UE5 only.
  • Add cal_triangles_derivatives Calculate the merged ddxy of DynamicMesh's triangles in current view. UE5 only.
  • Add export_normal_and_derivatives Export the current normal and mip of DynamicMesh in current view as raw data. (Experimental). UE5 only.

PythonTextureLib

  • Add create_texture2d Create a Texture2D with specified size which has no uasset file. UE5 only.
  • Add finish_compilation_texture Wait for the texture to finish compiling. UE5 only.
  • Add parameter FlipY to create_texture2d_from_raw, default is False

Menus

Add menu items for Blueprint Editor

  • OnBlueprintEditorMenu Add menu items to Blueprint Editor
    "OnBlueprintEditorMenu": {
        "name": "Python Menu On Control BP",
        "items":
        [
            {
                "name": "TA Python Blurprint Example",
                "items": [
                    {
                        "name": "Print Blueprint",
                        "command": "print(%asset_paths)"
                    }
                ]
            }
        ]
    }

The configuration items in Config.ini: MenuConfigFilePath and PythonContentFolder support absolute paths Request from. Now we can share Chameleon Tools in different projects.

Default Resource

Add two default menu items to the global Context menu of the Chameleon tool. (UE5 only)

  • "Log tool's json path" Log the json path of the current Chameleon tool's UI
  • "Log instance variable name" Log the instance variable name of the current Chameleon tool in Python
Utils.py

Add guess_instance_name method to guess the instance variable name of the current Chameleon tool in Python

Fix

  • Fix the warning of unreal.PythonBPLib.find_actor_by_name in UE5
  • Fix the problem that the right-click menu item of Outline cannot be created in UE4
  • Fix typo in some logs
  • Remove some redundant logs

Experimental

Below is Experimental. It is only recorded here. There may be major changes later, and it is not recommended to use it in official tools.

Slate

Add support for SGraphPanel (Experimental), and EdGraphSchema_K2 is used by default.

ChameleonData

Add SGraphPanel related methods (Experimental):

Note: The following methods are "Experimental" functions, which may be removed later. It is only recorded here.

  • Add spawn_to_graph_by_class
  • Add spawn_function_to_graph Spawn a specified function of a module in SGraphPanel.
  • Add spawn_function_to_graph_with_spawner Spawn a specified function of a module in SGraphPanel through a BPFunctionSpawner.
  • Add get_graph_panel_nodes Get all nodes in SGraphPanel.
  • Add clear_graph_panel Clear all nodes in SGraphPanel.
  • Add get_graph_selected_node Get the selected nodes in SGraphPanel.
  • Add get_graph_panel_content_as_json Get the content of SGraphPanel as JSON string
  • Add set_graph_panel_content_from_json Set the content of SGraphPanel from JSON string.

Add a new BPLib to process Blueprint related content

PythonBPAssetLib(Experimental)

  • Add get_selected_nodes
  • Add log_schema
  • Add log_all_k2_nodes
  • Add log_all_schemas Log all available Schemas, and return UClass array
  • Add get_graph_node_by_name
  • Add get_all_k2_nodes
  • Add get_children_classes Get the children classes from the specified UClass
  • Add get_classes_from_module Get the UClass from the specified module name
  • Add get_bp_functions_spawners Get the UFunction from the specified UClass
  • Add get_bp_function_spawner Get the Spawner of the specified Blueprint function name, used to create nodes in SGraphPanel

In v1.1.0

Dynamic Creating Slate

G33_Splinter_Button

The expample project of the "Splinter_Button" above is here:

https://github.com/cgerchenhp/TAPython_ButtonDivision_Example

The biggest change in TAPython v1.1 is the addition of a feature that allows widgets to be directly added, inserted, and deleted through Python code. With this feature, we can dynamically add widgets to the tool during runtime. This function is particularly useful for displaying widgets of an unknown quantity.

G34_dynamic_widgets

ChameleonData

  • Added chameleon_data_instance.set_content_from_json, which is used to set sub-widgets for SBox, SBorder, SCheckBox, SBox, and SButton components.
  • Added chameleon_data_instance.append_slot_from_json, which is used to add sub-widgets to Slots for SHorizontalBox, SVerticalBox, SScrollBox, SGridPanel, SUniformGridPanel, SUniformWrapPanel, SOverlay, SCanvas, and SSplitter.
  • Added chameleon_data_instance.insert_slot_from_json, which is used to add sub-widgets at a specified Slot index for SHorizontalBox, SVerticalBox.
  • Added chameleon_data_instance.remove_widget_at, which is used to remove the widget at the specified location. This is applicable to all the widgets mentioned above.
  • Added chameleon_data_instance.get_all_akas, which is used to get all Aka names in the chameleon tool.
  • Added chameleon_data_instance.get_widget_path, which is used to get the Slate path of the widget through its Aka name.

Add Support for UE 5.2

Documentation

In the past two months, TAPython has completed the update of the initial version of the document, and the subsequent documents will be iterated on the existing basis.

The document address in the plugin is updated to the new url: https://www.tacolor.xyz/tapython/welcome_to_tapython.html

Slate

  • Add "Modal Window", available options: InitTabSize, SizingRule (UserSized, FixedSize, Autosized), TabLabel, SupportsMinimize, SupportsMaximize, IsFloatingWindow. For details, please refer to: Modal Window
Add
  • Add the "%SelectionType" field to the OnSelectionChanged of SComboBox. Valid values for the field are: "OnKeyPress", "OnNavigation", "OnMouseClick", "Direct"
  • Add support for Font in SMultiLineEditableTextBox
  • Add support for ForegroundColor in SMultiLineEditableTextBox
  • Add support for ColorAndOpacity in SMultiLineEditableText
  • Add support for Font in SEditableTextBox
  • Add support for ColorAndOpacity in SEditableTextBox
  • Add support for TextStyle in SEditableText, SEditableTextBox, SMultiLineEditableText, and SMultiLineEditableTextBox
  • Add support for VAlign and HAlign in SGridPanel
  • Add support for BackgroundColor in SEditableTextBox and SMultiLineEditableTextBox
Fix
  • Set the default VAlign of the middle element in SHeader to Center
  • Set the maximum refresh rate for OnTick to 60hz
  • Modify the log level when some Widget properties are missing
  • Fix the false warning of unhandled VAlign and HAlign in SCanvas

Default Resources

  • Add ModalWindow example resource "./ChameleonGallery/example_modal_window.json"
  • Remove the "IsModalWindow" field originally in "ChameleonGallery.json". This field will be exclusively used for "ModalWindow"
  • Add "DisUnrealStub.py" to separate the huge unreal.py Stub file into individual files by class for easier viewing and code completion in PyCharm and similar tools, see here
  • Modify the default size of Chameleon Sketch to avoid scrollbar's flicker in some cases

ChameleonData

  • Add unreal.ChameleonData.snapshot_sketch command for capturing the current Sketch panel

  • Add chameleon_data_instance.get_top_scroll_box_offsets(json_path) for getting the offset of the top scroll box in Chameleon Tool.

  • Add chameleon_data_instance.get_scroll_box_offsets(aka_name) for getting the offset of the scroll box in Chameleon Tool with the given name.

  • chameleon_data_instance::set_image_from_path(aka_name, image_file_path) supports using absolute paths

  • Add SetMinAspectRatio/SetMaxAspectRatio for SBox

  • Add chameleon_data_instance.set_min_aspect_ratio and chameleon_data_instance.set_max_aspect_ratio for setting the min/max aspect ratio of the given SBox

Python Editor API

Add
  • Add unreal.PythonBPLib.get_class_path_name for getting the path name of the given object's class
  • Add unreal.PythonBPLib.get_viewport_linear_color_pixels for getting the pixels of the viewport as a linear color array
  • unreal.PythonBPLib.exec_python_command, add force_game_thread option to allow Python code to execute on the main thread. When we execute code in a sub-thread, if we need to modify the UI content, we can specify to modify it in the main thread through the force_game_thread option (the UI content can only be modified in the Game thread).
Fix
  • Fix the issue with the incorrect IsAltDown behavior in unreal.PythonBPLib.get_modifier_keys_state()

In v1.0.10

The Intermediate directory is added to the package and includes UnrealEditor-TAPython.lib (UE4Editor-TAPython.lib in UE4) to make compatibility with the automated build system. At the same time, add the corresponding .dll for DebugGame mode.

Slate

Add support for SWebBrowser

Adding support for SWebBrowser allows you to embed WebBrowser in the tool window, which can be helpful in some situations, such as embedding the internal pipeline tool in the python tool in Unreal Editor.

Web_browser

Using the SWebBrowser widget, the web browser plug-in is required. It is disabled by default. We must enable the plug-in before using it

SWebBrowser Plugin

Widgets
  • Added "SizeRule" attribute for the SSplitter widget. Optional values are "FractionOfParent" and "SizeToContent",

  • And more attributes for SColorBlock and SColorPicker

ChameleonData
  • GetVisibility

Get the current visibility status of the widget.

  • Set/GetColor

They are used for getting and setting the color of the widget.

More APIs for SWebBrowser widget though ChameleonData.

  • LoadURL
  • GetURL
  • LoadPageFromString
  • ReloadPage
  • GetTitleTextOfPage
  • IsPageLoaded
  • IsPageLoading
  • CanGoBack
  • GoBack
  • CanGoForward
  • GoForward
  • BindUobjectToBrowser
  • UnbindUobjectToBrowser
ChameleonTool
  • The tool's wind can be set with "IsModalWindow" or "HasMinimizeMaximizeButton" to hide the maximize button.

If IsModalWindow is set to True, Tab is still a nomad type and we can still dock to other Windows.

Known issue: the maximize button reappears after the window is floated from the docked window.

Menu

  • Add "HasSection" attribute, which defaults to True, used to hide the Section text above the menu item when creating a menu with ToolMenus Anchor.
Add a configurable menu for PhysicsAssetEditor and ControlRigEditor

As the Material Editor, we can add custom menus for Physics Asset Editor and Control Rig Editor now.

    "OnPhysicsAssetEditorMenu": {
        "name": "Python Menu On Physics Asset Editor",
        "items":
        [
            {
                "name": "TA Python Physics Asset Example",
                "items": [
                    {
                        "name": "Print Physics Asset",
                       "command": "print(%f)"
                    }
                ]
           }
        ]
     }
Add menu in ToolMenus Anchor

We can add a TAPython menu where the UE ToolMenus can.

    "ControlRigEditor.RigHierarchy.ContextMenu": {
        "name": "Python Menu On Control Rig Editor",
        "items": [
            {
                "name": "Rigging Tools",
                "command": "print('Rigging Tools')",
                "icon": {
                    "style": "ChameleonStyle",
                    "name": "Resources.Chameleon_32x_png"
                }
            }
        ]
    }

And we can add a context menu for object's component in Detail views.

    Kismet.SubobjectEditorContextMenu: {
        ...
    }
Console Command
TAPython.RefreshToolMenus 

"TAPython.RefreshToolMenus" can be used to refresh the "ToolMenus" menus, other menus will be auto-refreshed and not need this command

Editor Lib

PythonBPLib
  • GetModifierKeyState

GetModifierKeyState Get the modifier key states(Ctrl, Shift, Alt, etc.), so we used it to display an optional dialog or menu.

  • SnapshotDetails

We can tank a snapshot of the entire Details window via 'snapshot_details'. The file will be saved to <Your_project>\Saved\Screenshots\WindowsEditor\ObjectDetailProperties. Note we need to make sure the focus is on the Details window.

object_detail_snapshot

PythonTestLib
  • CancelDelayCallById

Cancel the specified DelayCall by ID.

Add PhysicsAssetLib

We got a new editor library: PhysicsAssetLib, as its name, it's for PhysicsAsset Editing.

Function Name Description
get_selected_bodies_indexes Get the indexes of the selected bodies in Physics Asset Editor
rotate_selected_body Set the rotation of the selected body in Physics Asset Editor
rotate_selected_constraint Set the rotation of the selected constraint in Physics Asset Editor
get_body_center Get the center value of the specified body
set_body_center Set the center value of the specified body
get_body_rotation Get the rotation value of the first body
get_bodies_rotations Get the rotation value of the first body
set_body_rotation Set the rotation value of the specified body
get_body_radius Get the Radius value of the body
set_body_radius Set the Radius value of the body
get_body_length Get the rotation value of the first body
set_body_length Get the rotation value of the first body
get_body_size Get the Size value of the box body
set_body_size Set the Size value of the box body
scale_body Scale the specified body
get_edited_physics_assets Get all PhysicsAsset currently being tracked with open editors
get_physics_asset_from_top_window Get the PhysicsAsset from the top opened editor window.
get_selected_item_names Get all the selected items name in PhysicsAsset editor window.
select_body_by_name Select the Body by name in PhysicsAsset editor window.
select_body_by_names Select the Bodies by name in PhysicsAsset editor window.
select_shape_by_name Select the Shape by name in PhysicsAsset editor window.
select_shape_by_names Select the Shapes by name in PhysicsAsset editor window.
select_constraint_by_name Select the constraint by name in PhysicsAsset editor window.
select_constraint_by_names Select the constraints by name in PhysicsAsset editor window.
add_constraints Add constraint to specified bodies
get_skeleton_hierarchy Get the bones hierarchy
get_bodies_hierarchy Get all the bodies names and their parent bone's index
get_constraints_names Get all the constraint's display names of PhysicsAsset
get_bone_indexes_of_constraint Get the parent and child bone's indexes of the specified Constraint
get_bone_index_from_body Get the first Body under the specified bone
get_bodies_from_bone Get the Bodies under the specified bone
get_constraint_instance_accessor Get the ConstraintInstanceAccessor from PhysicsAsset
reset_constraint_properties Reset the specified Constraint's values
update_profile_instance Update the Profile according to the specified Constraint
break_constraint_accessor Get the Owner and Constraint Index from ConstraintInstanceAccessor

Fixed

  • The "Margin" of STextBlock is not working.
  • The "OnTextChanged" and "OnTextCommitted" callback are not working when the input text is empty. (delete the text with backspace)

v1.0.9

Add PythonTestLib

A new editor lib PythonTestLib has been added to TAPython to complete the test cases of all the extended APIs.

gif

In the test cases repo UE_TAPython_Plugin_TestCases, more than 200 PythonLib APIs has been tested.

Get logs from python

Now we can get the contents of the Output Log, which we can use to validate the operation result from the editor.

Note that Logs are the same content as Output Log in the editor, but they are separate. Clearing Log in Output Log will not affect what PythonTestLib.get_log() returns, and vice visa

A new setting parameters LogNumberLimit in Config.ini will limit the maximum number of log buffers. The default size is 10240.

Call python command with delay and repetition

In the test case, I used delay_call, pushing the python scripting, then waiting for the editor to complete its asynchronous tasks, or waiting for the window to refresh, and so on.

Slates

OnMapChangedCmd

Add "OnMapChangedCmd" to the Chameleon tool for executing Python commands when changing maps.

Usage:

  • Clean references in Chameleon tool when unload map to avoid memory leaks
  • Sync the UI when changing map

For example, I fixed the crash when using ObjectDetailViewer tool and then loading another level, as the queried object will referenced by ObjectDetailViewer. :-(

    "OnMapChangedCmd": "chemeleon_objectDetailViewer.on_map_changed(%map_change_type)",
    def on_map_changed(self, map_change_type_str):
        # remove the reference, avoid memory leaking when load another map.
        if map_change_type_str == "TearDownWorld":
            self.reset(bResetParameter=False)
        else:
            pass # skip: LoadMap, SaveMap, NewMap
parameters
  • %world: Get the world of map operation

  • %map_change_type: Get the operation type of changing map, "LoadMap", "SaveMap", "NewMap" or "TearDownWorld"

SDetailViewer

We can use SDetailViewer for showing the object properties.

G_015_SDetailsView_s

SMultiLineEditableTextBox
  • Add "AlwaysShowScrollbars" bool field in SMultiLineEditableTextBox

  • Add ScrollTo function, for scrolling the scroll bar to the specified location

SetColorAndOpacity

Add SetColorAndOpacity support for SScrollBox/SImage/STextBlock/SEditableText

PythonBPLib

SetLevelViewportCameraSpeed

Fix

  • remove incorrect waring logs when OnContextMenuOpening in SEditableTextBox was set.
  • Fix PythonBPLib.SetFolderColor not immediate apply the color with existing directories
  • Add more logs for PythonBPLib.SaveThumbnail.
  • Remove redundant /All/Game", "/All/EngineData/" in the return value from PythonBPLib.GetSelectedFolder
  • Fix PythonBPLib.SetSelectedFolder not work.
  • Fix crash when param "comp" is null when calling PythonBpLib.set_anim_blueprint
  • Fix PythonDataTableLib.SetPropertyByStringAt not work when "quote" in input values.
  • Fix PythonBPLib.FixupRedirectorsInFolder not work when input value is a string.
  • Fix create_landscape_proxy not work when SectionSize = 1
  • Add Optional parameters QuadsSpaceOffsetX/Y for create_landscape_proxy_with_guid
  • Fix crash when input value "asset_input_data" is null when calling PythonMeshLib.get_imported_original_mat_names.
  • Fix crash when input value "socket" is null when calling PythonMeshLib.set_static_mesh_socket_name.
  • Fix typo PythonMeshLib.get_selection_cast_shadow
  • Add Deprecated warning in some PythonLib APIs to warn that some functions can use ue engine native functions instead.
  • Add return value for PythonMeshLib.convert_mesh_to_static_mesh

v1.0.8

Support MacOS

TAPython released its first version of MacOS Monterey (v1.0.8 for UE 5.0.3), although there are far fewer Unreal developers on the MAC than PC. If you have any problems, please let me know.

0_49_tapython_osx_small

Context Menu for Chameleon Tools (UE5 only)

Global Context Menu

Now, we can add the global context menu of the Chameleon Tool by adding "OnTabContextMenu" in the MenuConfig.json.

For example, the following example adds a menu item named "Reload This Tool" to all Chameleon Tools. The tool will re-launch when the user clicks the menu. If we use this method to reload the python module when we open the tool, we can quickly reload both the interface and python logic, which is very convenient when developing the tools.

049_images/reload simple example

MenuConfig.json:

"OnTabContextMenu":{
    "name": "TA Python Tab",
    "items": [
        {
            "name": "Reload This tool",
            "command": "unreal.ChameleonData.request_close(%tool_path); unreal.ChameleonData.launch_chameleon_tool(%tool_path)"
        }
    ]
}
Individual Context for each Chameleon Tool

Each Chameleon Tool can also add its own context menu. The way of adding menu is similar to the Global Context Menu: add the "OnTabContextMenu" subitem in the Json file of tool's json file, and add the menu content to it.

For example, add a custom context menu for MinimalExample

{
    "TabLabel": "Example",
    "InitTabSize": [200, 123],
    "InitTabPosition": [180, 200],
    "InitPyCmd": "import Example; chameleon_example = Example.MinimalExample.MinimalExample(%JsonPath)",
    "Root":
    {
        ...
    },
    "OnTabContextMenu":{
        "items": [
            {
                "name": "Reset Click Count",
                "command": "chameleon_example.reset_click_count()"
            }
        ]
    }
}

Or a menu item that switches the tool to "Development Mode" for your tool.

049_development_mode

Tips:

  • These new context menu only support UE5, now
  • OnTabContextMenu also support sub menu items
New Content Menu for Material Editor

One of the most important features in this release is the addition of support for the Material Editor.

Now we can add custom menu items directly to the material editor and pass the material instance that we are currently editing to the python script so that we can "play with" the material nodes directly in python.

The %asset_paths in the following example will be replaced by the TAPython with an array of paths to the material currently being edited, which usually has only one element.

With the APIs added to PythonMaterialLib in this release, we can fully script the material expression nodes via Python.

G013_get_node_as_r

MenuConfig.json:

    "OnMaterialEditorMenu": {
        "name": "Python Menu On Material Editor",
        "items":
        [
            {
                "name": "TA Python Material Example",
                "items": [
                    {
                        "name": "Print Editing Material / MF",
                        "command": "print(%asset_paths)"
                    },
                    {
                        "name": "Log Editing Nodes",
                        "command": "editing_asset = unreal.load_asset(%asset_paths[0]); unreal.PythonMaterialLib.log_editing_nodes(editing_asset)"
                    },
                    {
                        "name": "Selected Nodes --> global variable _r",
                        "command": "_r = unreal.PythonMaterialLib.get_selected_nodes_in_material_editor(unreal.load_asset(%asset_paths[0]))"
                    }
                ]
            }
        ]
    },

Slates

SScrollBox

Now we can calculate the size of all content in the whole ScrollBox from the Offset, ScrollOffsetOfEnd,ViewFraction,ViewOffsetFraction, etc. Then use SnapshotChameleonWindow to capture the contents of the entire tool window, including the parts of ScrollBox that are not shown.

SButton

Add %widgetPath keyword in JSON

It will pass the widget path of the current clicked button to python code, so we can figure out which SButton was clicked, when we import the External JONS file multi-times.

More Control with Chameleon Tool's Window

flash window

We can capture the contents of the entire chameleon tool window, including the parts of ScrollBox that are not shown.

For example, the ChameleonGallery tool that comes with the plugin is over 3,000 pixels height and wrapped in ScrollBox, which we can also save as an image at once.

snap gallery

The following code will calculate the size of the contents in the entire tool window, then take the snapshot.

    def get_full_size_of_this_chameleon(self):
        current_size = unreal.ChameleonData.get_chameleon_window_size(self.jsonPath)
        scrollbox_offsets = self.data.get_scroll_box_offsets(self.ui_scrollbox)
        height_full = scrollbox_offsets["ScrollOffsetOfEnd"] / (1.0 - scrollbox_offsets["viewFraction"])
        height_full += 48   # add title bar
        return current_size.x, round(height_full)

    def on_button_Snapshot_click(self):
        full_size = self.get_full_size_of_this_chameleon()
        saved_file_path = unreal.ChameleonData.snapshot_chameleon_window(self.jsonPath, unreal.Vector2D(*full_size))
        
        if saved_file_path:
            unreal.PythonBPLib.notification(f"UI Snapshot Saved:", hyperlink_text = saved_file_path
                                            , on_hyperlink_click_command = f'chameleon_gallery.explorer("{saved_file_path}")')
        else:
            unreal.PythonBPLib.notification(f"Save UI snapshot failed.", info_level = 1)

Now we can iterate, create, and modify Material Expression nodes of Material and Material Function with Python. Including the nodes that cannot be created or modified in the MaterialEditingLibrary. For example, connect properties to World Position Offset, add Get/SetMaterialAttribute nodes, etc.

For more details and examples of material expressions can be found here: How to manipulate Material Expressions Node in Material with Python in Unreal Engine

PythonMaterialLib Description Is New added
get_static_switch_parameter_values Get the Static Switch Infos of material instance
set_static_switch_parameter_value Set the Static Switch Infos of material instance
set_static_switch_parameters_values Batch set the Static Switch's status of material instance.
get_mf_static_switch_parameter Get the Static Switch Infos of material function.
get_static_parameters_summary Get the numbers of each StaticSwitchParameter of material instance.
log_mat Log out all the connections in the material Yes
get_material_expressions Log out all the Material Expressions in the material Yes
get_all_referenced_expressions Get Material Expressions in the material with specified feature level Yes
get_material_connections Get all the connections in the material Yes
get_material_function_connections Get all the connections in the material function Yes
get_material_expression_input_names Get the input pin's names of the material expression Yes
get_material_expression_output_names Get the output pin's names of the material expression Yes
get_material_expression_captions The captions of the material expression Yes
set_shading_model Set the shading model of the material, for the hidden shading model Yes
get_material_expression_id Get the ParameterExpressionId of the material expression. Yes
log_mf Log out all the connections in the material function Yes
get_material_function_expressions Get all the expressions in the Material Function Yes
get_material_function_output_expressions Get all the output expressions in the Material Function Yes
get_selected_material_nodes Get the selected nodes in material editor. Yes
log_material_expression Log Detail information of the MaterialExpression, include inputs, outputs etc. Yes
log_editing_nodes Log Detail information of the Material or Material Function Yes
get_selected_nodes_in_material_editor Get the selected nodes in material editor. Yes
get_hlsl_code Get the HLSL code of the Material Yes
get_shader_map_info Get the ShaderMaps infos in string format. Yes
get_material_content Get the material's content in JSON Format Yes
get_material_function_content Get the material function's content in JSON Format Yes
connect_material_expressions Create connection between two material expressions Yes
disconnect_expression Disconnection the material expression's input Yes
connect_material_property Connect a material expression output to one of the material property inputs (e.g. diffuse color, world position offset etc) Yes
disconnect_material_property Disconnect the material property input Yes
get_material_proper_str_from_guid Get EMaterialProperty in string format from a guid Yes
gen_guid_from_material_property_str Generate a Guid from EMaterialProperty Yes
add_input_at_expression_set_material_attributes Add an Attribute Get Type pin for material expression "GetMaterialAttributes" Yes
add_output_at_expression_get_material_attributes Add an Attribute Get Type pin for material expression "GetMaterialAttributes" Yes

1.0.7

SImage

Add Mouse Event for SImage

  • OnMouseMove
  • OnMouseEnter
  • OnMouseLeave events

With the three mouse events, our python code can use them to perform more complex operations based on the user's mouse input in SImage.

The %uv, %mouse_flags in the following example will be automatically replaced with the UV coordinates of the mouse in SImage and the pressed state of the left, middle and right mouse button

{
    "SImage": {
        "DesiredSizeOverride": [200, 200],
        "Aka": "ImageCanvas",
        "OnTick": "your_tool.on_tick()",
        "OnMouseLeave": "your_tool.on_mouse_leave(%mouse_flags)",
        "OnMouseMove": "your_tool.on_mouse_move(%uv, %mouse_flags)"
    }
}

Painter

The user's operation in SImage is taken as Stable Fluid function's input, then using result drive the volume cloud with set_render_target_data function of PythonTextureLibs.

PaintCloud

Add More Editor APIs

PythonStructLib

PythonBPLib

  • BreakSoftObject

  • Notification

    Two new optional parameters in notifications were added, for adding a specify hyperlinks and the custom python function that executes when click. So we can quickly jump to a specific location or open a hyperlink.

More information and example about modify RenderTexture2D and SImage can be found here.

Fix

  • PythonStructLib.get_guid_from_friendly_name not return the correct guid.

In v1.0.6

Added:

  • Support Unreal Engine 5.0.3
  • Support Unreal Engine 4.27.2
  • Support Unreal Engine 4.26.2
  • Add an optional parameter: "friendly name" to PythonStructLib.add_variable and PythonStructLib.add_directory_variable
  • Better warning message for PythonDataTableLib.set_property_by_string when "row_name" or "column_name" not exists in datatable

Fixed:

  • The Chameleon tab's reference not released when the project closes.

In v1.0.5

PythonEnumLib and PythonStructLib has been added to Python Editor Libs, PythonDataTableLib also adds more python/blueprint callable functions.

PythonEnumLib PythonStructLib PythonDataTableLib
get_display_name_map log_var_desc get_data_table_struct_path
set_enum_items log_var_desc_by_friendly_name get_data_table_struct
get_enum_len get_variable_description get_table_as_json
get_display_name_by_index get_guid_from_friendly_name get_row_names
set_display_name get_guid_from_property_name get_column_names
get_description_by_index get_variable_names get_shape
set_description_by_index get_friendly_names remove_row
get_name_by_index is_unique_friendly_name add_row
move_enum_item add_variable duplicate_row
is_bitflags_type add_directory_variable rename_row
set_bitflags_type remove_variable_by_name reset_row
get_cpp_form rename_variable move_row
change_variable_default_value get_row_name
get_column_name
get_flatten_data_table
get_property_as_string
get_property_as_string_at
set_property_by_string
set_property_by_string_at

In short, we can use Python to do almost everything you did manually in the editor with User defined ENum, User Defined Struct and DataTable. More details and examples can be found here.

v1.0.4

Support more slates:

Now we can create widge: SSplitter

G006_widget_SSplitter

G006_widget_SExpandableArea

Two APIs was added in ChameleonData for SExpandableArea:

  1. bool GetIsExpanded(const FName AkaName)
  2. void SetIsExpanded(const FName AkaName, bool bExpanded, bool bAnimated=false)
data.get_is_expanded(aka_name) -> bool
    Get the Expanded state of Specified SExpandableArea
    note: Supported widgets: SExpandableArea.
    note: added in v1.0.4

    Args:
        aka_name (Name): The aka name of the widget

    Returns:
        bool: Is Expanded or not.
	data.set_is_expanded(aka_name, expanded, animated=False) -> None
	    Set the Expanded state of Specified SExpandableArea
	    note: Supported widgets: SExpandableArea.
	    note: added in v1.0.4
	
	    Args:
	        aka_name (Name): The aka name of the widget
	        expanded (bool): Is Expanded or not.
	        animated (bool): Expanded with animation or not.

Add Context menu in Outline window

Now we can add context menu in Outline window, with the "OnOutlineMenu" field in MenuConfig.ini.

    "OnOutlineMenu": {
        "name:": "Python Menu On OutlineMenu",
        "items":
        [
            {
                "name": "Print selected actors",
                "command": "print(unreal.get_editor_subsystem(unreal.EditorActorSubsystem).get_selected_level_actors())"
            }
        ]
    },

G009_context_menu_in_outline

Add configurable icons in front the menu item

024_icons_in_menus

The .png and.svg files in the plugin resource directory will be added to "ChameleonStyle" automatically. Then we can use it for menu items.

  • We can specify the icon of a menu item with a relative path of the icon image in the plug-in resource directory.
    {
        "name": "Chameleon Shelf Tool",
        "ChameleonTools": "../Python/ShelfTools/Shelf.json",
        "icon": {
            "ImagePathInPlugin": "Resources/briefcase_32x.png"
        }
    },
  • Or use ImageBrush directly in the style. For instance, the image brushes in FEditorStyle, FCoreStyle
    {
        "name": "Minimal Example",
        "ChameleonTools": "../Python/Example/MinimalExample.json",
        "icon": {
            "style": "ChameleonStyle",
            "name": "Flash"
        }
    }

The Chameleon UI .json file can reference other json files.

Now the Chameleon UI json file can reference other Json files. Nested references are supported, but circular references need to be avoided

    {
        "autoWidth": true,
        "SBox": {
            "WidthOverride": 480,
            "Content": {
                "ExternalJson": "ZeldaWorldMapEditor_Buttons.json"
            }
        }
    }

pros:

  • Reduce the complexity and size of a single json file
  • reuse part ui code

cons:

  • The UI json files becomes less intuitive and more obscure
  • The Widget path logged in the console window is not the same as the Json crumb path shown in PyCharm. As PyCharm don't know that another json content has being "import" here.

recommendation:

  • Put the repetitive ui code (such as 16x16 map buttons) or the ui code which generated by other script into an "external" json file.

The number of shortcut keys has been increased to 10

The number of shortcuts that can be configured in ExitorSettings has now been increased to 10. It will be a configurable number in later version.

Add "BorderBackgroundColor" of SBorder
   {
       "SBorder": {
           "BorderBackgroundColor": [1, 0.5, 0, 1],
           "BorderImage":
           {
               "Style": "FEditorStyle",
               "Brush": "ErrorReporting.EmptyBox"
           }
       }
   }

Add More API in PythonBPLib:

  • GetViewportPixels Now we can grab and get the content of viewport. Use it in tools widgets:

025_snap_in_editor

Or send it to other device, for example, I send the viewport content to my MacroKeyboard. I think this is the smallest screen which displays Unreal Engine viewport content :D

G008_ue_screen_image_to_pico

  • ViewportRedraw

Force the viewport Redraw

  • GetObjectFlags

We can get the EObjectFlags of a UObject.

026_object_flags

  • GetLevelViewportCameraFov

  • GetActorsFromFolder Get the actors in Specified folder in outline

  • FindActorsByLabelName

Find the actor by it's "label name" not the "actor name"

Config.ini

  • add LogOnTickWarnings in config.ini
  LogOnTickWarnings=True

This option controls whether a warning is printed when the user uses the keyword OnTick.

ChameleonTools has a hidden keyword that has not been mentioned: "OnTick". The python code in it is executed during Slate updates, which are much more frequent than viewPort updates, So the py code can easily lower the editor's FPS.

"OnTick" is hidden because 99.9% of the time it is not needed and there are better ways to do it if there is a "real" need. So I don't recommend using OnTick and changing the LogOnTickWarnings setting.

Fix:

  • Fixed RequestClose failing after Chameleon dock to another window.

  • Fixed unreal.PythonBp.get_all_objects crash, when some objects don't have "world"

  • Fixed the incorrect display of the Breadcrumb in Python Tool: ObjectDetailViewer

  • Fixed chameleonData.get_float_value failed with SSpinBox

  • Fixed incorrect Padding setting in SBox

Feature

  • Use UE4 and UE5 native Python
  • Create UE Slate UI dynamically, support 39+ Slate widgets.
  • Configurable main menu/toolbar/Content Brower menu.
  • Slate like syntax interface description file, real-time preview UI result, without any reload.
  • Bind Python command to Slate UI widget, and change the UI content with python.
  • No enging source code modified, compatible with lower versions of UE4(4.21, release later) and latest UE5
  • 100+ Extra Editor Command for Python and Blutility.

Sketch Editing Gif

How to Install

Prerequisites

This plugin use UE native Python Script Plugin. The Scripting the Editor using Python is also very useful.

Python

Steps

  1. Download from TAPython release repo @github and unzip the plugin to <Your_UE_Project>\Plugins release
    Your_UE_Project
    β”œβ”€β”€ Content                         
    β”œβ”€β”€ ...
    └── Plugins                        
        └── TAPython       # <--- Put Plugin Here
            β”œβ”€β”€ Binaries                     
            β”œβ”€β”€ Config                     
            └── Content                   
            └─ ...

  1. Laungch project, open Project settings - Plugin Python - additional path, add <Your_UE_Project>/TA/TAPython/Python to additional path. then restart the editor.

Project Setting Image

  1. click the Gallery icon on main toolbar, you should see a green check box UI like below.

SketchIconOnMainBar

Green sign and text "Python Path Ready" will showing at the top of gallery.

Python Path Is Ready

If a Red Cross is displayed, check the Project Setting above.

Python Path Is not Ready

Quick Start

The plug-in package contains several menu items and four demo tools by default.

The latest DefaultResources is here: DefaultResources@github

Menu Items

  • Context Menu Items in Content Browser
  • Context Menu Items for selected asset
  • Menu Item in Main menu
  • Menu icons on Mainbar

menu gifs

Sketch Tool for design/tweaking UI

005_sketch_icon_on_mainbar

The Sketch Tool is a special ui design tool. When the<Your_UE_Project&gt\TA\TAPython\Python\ChameleonSketch\ChameleonSketch.json file is modified, the content of the ui will be updated immediately(see below gif). This can be very useful when writing tool interfaces, and will save a lot of time when tweaking the interface layout or parameters.

G000_SketchEditing

The default sketch tool looks like below. Try to modify the content of ChameleonSketch.json with any text editor, and save it. Don't worry about the json keywords and syntax, it's easy to learn and has lots of examples, will be described below.

012_default_sketch


Example Tools

All the 4 Example tools, are written with python, without any single line of c++ code.

013_Chameleon_menu

Tool 1: MinimalExample

MinimalExample

This is a tool demonstrating the creation of a standard UE Slate UI with python and a json file. The Button calls Python code, then the python code sends the results(click count) back to the UI.

The tool includes a 30-lines Json file and a 15-lines Python file. In fact, it can be shorter.

I will call this kind of tool which creates Slate interfaces in this way "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 is a Maya-like shortcut shelf tool, showing how to set visibility of widget and the usage of SDropTarget widget.

Users can drag and drop items to the shelf, and execute custom Python Code, launch Chameleon tool when clicking the item on the shelf.

shelf gif

Type Action
assets select saved assets in content Brower
folder enter saved folder in Content Brower
actors select saved actors in level
text(python snippetοΌ‰ execute as python code
chamelon tool json file launch the Chameleon tool

You can modify the python code, and make it better.


Tool 2 Object Detail Viewer

Object Detail Viewer

Object Detail Viewer is an inspector Tool for UE object. It shows all the functions and property in any UObject. Double click the property will query the child property. The image above shows the detail values of Floor_14(actor).static_mesh_component.static_mesh.static_materials[0].

In compare mode, the differences of two UObjects will be highlighted. It's very useful for being familiar with all kinds of UObject.

Object Detail Viewer use

Tool 3 Chameleon Gallery

Chameleon Gallery shows the most common widgets, and how to describe them in a json file. All the supported widgets and API documents can be found here

Gallery Gif

FAQ

Q0. Can UE4 use this plugin?

A: Yes, at the beginning this plugin was developed with UE 4.21. We have released this plugin for UE 4.26, 4.27, UE5.0EA, UE5.0Preview1.

Links

Contributing and feedback

This Plugin: TAPython is Free for use. The PythonDefaultResource is under MIT license.

  • Any suggestions and comments are welcome. Please don't hesitate to leave your message.
  • If you encounter difficulties or problems. EMail me with the problem description, screenshot and the log.
  • If you find any English ambiguities or language errors on this page, please feel free to contact me as well.

ue_tapython_plugin_release's People

Contributors

cgerchenhp avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.