Skip to content

Commit 2216cad

Browse files
author
Roberto De Ioris
committed
added folder api
1 parent bd21076 commit 2216cad

File tree

6 files changed

+192
-1
lines changed

6 files changed

+192
-1
lines changed

Source/UnrealEnginePython/Private/UEPyModule.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,14 @@ static PyMethodDef ue_PyUObject_methods[] = {
621621
{ "set_actor_label", (PyCFunction)py_ue_set_actor_label, METH_VARARGS, "" },
622622
{ "set_actor_hidden_in_game", (PyCFunction)py_ue_set_actor_hidden_in_game, METH_VARARGS, "" },
623623

624+
{ "get_folder_path", (PyCFunction)py_ue_get_folder_path, METH_VARARGS, "" },
625+
{ "set_folder_path", (PyCFunction)py_ue_set_folder_path, METH_VARARGS, "" },
626+
627+
{ "world_create_folder", (PyCFunction)py_ue_world_create_folder, METH_VARARGS, "" },
628+
{ "world_delete_folder", (PyCFunction)py_ue_world_delete_folder, METH_VARARGS, "" },
629+
{ "world_rename_folder", (PyCFunction)py_ue_world_rename_folder, METH_VARARGS, "" },
630+
{ "world_folders", (PyCFunction)py_ue_world_folders, METH_VARARGS, "" },
631+
624632
{ "get_editor_world_counterpart_actor", (PyCFunction)py_ue_get_editor_world_counterpart_actor, METH_VARARGS, "" },
625633
{ "component_type_registry_invalidate_class", (PyCFunction)py_ue_component_type_registry_invalidate_class, METH_VARARGS, "" },
626634

Source/UnrealEnginePython/Private/UObject/UEPyActor.cpp

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,49 @@ PyObject *py_ue_component_type_registry_invalidate_class(ue_PyUObject *self, PyO
221221
Py_RETURN_NONE;
222222
}
223223

224+
PyObject *py_ue_get_folder_path(ue_PyUObject *self, PyObject * args)
225+
{
226+
227+
ue_py_check(self);
228+
229+
AActor *actor = ue_py_check_type<AActor>(self);
230+
if (!actor)
231+
return PyErr_Format(PyExc_Exception, "uobject is not an actor");
232+
233+
const FName DirPath = actor->GetFolderPath();
234+
235+
return PyUnicode_FromString(TCHAR_TO_UTF8(*DirPath.ToString()));
236+
}
237+
238+
PyObject *py_ue_set_folder_path(ue_PyUObject *self, PyObject * args)
239+
{
240+
241+
ue_py_check(self);
242+
243+
char *path;
244+
PyObject *py_bool = nullptr;
245+
246+
if (!PyArg_ParseTuple(args, "s|O:set_folder_path", &path, &py_bool))
247+
return nullptr;
248+
249+
AActor *actor = ue_py_check_type<AActor>(self);
250+
if (!actor)
251+
return PyErr_Format(PyExc_Exception, "uobject is not an actor");
252+
253+
FName DirPath = FName(UTF8_TO_TCHAR(path));
254+
255+
if (py_bool && PyObject_IsTrue(py_bool))
256+
{
257+
actor->SetFolderPath_Recursively(DirPath);
258+
}
259+
else
260+
{
261+
actor->SetFolderPath(DirPath);
262+
}
263+
264+
Py_RETURN_NONE;
265+
}
266+
224267
PyObject *py_ue_get_actor_label(ue_PyUObject *self, PyObject * args)
225268
{
226269

@@ -285,7 +328,7 @@ PyObject *py_ue_set_actor_hidden_in_game(ue_PyUObject *self, PyObject * args)
285328
actor->SetActorHiddenInGame(false);
286329
}
287330

288-
331+
289332

290333
Py_RETURN_NONE;
291334
}

Source/UnrealEnginePython/Private/UObject/UEPyActor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ PyObject *py_ue_actor_set_level_sequence(ue_PyUObject *, PyObject *);
2727
#if WITH_EDITOR
2828
PyObject *py_ue_get_actor_label(ue_PyUObject *, PyObject *);
2929
PyObject *py_ue_set_actor_label(ue_PyUObject *, PyObject *);
30+
PyObject *py_ue_get_folder_path(ue_PyUObject *, PyObject *);
31+
PyObject *py_ue_set_folder_path(ue_PyUObject *, PyObject *);
3032
PyObject *py_ue_set_actor_hidden_in_game(ue_PyUObject *, PyObject *);
3133
PyObject *py_ue_find_actor_by_label(ue_PyUObject *, PyObject *);
3234
PyObject *py_ue_get_editor_world_counterpart_actor(ue_PyUObject *, PyObject *);

Source/UnrealEnginePython/Private/UObject/UEPyWorld.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#include "EngineUtils.h"
55
#include "Kismet/GameplayStatics.h"
66
#include "Runtime/CoreUObject/Public/UObject/UObjectIterator.h"
7+
#if WITH_EDITOR
8+
#include "Editor/UnrealEd/Public/EditorActorFolders.h"
9+
#endif
710

811
PyObject *py_ue_world_exec(ue_PyUObject *self, PyObject * args)
912
{
@@ -315,3 +318,105 @@ PyObject *py_ue_set_current_level(ue_PyUObject *self, PyObject * args)
315318
Py_RETURN_FALSE;
316319
}
317320

321+
#if WITH_EDITOR
322+
PyObject *py_ue_world_create_folder(ue_PyUObject *self, PyObject * args)
323+
{
324+
325+
ue_py_check(self);
326+
327+
char *path;
328+
if (!PyArg_ParseTuple(args, "s:world_create_folder", &path))
329+
return nullptr;
330+
331+
if (!FActorFolders::IsAvailable())
332+
return PyErr_Format(PyExc_Exception, "FActorFolders is not available");
333+
334+
UWorld *world = ue_get_uworld(self);
335+
if (!world)
336+
return PyErr_Format(PyExc_Exception, "unable to retrieve UWorld from uobject");
337+
338+
FName FolderPath = FName(UTF8_TO_TCHAR(path));
339+
340+
FActorFolders::Get().CreateFolder(*world, FolderPath);
341+
342+
Py_RETURN_NONE;
343+
}
344+
345+
PyObject *py_ue_world_delete_folder(ue_PyUObject *self, PyObject * args)
346+
{
347+
348+
ue_py_check(self);
349+
350+
char *path;
351+
if (!PyArg_ParseTuple(args, "s:world_delete_folder", &path))
352+
return nullptr;
353+
354+
if (!FActorFolders::IsAvailable())
355+
return PyErr_Format(PyExc_Exception, "FActorFolders is not available");
356+
357+
UWorld *world = ue_get_uworld(self);
358+
if (!world)
359+
return PyErr_Format(PyExc_Exception, "unable to retrieve UWorld from uobject");
360+
361+
FName FolderPath = FName(UTF8_TO_TCHAR(path));
362+
363+
FActorFolders::Get().DeleteFolder(*world, FolderPath);
364+
365+
Py_RETURN_NONE;
366+
}
367+
368+
PyObject *py_ue_world_rename_folder(ue_PyUObject *self, PyObject * args)
369+
{
370+
371+
ue_py_check(self);
372+
373+
char *path;
374+
char *new_path;
375+
if (!PyArg_ParseTuple(args, "ss:world_rename_folder", &path, &new_path))
376+
return nullptr;
377+
378+
if (!FActorFolders::IsAvailable())
379+
return PyErr_Format(PyExc_Exception, "FActorFolders is not available");
380+
381+
UWorld *world = ue_get_uworld(self);
382+
if (!world)
383+
return PyErr_Format(PyExc_Exception, "unable to retrieve UWorld from uobject");
384+
385+
FName FolderPath = FName(UTF8_TO_TCHAR(path));
386+
FName NewFolderPath = FName(UTF8_TO_TCHAR(new_path));
387+
388+
if (FActorFolders::Get().RenameFolderInWorld(*world, FolderPath, NewFolderPath))
389+
Py_RETURN_TRUE;
390+
391+
Py_RETURN_FALSE;
392+
}
393+
394+
PyObject *py_ue_world_folders(ue_PyUObject *self, PyObject * args)
395+
{
396+
397+
ue_py_check(self);
398+
399+
if (!FActorFolders::IsAvailable())
400+
return PyErr_Format(PyExc_Exception, "FActorFolders is not available");
401+
402+
UWorld *world = ue_get_uworld(self);
403+
if (!world)
404+
return PyErr_Format(PyExc_Exception, "unable to retrieve UWorld from uobject");
405+
406+
const TMap<FName, FActorFolderProps> &Folders = FActorFolders::Get().GetFolderPropertiesForWorld(*world);
407+
408+
PyObject *py_list = PyList_New(0);
409+
410+
TArray<FName> FolderNames;
411+
Folders.GenerateKeyArray(FolderNames);
412+
413+
for (FName FolderName : FolderNames)
414+
{
415+
PyObject *py_str = PyUnicode_FromString(TCHAR_TO_UTF8(*FolderName.ToString()));
416+
PyList_Append(py_list, py_str);
417+
Py_DECREF(py_str);
418+
}
419+
420+
return py_list;
421+
}
422+
#endif

Source/UnrealEnginePython/Private/UObject/UEPyWorld.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,10 @@ PyObject *py_ue_set_current_level(ue_PyUObject *, PyObject *);
3030

3131
PyObject *py_ue_get_world_type(ue_PyUObject *, PyObject *);
3232

33+
#if WITH_EDITOR
34+
PyObject *py_ue_world_create_folder(ue_PyUObject *, PyObject *);
35+
PyObject *py_ue_world_delete_folder(ue_PyUObject *, PyObject *);
36+
PyObject *py_ue_world_rename_folder(ue_PyUObject *, PyObject *);
37+
PyObject *py_ue_world_folders(ue_PyUObject *, PyObject *);
38+
#endif
39+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import unreal_engine as ue
2+
from unreal_engine.classes import GroupActor
3+
4+
import time
5+
6+
world = ue.get_editor_world()
7+
group_actor = world.actor_spawn(GroupActor)
8+
9+
for folder in world.world_folders():
10+
print(folder)
11+
12+
new_folder = 'FooBar_{}'.format(int(time.time()))
13+
14+
world.world_create_folder(new_folder)
15+
16+
world.world_rename_folder(new_folder, new_folder + '__hello')
17+
18+
world.world_delete_folder(new_folder + '__hello')
19+
20+
actor = ue.editor_get_selected_actors()[0]
21+
22+
# folder tree will be automatically created
23+
actor.set_folder_path('Test1/Test2/Test3')
24+
25+
# assign actors to the group
26+
group_actor.GroupActors = [actor]

0 commit comments

Comments
 (0)