Skip to content

Commit 03c2f96

Browse files
author
Roberto De Ioris
committed
various HUD improvements
1 parent c6938bd commit 03c2f96

File tree

14 files changed

+281
-24
lines changed

14 files changed

+281
-24
lines changed

Source/UnrealEnginePython/Private/PyActor.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ APyActor::APyActor()
1212

1313
}
1414

15-
void APyActor::PostInitializeComponents()
15+
void APyActor::PreInitializeComponents()
1616
{
17-
Super::PostInitializeComponents();
18-
17+
Super::PreInitializeComponents();
1918

2019
if (PythonModule.IsEmpty())
2120
return;
@@ -73,6 +72,25 @@ void APyActor::PostInitializeComponents()
7372

7473
ue_bind_events_for_py_class_by_attribute(this, py_actor_instance);
7574

75+
if (!PyObject_HasAttrString(py_actor_instance, (char *)"pre_initialize_components"))
76+
return;
77+
78+
PyObject *pic_ret = PyObject_CallMethod(py_actor_instance, (char *)"pre_initialize_components", NULL);
79+
if (!pic_ret) {
80+
unreal_engine_py_log_error();
81+
return;
82+
}
83+
Py_DECREF(pic_ret);
84+
}
85+
86+
87+
void APyActor::PostInitializeComponents()
88+
{
89+
Super::PostInitializeComponents();
90+
91+
if (!py_actor_instance)
92+
return;
93+
7694
if (!PyObject_HasAttrString(py_actor_instance, (char *)"post_initialize_components"))
7795
return;
7896

Source/UnrealEnginePython/Private/UEPyModule.cpp

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ static PyMethodDef unreal_engine_methods[] = {
159159
{ "compress_image_array", py_unreal_engine_compress_image_array, METH_VARARGS, "" },
160160
{ "create_checkerboard_texture", py_unreal_engine_create_checkerboard_texture, METH_VARARGS, "" },
161161
{ "create_transient_texture", py_unreal_engine_create_transient_texture, METH_VARARGS, "" },
162+
{ "create_transient_texture_render_target2d", py_unreal_engine_create_transient_texture_render_target2d, METH_VARARGS, "" },
162163

163164
{ "create_world", py_unreal_engine_create_world, METH_VARARGS, "" },
164165

@@ -290,7 +291,7 @@ static PyMethodDef unreal_engine_methods[] = {
290291

291292
{ "get_game_viewport_client", py_unreal_engine_get_game_viewport_client, METH_VARARGS, "" },
292293
#pragma warning(suppress: 4191)
293-
{ "open_color_picker", (PyCFunction)py_unreal_engine_open_color_picker, METH_VARARGS| METH_KEYWORDS, "" },
294+
{ "open_color_picker", (PyCFunction)py_unreal_engine_open_color_picker, METH_VARARGS | METH_KEYWORDS, "" },
294295
{ "destroy_color_picker", py_unreal_engine_destroy_color_picker, METH_VARARGS, "" },
295296
{ "play_sound", py_unreal_engine_play_sound, METH_VARARGS, "" },
296297
#if WITH_EDITOR
@@ -406,7 +407,7 @@ static PyMethodDef ue_PyUObject_methods[] = {
406407
{ "set_actor_label", (PyCFunction)py_ue_set_actor_label, METH_VARARGS, "" },
407408

408409
{ "get_editor_world_counterpart_actor", (PyCFunction)py_ue_get_editor_world_counterpart_actor, METH_VARARGS, "" },
409-
410+
410411
{ "find_actor_by_label", (PyCFunction)py_ue_find_actor_by_label, METH_VARARGS, "" },
411412
{ "save_package", (PyCFunction)py_ue_save_package, METH_VARARGS, "" },
412413
{ "asset_can_reimport", (PyCFunction)py_ue_asset_can_reimport, METH_VARARGS, "" },
@@ -437,6 +438,7 @@ static PyMethodDef ue_PyUObject_methods[] = {
437438

438439
{ "is_rooted", (PyCFunction)py_ue_is_rooted, METH_VARARGS, "" },
439440
{ "add_to_root", (PyCFunction)py_ue_add_to_root, METH_VARARGS, "" },
441+
{ "auto_root", (PyCFunction)py_ue_auto_root, METH_VARARGS, "" },
440442
{ "remove_from_root", (PyCFunction)py_ue_remove_from_root, METH_VARARGS, "" },
441443

442444
{ "find_function", (PyCFunction)py_ue_find_function, METH_VARARGS, "" },
@@ -498,6 +500,8 @@ static PyMethodDef ue_PyUObject_methods[] = {
498500
{ "hud_draw_2d_line", (PyCFunction)py_ue_hud_draw_2d_line, METH_VARARGS, "" },
499501
{ "hud_draw_line", (PyCFunction)py_ue_hud_draw_line, METH_VARARGS, "" },
500502
{ "hud_draw_texture", (PyCFunction)py_ue_hud_draw_texture, METH_VARARGS, "" },
503+
{ "hud_draw_rect", (PyCFunction)py_ue_hud_draw_rect, METH_VARARGS, "" },
504+
{ "hud_draw_text", (PyCFunction)py_ue_hud_draw_text, METH_VARARGS, "" },
501505

502506

503507
// Movements
@@ -527,6 +531,8 @@ static PyMethodDef ue_PyUObject_methods[] = {
527531

528532
{ "component_is_registered", (PyCFunction)py_ue_component_is_registered, METH_VARARGS, "" },
529533
{ "register_component", (PyCFunction)py_ue_register_component, METH_VARARGS, "" },
534+
{ "unregister_component", (PyCFunction)py_ue_unregister_component, METH_VARARGS, "" },
535+
{ "destroy_component", (PyCFunction)py_ue_destroy_component, METH_VARARGS, "" },
530536

531537
{ "actor_destroy_component", (PyCFunction)py_ue_actor_destroy_component, METH_VARARGS, "" },
532538
{ "destroy_actor_component", (PyCFunction)py_ue_actor_destroy_component, METH_VARARGS, "" },
@@ -554,7 +560,8 @@ static PyMethodDef ue_PyUObject_methods[] = {
554560
{ "actor_has_component_of_type", (PyCFunction)py_ue_actor_has_component_of_type, METH_VARARGS, "" },
555561

556562
{ "actor_destroy", (PyCFunction)py_ue_actor_destroy, METH_VARARGS, "" },
557-
{ "actor_spawn", (PyCFunction)py_ue_actor_spawn, METH_VARARGS, "" },
563+
#pragma warning(suppress: 4191)
564+
{ "actor_spawn", (PyCFunction)py_ue_actor_spawn, METH_VARARGS | METH_KEYWORDS, "" },
558565
{ "actor_has_tag", (PyCFunction)py_ue_actor_has_tag, METH_VARARGS, "" },
559566
{ "get_actor_bounds", (PyCFunction)py_ue_get_actor_bounds, METH_VARARGS, "" },
560567

@@ -579,6 +586,8 @@ static PyMethodDef ue_PyUObject_methods[] = {
579586
{ "get_actor_components_by_type", (PyCFunction)py_ue_get_actor_components_by_type, METH_VARARGS, "" },
580587
{ "get_components_by_type", (PyCFunction)py_ue_get_actor_components_by_type, METH_VARARGS, "" },
581588

589+
{ "add_python_component", (PyCFunction)py_ue_add_python_component, METH_VARARGS, "" },
590+
582591
{ "set_simulate_physics", (PyCFunction)py_ue_set_simulate_physics, METH_VARARGS, "" },
583592
{ "add_impulse", (PyCFunction)py_ue_add_impulse, METH_VARARGS, "" },
584593
{ "add_angular_impulse", (PyCFunction)py_ue_add_angular_impulse, METH_VARARGS, "" },
@@ -588,7 +597,7 @@ static PyMethodDef ue_PyUObject_methods[] = {
588597
{ "get_physics_linear_velocity", (PyCFunction)py_ue_get_physics_linear_velocity, METH_VARARGS, "" },
589598
{ "set_physics_angular_velocity", (PyCFunction)py_ue_set_physics_angular_velocity, METH_VARARGS, "" },
590599
{ "get_physics_angular_velocity", (PyCFunction)py_ue_get_physics_angular_velocity, METH_VARARGS, "" },
591-
{ "find_object", (PyCFunction)py_ue_find_object, METH_VARARGS, "" },
600+
{ "find_object", (PyCFunction)py_ue_find_object, METH_VARARGS, "" },
592601
{ "get_world", (PyCFunction)py_ue_get_world, METH_VARARGS, "" },
593602
{ "has_world", (PyCFunction)py_ue_has_world, METH_VARARGS, "" },
594603

@@ -597,8 +606,8 @@ static PyMethodDef ue_PyUObject_methods[] = {
597606
{ "get_world_location_at_distance_along_spline", (PyCFunction)py_ue_get_world_location_at_distance_along_spline, METH_VARARGS, "" },
598607
{ "get_spline_length", (PyCFunction)py_ue_get_spline_length, METH_VARARGS, "" },
599608

600-
// Widget
601-
{ "take_widget", (PyCFunction)py_ue_take_widget, METH_VARARGS, "" },
609+
// Widget
610+
{ "take_widget", (PyCFunction)py_ue_take_widget, METH_VARARGS, "" },
602611

603612
// WidgetComponent
604613
{ "set_slate_widget", (PyCFunction)py_ue_set_slate_widget, METH_VARARGS, "" },
@@ -622,6 +631,7 @@ static PyMethodDef ue_PyUObject_methods[] = {
622631
{ "get_num_spectators", (PyCFunction)py_ue_get_num_spectators, METH_VARARGS, "" },
623632
{ "get_player_controller", (PyCFunction)py_ue_get_player_controller, METH_VARARGS, "" },
624633
{ "get_player_hud", (PyCFunction)py_ue_get_player_hud, METH_VARARGS, "" },
634+
{ "set_player_hud", (PyCFunction)py_ue_set_player_hud, METH_VARARGS, "" },
625635
{ "get_player_camera_manager", (PyCFunction)py_ue_get_player_camera_manager, METH_VARARGS, "" },
626636
{ "get_player_pawn", (PyCFunction)py_ue_get_player_pawn, METH_VARARGS, "" },
627637

@@ -671,6 +681,7 @@ static PyMethodDef ue_PyUObject_methods[] = {
671681
{ "texture_get_width", (PyCFunction)py_ue_texture_get_width, METH_VARARGS, "" },
672682
{ "texture_get_height", (PyCFunction)py_ue_texture_get_height, METH_VARARGS, "" },
673683
{ "render_target_get_data", (PyCFunction)py_ue_render_target_get_data, METH_VARARGS, "" },
684+
{ "texture_update_resource", (PyCFunction)py_ue_texture_update_resource, METH_VARARGS, "" },
674685

675686
// Sequencer
676687
{ "sequencer_master_tracks", (PyCFunction)py_ue_sequencer_master_tracks, METH_VARARGS, "" },
@@ -749,12 +760,16 @@ void ue_pydelegates_cleanup(ue_PyUObject *self) {
749760
UE_LOG(LogPython, Warning, TEXT("Removing UPythonDelegate %p from ue_PyUObject %p mapped to UObject %p"), py_delegate, self, self->ue_object);
750761
#endif
751762
py_delegate->RemoveFromRoot();
763+
}
752764
}
753-
}
754765
self->python_delegates_gc->clear();
755766
delete self->python_delegates_gc;
756767
self->python_delegates_gc = nullptr;
757768

769+
if (self->auto_rooted && self->ue_object->IsRooted()) {
770+
self->ue_object->RemoveFromRoot();
771+
}
772+
758773
Py_XDECREF(self->py_dict);
759774
}
760775

@@ -826,8 +841,8 @@ static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name)
826841
return PyLong_FromLong(u_enum->FindEnumIndex(item.Key));
827842
#endif
828843
}
829-
}
830844
}
845+
}
831846
#endif
832847
if (self->ue_object->IsA<UEnum>()) {
833848
UEnum *u_enum = (UEnum *)self->ue_object;
@@ -837,15 +852,15 @@ static PyObject *ue_PyUObject_getattro(ue_PyUObject *self, PyObject *attr_name)
837852
#else
838853
return PyLong_FromLong(u_enum->FindEnumIndex(FName(UTF8_TO_TCHAR(attr))));
839854
#endif
840-
}
841-
}
855+
}
856+
}
842857

843858
if (function) {
844859
// swallow previous exception
845860
PyErr_Clear();
846861
return py_ue_new_callable(function, self->ue_object);
847862
}
848-
}
863+
}
849864
}
850865
return ret;
851866
}
@@ -1460,7 +1475,7 @@ void unreal_engine_py_log_error() {
14601475
PyObject *zero = PyUnicode_AsUTF8String(PyObject_Str(value));
14611476
if (zero) {
14621477
msg = PyBytes_AsString(zero);
1463-
}
1478+
}
14641479
#else
14651480
msg = PyString_AsString(PyObject_Str(value));
14661481
#endif

Source/UnrealEnginePython/Private/UEPyModule.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@
1010

1111
typedef struct {
1212
PyObject_HEAD
13-
/* Type-specific fields go here. */
14-
UObject *ue_object;
13+
/* Type-specific fields go here. */
14+
UObject *ue_object;
1515
// reference to proxy class (can be null)
1616
PyObject *py_proxy;
1717
// list of exposed delegates
1818
std::list<UPythonDelegate*> *python_delegates_gc;
1919
// the __dict__
2020
PyObject *py_dict;
21+
// if true RemoveFromRoot will be called at object destruction time
22+
int auto_rooted;
2123
} ue_PyUObject;
2224

2325

Source/UnrealEnginePython/Private/UObject/UEPyActor.cpp

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "Runtime/LevelSequence/Public/LevelSequenceActor.h"
44
#include "Runtime/LevelSequence/Public/LevelSequence.h"
5+
#include "PythonComponent.h"
6+
#include "UEPyObject.h"
57

68
PyObject *py_ue_actor_has_tag(ue_PyUObject * self, PyObject * args) {
79

@@ -309,6 +311,30 @@ PyObject *py_ue_setup_attachment(ue_PyUObject *self, PyObject * args) {
309311
Py_RETURN_NONE;
310312
}
311313

314+
PyObject *py_ue_unregister_component(ue_PyUObject * self, PyObject * args) {
315+
ue_py_check(self);
316+
317+
UActorComponent *component = ue_py_check_type<UActorComponent>(self);
318+
if (!component)
319+
return PyErr_Format(PyExc_Exception, "uobject is not an UActorComponent");
320+
321+
component->UnregisterComponent();
322+
323+
Py_RETURN_NONE;
324+
}
325+
326+
PyObject *py_ue_destroy_component(ue_PyUObject * self, PyObject * args) {
327+
ue_py_check(self);
328+
329+
UActorComponent *component = ue_py_check_type<UActorComponent>(self);
330+
if (!component)
331+
return PyErr_Format(PyExc_Exception, "uobject is not an UActorComponent");
332+
333+
component->DestroyComponent();
334+
335+
Py_RETURN_NONE;
336+
}
337+
312338
PyObject *py_ue_add_actor_component(ue_PyUObject * self, PyObject * args) {
313339

314340
ue_py_check(self);
@@ -369,7 +395,40 @@ PyObject *py_ue_add_actor_component(ue_PyUObject * self, PyObject * args) {
369395
return PyErr_Format(PyExc_Exception, "uobject is in invalid state");
370396
Py_INCREF(ret);
371397
return ret;
398+
}
399+
400+
PyObject *py_ue_add_python_component(ue_PyUObject * self, PyObject * args) {
401+
402+
ue_py_check(self);
403+
404+
char *name;
405+
char *module_name;
406+
char *class_name;
407+
if (!PyArg_ParseTuple(args, "sss:add_python_component", &name, &module_name, &class_name)) {
408+
return NULL;
409+
}
372410

411+
AActor *actor = ue_py_check_type<AActor >(self);
412+
if (!actor) {
413+
return PyErr_Format(PyExc_Exception, "uobject is not an AActor");
414+
}
415+
416+
UPythonComponent *component = NewObject<UPythonComponent>(actor, FName(UTF8_TO_TCHAR(name)));
417+
if (!component)
418+
return PyErr_Format(PyExc_Exception, "unable to create component");
419+
420+
component->PythonModule = FString(UTF8_TO_TCHAR(module_name));
421+
component->PythonClass = FString(UTF8_TO_TCHAR(class_name));
422+
423+
if (actor->GetWorld()) {
424+
component->RegisterComponent();
425+
}
426+
427+
PyObject *ret = (PyObject *)ue_get_python_wrapper(component);
428+
if (!ret)
429+
return PyErr_Format(PyExc_Exception, "uobject is in invalid state");
430+
Py_INCREF(ret);
431+
return ret;
373432
}
374433

375434
PyObject *py_ue_actor_create_default_subobject(ue_PyUObject * self, PyObject * args) {
@@ -580,7 +639,7 @@ PyObject *py_ue_get_actor_components_by_type(ue_PyUObject * self, PyObject * arg
580639
}
581640

582641

583-
PyObject *py_ue_actor_spawn(ue_PyUObject * self, PyObject * args) {
642+
PyObject *py_ue_actor_spawn(ue_PyUObject * self, PyObject * args, PyObject *kwargs) {
584643

585644
ue_py_check(self);
586645

@@ -629,9 +688,39 @@ PyObject *py_ue_actor_spawn(ue_PyUObject * self, PyObject * args) {
629688
rotation = py_rotation->rot;
630689
}
631690

632-
AActor *actor = world->SpawnActor((UClass *)py_obj->ue_object, &location, &rotation);
691+
AActor *actor = nullptr;
692+
PyObject *ret = nullptr;
693+
694+
if (kwargs && PyDict_Size(kwargs) > 0) {
695+
FTransform transform;
696+
transform.SetTranslation(location);
697+
transform.SetRotation(rotation.Quaternion());
698+
actor = world->SpawnActorDeferred<AActor>((UClass *)py_obj->ue_object, transform);
699+
if (!actor)
700+
return PyErr_Format(PyExc_Exception, "unable to spawn a new Actor");
701+
ue_PyUObject *py_u_obj = ue_get_python_wrapper(actor);
702+
if (!py_u_obj)
703+
return PyErr_Format(PyExc_Exception, "uobject is in invalid state");
704+
705+
PyObject *py_iter = PyObject_GetIter(kwargs);
706+
707+
while (PyObject *py_key = PyIter_Next(py_iter)) {
708+
PyObject *void_ret = py_ue_set_property(py_u_obj, Py_BuildValue("OO", py_key, PyDict_GetItem(kwargs, py_key)));
709+
if (!void_ret) {
710+
return PyErr_Format(PyExc_Exception, "unable to set property for new Actor");
711+
}
712+
}
713+
Py_DECREF(py_iter);
714+
UGameplayStatics::FinishSpawningActor(actor, transform);
715+
ret = (PyObject *)py_u_obj;
716+
}
717+
else {
718+
actor = world->SpawnActor((UClass *)py_obj->ue_object, &location, &rotation);
719+
if (!actor)
720+
return PyErr_Format(PyExc_Exception, "unable to spawn a new Actor");
721+
ret = (PyObject *)ue_get_python_wrapper(actor);
722+
}
633723

634-
PyObject *ret = (PyObject *)ue_get_python_wrapper(actor);
635724
if (!ret)
636725
return PyErr_Format(PyExc_Exception, "uobject is in invalid state");
637726
Py_INCREF(ret);

Source/UnrealEnginePython/Private/UObject/UEPyActor.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,18 @@ PyObject *py_ue_get_editor_world_counterpart_actor(ue_PyUObject *, PyObject *);
2020
#endif
2121
PyObject *py_ue_get_owner(ue_PyUObject *, PyObject *);
2222
PyObject *py_ue_add_actor_component(ue_PyUObject *, PyObject *);
23+
PyObject *py_ue_add_python_component(ue_PyUObject *, PyObject *);
2324
PyObject *py_ue_add_actor_root_component(ue_PyUObject *, PyObject *);
2425
PyObject *py_ue_actor_has_component_of_type(ue_PyUObject *, PyObject *);
2526
PyObject *py_ue_get_actor_component_by_type(ue_PyUObject *, PyObject *);
2627
PyObject *py_ue_get_actor_components_by_type(ue_PyUObject *, PyObject *);
27-
PyObject *py_ue_actor_spawn(ue_PyUObject * self, PyObject *);
28+
PyObject *py_ue_actor_spawn(ue_PyUObject * self, PyObject *, PyObject *);
2829
PyObject *py_ue_get_overlapping_actors(ue_PyUObject *, PyObject *);
2930

3031
PyObject *py_ue_actor_destroy_component(ue_PyUObject *, PyObject *);
3132

3233
PyObject *py_ue_register_component(ue_PyUObject * self, PyObject *);
34+
PyObject *py_ue_unregister_component(ue_PyUObject * self, PyObject *);
35+
PyObject *py_ue_destroy_component(ue_PyUObject * self, PyObject *);
3336
PyObject *py_ue_component_is_registered(ue_PyUObject * self, PyObject *);
3437
PyObject *py_ue_actor_create_default_subobject(ue_PyUObject * self, PyObject *);

0 commit comments

Comments
 (0)