Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial port to UnrealEngine 4.24 #817

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Once the plugin is installed and enabled, you get access to the 'PythonConsole'

All of the exposed engine features are under the 'unreal_engine' virtual module (it is completely coded in c into the plugin, so do not expect to run 'import unreal_engine' from a standard python shell)

The currently supported Unreal Engine versions are 4.12, 4.13, 4.14, 4.15, 4.16, 4.17, 4.18, 4.19, 4.20, 4.21 and 4.22
The minimal supported Unreal Engine version is 4.12, while the latest is 4.23

We support official python.org releases as well as IntelPython and Anaconda distributions.

Expand Down
6 changes: 6 additions & 0 deletions Source/PythonEditor/Private/PythonProjectEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "PythonProjectEditorCommands.h"
#include "Runtime/Core/Public/HAL/PlatformFilemanager.h"
#include "Runtime/Core/Public/Misc/MessageDialog.h"
#include "Editor/UnrealEd/Public/Toolkits/AssetEditorManager.h"
#define LOCTEXT_NAMESPACE "PythonEditor"

TWeakPtr<FPythonProjectEditor> FPythonProjectEditor::PythonEditor;
Expand Down Expand Up @@ -209,7 +210,12 @@ void FPythonProjectEditor::RegisterToolbarTab(const TSharedRef<class FTabManager

void FPythonProjectEditor::InitPythonEditor(const EToolkitMode::Type Mode, const TSharedPtr< class IToolkitHost >& InitToolkitHost, class UPythonProject* PythonProject)
{
#if ENGINE_MINOR_VERSION >= 24
UAssetEditorSubsystem* AssetEditor = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>();
AssetEditor->CloseOtherEditors(PythonProject, this);
#else
FAssetEditorManager::Get().CloseOtherEditors(PythonProject, this);
#endif
PythonProjectBeingEdited = PythonProject;

TSharedPtr<FPythonProjectEditor> ThisPtr(SharedThis(this));
Expand Down
1 change: 1 addition & 0 deletions Source/PythonEditor/PythonEditor.Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public PythonEditor(TargetInfo Target)
{
"Core",
"CoreUObject",
"Engine",
"SlateCore",
"Slate",
"AssetTools",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ static PyObject *py_ue_command_apply(PyObject *cls, PyObject * args)
return PyErr_Format(PyExc_Exception, "argument is not a UMaterial");
}

#if ENGINE_MINOR_VERSION >= 24
UAssetEditorSubsystem* AssetEditorSubsystem = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>();
IAssetEditorInstance* Instance = AssetEditorSubsystem->FindEditorForAsset(Material, false);
#else
IAssetEditorInstance *Instance = FAssetEditorManager::Get().FindEditorForAsset(Material, false);
#endif
if (!Instance)
{
return PyErr_Format(PyExc_Exception, "unable to retrieve editor for UMaterial");
Expand Down
83 changes: 49 additions & 34 deletions Source/UnrealEnginePython/Private/Slate/UEPyFMenuBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

#include "Wrappers/UEPyESlateEnums.h"

static PyObject *py_ue_fmenu_builder_begin_section(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_begin_section(ue_PyFMenuBuilder* self, PyObject* args)
{
char *name;
char *text;
char* name;
char* text;
if (!PyArg_ParseTuple(args, "ss:begin_section", &name, &text))
return nullptr;

Expand All @@ -14,27 +14,31 @@ static PyObject *py_ue_fmenu_builder_begin_section(ue_PyFMenuBuilder *self, PyOb
Py_RETURN_NONE;
}

static PyObject *py_ue_fmenu_builder_end_section(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_end_section(ue_PyFMenuBuilder* self, PyObject* args)
{
self->menu_builder.EndSection();

Py_RETURN_NONE;
}

static PyObject *py_ue_fmenu_builder_make_widget(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_make_widget(ue_PyFMenuBuilder* self, PyObject* args)
{
ue_PySWidget *ret = (ue_PySWidget *)PyObject_New(ue_PySWidget, &ue_PySWidgetType);
ue_PySWidget* ret = (ue_PySWidget*)PyObject_New(ue_PySWidget, &ue_PySWidgetType);
new (&ret->Widget) TSharedRef<SWidget>(self->menu_builder.MakeWidget());
return (PyObject *)ret;
return (PyObject*)ret;
}

static PyObject *py_ue_fmenu_builder_add_menu_entry(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_add_menu_entry(ue_PyFMenuBuilder* self, PyObject* args)
{
char *label;
char *tooltip;
PyObject *py_callable;
PyObject *py_obj = nullptr;
char* label;
char* tooltip;
PyObject* py_callable;
PyObject* py_obj = nullptr;
#if ENGINE_MINOR_VERSION >= 23
int ui_action_type = (int)EUserInterfaceActionType::Button;
#else
int ui_action_type = EUserInterfaceActionType::Button;
#endif
if (!PyArg_ParseTuple(args, "ssO|Oi:add_menu_entry", &label, &tooltip, &py_callable, &py_obj, &ui_action_type))
return nullptr;

Expand All @@ -58,17 +62,21 @@ static PyObject *py_ue_fmenu_builder_add_menu_entry(ue_PyFMenuBuilder *self, PyO
}

self->menu_builder.AddMenuEntry(FText::FromString(UTF8_TO_TCHAR(label)), FText::FromString(UTF8_TO_TCHAR(tooltip)), FSlateIcon(), FUIAction(handler), NAME_None,
#if ENGINE_MINOR_VERSION >= 23
(EUserInterfaceActionType)ui_action_type);
#else
(EUserInterfaceActionType::Type)ui_action_type);
#endif

Py_RETURN_NONE;
}

static PyObject *py_ue_fmenu_builder_add_sub_menu(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_add_sub_menu(ue_PyFMenuBuilder* self, PyObject* args)
{
char *label;
char *tooltip;
PyObject *py_callable;
PyObject *py_bool = nullptr;
char* label;
char* tooltip;
PyObject* py_callable;
PyObject* py_bool = nullptr;
if (!PyArg_ParseTuple(args, "ssO|O:add_sub_menu", &label, &tooltip, &py_callable, &py_bool))
return nullptr;

Expand All @@ -77,7 +85,7 @@ static PyObject *py_ue_fmenu_builder_add_sub_menu(ue_PyFMenuBuilder *self, PyObj
return PyErr_Format(PyExc_Exception, "argument is not callable");
}


TSharedRef<FPythonSlateDelegate> py_delegate = FUnrealEnginePythonHouseKeeper::Get()->NewStaticSlateDelegate(py_callable);

FNewMenuDelegate menu_delegate;
Expand All @@ -89,9 +97,9 @@ static PyObject *py_ue_fmenu_builder_add_sub_menu(ue_PyFMenuBuilder *self, PyObj
Py_RETURN_NONE;
}

static PyObject *py_ue_fmenu_builder_add_menu_separator(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_add_menu_separator(ue_PyFMenuBuilder* self, PyObject* args)
{
char *name = nullptr;
char* name = nullptr;

if (!PyArg_ParseTuple(args, "|s:add_menu_separator", &name))
return nullptr;
Expand All @@ -107,9 +115,10 @@ static PyObject *py_ue_fmenu_builder_add_menu_separator(ue_PyFMenuBuilder *self,
}

#if WITH_EDITOR
static PyObject *py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder *self, PyObject * args)
#if ENGINE_MINOR_VERSION < 24
static PyObject* py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder* self, PyObject* args)
{
PyObject *py_assets;
PyObject* py_assets;

if (!PyArg_ParseTuple(args, "O:add_asset_actions", &py_assets))
return nullptr;
Expand All @@ -120,10 +129,10 @@ static PyObject *py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder *self,
return PyErr_Format(PyExc_Exception, "argument is not iterable");
}

TArray<UObject *> u_objects;
while (PyObject *item = PyIter_Next(py_assets))
TArray<UObject*> u_objects;
while (PyObject * item = PyIter_Next(py_assets))
{
UObject *u_object = ue_py_check_type<UObject>(item);
UObject* u_object = ue_py_check_type<UObject>(item);
if (u_object)
{
u_objects.Add(u_object);
Expand All @@ -140,9 +149,15 @@ static PyObject *py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder *self,

Py_RETURN_FALSE;
}
#else
static PyObject* py_ue_fmenu_builder_add_asset_actions(ue_PyFMenuBuilder* self, PyObject* args)
{
Py_RETURN_FALSE;
}
#endif
#endif

static PyObject *py_ue_fmenu_builder_add_search_widget(ue_PyFMenuBuilder *self, PyObject * args)
static PyObject* py_ue_fmenu_builder_add_search_widget(ue_PyFMenuBuilder* self, PyObject* args)
{
self->menu_builder.AddSearchWidget();

Expand All @@ -164,13 +179,13 @@ static PyMethodDef ue_PyFMenuBuilder_methods[] = {
};


static PyObject *ue_PyFMenuBuilder_str(ue_PyFMenuBuilder *self)
static PyObject* ue_PyFMenuBuilder_str(ue_PyFMenuBuilder* self)
{
return PyUnicode_FromFormat("<unreal_engine.FMenuBuilder '%p'}>",
&self->menu_builder);
}

static void ue_py_fmenu_builder_dealloc(ue_PyFMenuBuilder *self)
static void ue_py_fmenu_builder_dealloc(ue_PyFMenuBuilder* self)
{
#if PY_MAJOR_VERSION < 3
self->ob_type->tp_free((PyObject*)self);
Expand Down Expand Up @@ -210,14 +225,14 @@ static PyTypeObject ue_PyFMenuBuilderType = {
ue_PyFMenuBuilder_methods, /* tp_methods */
};

static int ue_py_fmenu_builder_init(ue_PyFMenuBuilder *self, PyObject *args, PyObject *kwargs)
static int ue_py_fmenu_builder_init(ue_PyFMenuBuilder* self, PyObject* args, PyObject* kwargs)
{
new(&self->menu_builder) FMenuBuilder(true, nullptr);
return 0;
}


void ue_python_init_fmenu_builder(PyObject *ue_module)
void ue_python_init_fmenu_builder(PyObject* ue_module)
{
ue_PyFMenuBuilderType.tp_new = PyType_GenericNew;

Expand All @@ -227,12 +242,12 @@ void ue_python_init_fmenu_builder(PyObject *ue_module)
return;

Py_INCREF(&ue_PyFMenuBuilderType);
PyModule_AddObject(ue_module, "FMenuBuilder", (PyObject *)&ue_PyFMenuBuilderType);
PyModule_AddObject(ue_module, "FMenuBuilder", (PyObject*)& ue_PyFMenuBuilderType);
}

PyObject *py_ue_new_fmenu_builder(FMenuBuilder menu_builder)
PyObject* py_ue_new_fmenu_builder(FMenuBuilder menu_builder)
{
ue_PyFMenuBuilder *ret = (ue_PyFMenuBuilder *)PyObject_New(ue_PyFMenuBuilder, &ue_PyFMenuBuilderType);
ue_PyFMenuBuilder* ret = (ue_PyFMenuBuilder*)PyObject_New(ue_PyFMenuBuilder, &ue_PyFMenuBuilderType);
new(&ret->menu_builder) FMenuBuilder(menu_builder);
return (PyObject *)ret;
return (PyObject*)ret;
}
6 changes: 5 additions & 1 deletion Source/UnrealEnginePython/Private/Slate/UEPySTextBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ static PyObject *py_ue_stext_block_set_text(ue_PySTextBlock *self, PyObject * ar
return nullptr;
}

py_STextBlock->SetText(FString(UTF8_TO_TCHAR(text)));
py_STextBlock->SetText(FText::FromString(UTF8_TO_TCHAR(text)));

Py_RETURN_SLATE_SELF;
}
Expand Down Expand Up @@ -70,7 +70,11 @@ static int ue_py_stext_block_init(ue_PySTextBlock *self, PyObject *args, PyObjec
ue_py_slate_farguments_float("line_height_percentage", LineHeightPercentage);
ue_py_slate_farguments_struct("margin", Margin, FMargin);
ue_py_slate_farguments_float("min_desired_width", MinDesiredWidth);
#if ENGINE_MINOR_VERSION >= 23
ue_py_slate_farguments_event("on_double_clicked", OnDoubleClicked, FPointerEventHandler, OnMouseEvent);
#else
ue_py_slate_farguments_event("on_double_clicked", OnDoubleClicked, FOnClicked, OnClicked);
#endif
ue_py_slate_farguments_flinear_color("shadow_color_and_opacity", ShadowColorAndOpacity);
ue_py_slate_farguments_fvector2d("shadow_offset", ShadowOffset);
ue_py_slate_farguments_text("text", Text);
Expand Down
5 changes: 4 additions & 1 deletion Source/UnrealEnginePython/Private/Slate/UEPySlate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1020,8 +1020,11 @@ class FPythonSlateCommands : public TCommands<FPythonSlateCommands>
virtual void RegisterCommands() override
{
commands = MakeShareable(new FUICommandList);

#if ENGINE_MINOR_VERSION >= 23
MakeUICommand_InternalUseOnly(this, command, nullptr, *name, *name, TCHAR_TO_UTF8(*name), *name, *name, EUserInterfaceActionType::Button, FInputGesture());
#else
UI_COMMAND_Function(this, command, nullptr, *name, *name, TCHAR_TO_UTF8(*name), *name, *name, EUserInterfaceActionType::Button, FInputGesture());
#endif
commands->MapAction(command, FExecuteAction::CreateRaw(this, &FPythonSlateCommands::Callback), FCanExecuteAction());
}

Expand Down
58 changes: 58 additions & 0 deletions Source/UnrealEnginePython/Private/UEPyEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,12 @@ PyObject *py_unreal_engine_get_selected_assets(PyObject * self, PyObject * args)

PyObject *py_unreal_engine_get_all_edited_assets(PyObject * self, PyObject * args)
{
#if ENGINE_MINOR_VERSION >= 24
UAssetEditorSubsystem* AssetEditorSubsystem = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>();
TArray<UObject *> assets = AssetEditorSubsystem->GetAllEditedAssets();
#else
TArray<UObject *> assets = FAssetEditorManager::Get().GetAllEditedAssets();
#endif
PyObject *assets_list = PyList_New(0);

for (UObject *asset : assets)
Expand Down Expand Up @@ -1168,7 +1173,12 @@ PyObject *py_unreal_engine_open_editor_for_asset(PyObject * self, PyObject * arg
if (!u_obj)
return PyErr_Format(PyExc_Exception, "argument is not a UObject");

#if ENGINE_MINOR_VERSION >= 24
UAssetEditorSubsystem* AssetEditorSubsystem = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>();
if (AssetEditorSubsystem->OpenEditorForAsset(u_obj))
#else
if (FAssetEditorManager::Get().OpenEditorForAsset(u_obj))
#endif
{
Py_RETURN_TRUE;
}
Expand All @@ -1193,7 +1203,11 @@ PyObject *py_unreal_engine_find_editor_for_asset(PyObject * self, PyObject * arg
if (py_bool && PyObject_IsTrue(py_bool))
bFocus = true;

#if ENGINE_MINOR_VERSION >= 24
IAssetEditorInstance* instance = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>()->FindEditorForAsset(u_obj, bFocus);
#else
IAssetEditorInstance *instance = FAssetEditorManager::Get().FindEditorForAsset(u_obj, bFocus);
#endif
if (!instance)
return PyErr_Format(PyExc_Exception, "no editor found for asset");

Expand All @@ -1212,14 +1226,23 @@ PyObject *py_unreal_engine_close_editor_for_asset(PyObject * self, PyObject * ar
UObject *u_obj = ue_py_check_type<UObject>(py_obj);
if (!u_obj)
return PyErr_Format(PyExc_Exception, "argument is not a UObject");

#if ENGINE_MINOR_VERSION >= 24
GEditor->GetEditorSubsystem<UAssetEditorSubsystem>()->CloseAllEditorsForAsset(u_obj);
#else
FAssetEditorManager::Get().CloseAllEditorsForAsset(u_obj);
#endif

Py_RETURN_NONE;
}

PyObject *py_unreal_engine_close_all_asset_editors(PyObject * self, PyObject * args)
{
#if ENGINE_MINOR_VERSION >= 24
GEditor->GetEditorSubsystem<UAssetEditorSubsystem>()->CloseAllAssetEditors();
#else
FAssetEditorManager::Get().CloseAllAssetEditors();
#endif

Py_RETURN_NONE;
}
Expand Down Expand Up @@ -1336,6 +1359,9 @@ PyObject *py_unreal_engine_get_blueprint_hierarchy_from_class(PyObject * self, P

PyObject *py_unreal_engine_reload_blueprint(PyObject * self, PyObject * args)
{
#if ENGINE_MINOR_VERSION >= 24
return PyErr_Format(PyExc_Exception, "Functionality not supported in UE 4.24");
#else

PyObject *py_blueprint;
if (!PyArg_ParseTuple(args, "O:reload_blueprint", &py_blueprint))
Expand All @@ -1359,6 +1385,7 @@ PyObject *py_unreal_engine_reload_blueprint(PyObject * self, PyObject * args)
Py_END_ALLOW_THREADS

Py_RETURN_UOBJECT(reloaded_bp);
#endif
}

PyObject *py_unreal_engine_compile_blueprint(PyObject * self, PyObject * args)
Expand Down Expand Up @@ -1473,6 +1500,37 @@ PyObject *py_unreal_engine_get_blueprint_components(PyObject * self, PyObject *

}

PyObject *py_unreal_engine_remove_component_from_blueprint(PyObject *self, PyObject *args)
{
PyObject *py_blueprint;
char *name;
char *parentName = nullptr;

if (!PyArg_ParseTuple(args, "Os|s:remove_component_from_blueprint", &py_blueprint, &name, &parentName))
{
return NULL;
}

if (!ue_is_pyuobject(py_blueprint))
{
return PyErr_Format(PyExc_Exception, "argument is not a UObject");
}

ue_PyUObject *py_obj = (ue_PyUObject *)py_blueprint;
if (!py_obj->ue_object->IsA<UBlueprint>())
return PyErr_Format(PyExc_Exception, "uobject is not a UBlueprint");
UBlueprint *bp = (UBlueprint *)py_obj->ue_object;

bp->Modify();
USCS_Node *ComponentNode = bp->SimpleConstructionScript->FindSCSNode(UTF8_TO_TCHAR(name));
if (ComponentNode)
{
bp->SimpleConstructionScript->RemoveNode(ComponentNode);
}

Py_RETURN_NONE;
}

PyObject *py_unreal_engine_add_component_to_blueprint(PyObject * self, PyObject * args)
{

Expand Down
Loading