Open sinokgr opened 8 years ago
Hi, i think
actors = ue.get_editor_world().all_actors()
is what you are searching for. Basically you are getting all the actors of the editor world.
unreal_engine.get_content_dir() should give you the path of the Content dir.
Regarding callbacks i did not know the import system supports them. Do you have some reference ?
Awesome! I need to find a way to discover these by myself... 😞 When working with Python I usually use help() and dir() to discover the functions etc. When I try to do that here, the help() fails because of Bad file descriptor and dir() always returns the same list no matter in what object I'm using it with. Any ideas why?
Hm, no I don't but I can ask epic. I'll get back to you about this as soon as they get back to me.
For dir:
ue.log(dir(ue.get_editor_world()))
unfortuntaley help() requires setting stdout/stderr, adding this on top of ue_site.py should be enough:
import sys
class UnrealEngineOutput:
def __init__(self, logger):
self.logger = logger
def write(self, buf):
self.logger(buf)
def flush(self):
return
sys.stdout = UnrealEngineOutput(ue.log)
sys.stderr = UnrealEngineOutput(ue.log_error)
Regarding to the dir, I was probably not very clear. What I was trying to say, is that both the following lines return the same value.
Lines:
ue.log(dir(ue.get_editor_world()))
ue.log(dir(ue.editor_get_selected_actors()[0]))
Result:
['__call__', '__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'actor_destroy', 'actor_has_component_of_type', 'actor_has_tag', 'actor_spawn', 'add_actor_component', 'add_actor_root_component', 'add_controller_pitch_input', 'add_controller_yaw_input', 'add_movement_input', 'add_property', 'add_to_root', 'all_actors', 'all_objects', 'as_dict', 'asset_reimport', 'attach_to_actor', 'attach_to_component', 'bind_action', 'bind_axis', 'bind_event', 'bind_input_axis', 'bind_key', 'bind_pressed_key', 'bind_released_key', 'broadcast', 'call', 'call_function', 'can_crouch', 'can_jump', 'component_is_registered', 'components', 'conditional_begin_destroy', 'create_player', 'crouch', 'destructible_apply_damage', 'draw_debug_line', 'enable_click_events', 'enable_input', 'enable_mouse_over_events', 'enum_values', 'find_actor_by_label', 'find_function', 'functions', 'get_actor_bounds', 'get_actor_component', 'get_actor_component_by_type', 'get_actor_components', 'get_actor_components_by_type', 'get_actor_forward', 'get_actor_label', 'get_actor_location', 'get_actor_right', 'get_actor_rotation', 'get_actor_scale', 'get_actor_up', 'get_actor_velocity', 'get_all_child_actors', 'get_anim_instance', 'get_attached_actors', 'get_cdo', 'get_class', 'get_component', 'get_component_by_type', 'get_components', 'get_components_by_type', 'get_control_rotation', 'get_forward_vector', 'get_full_name', 'get_hit_result_under_cursor', 'get_input_axis', 'get_metadata', 'get_name', 'get_num_players', 'get_num_spectators', 'get_outer', 'get_outermost', 'get_overlapping_actors', 'get_owner', 'get_player_controller', 'get_property', 'get_py_proxy', 'get_relative_location', 'get_relative_rotation', 'get_relative_scale', 'get_right_vector', 'get_socket_actor_transform', 'get_socket_location', 'get_socket_rotation', 'get_socket_transform', 'get_socket_world_transform', 'get_spline_length', 'get_super_class', 'get_up_vector', 'get_world', 'get_world_delta_seconds', 'get_world_location', 'get_world_location_at_distance_along_spline', 'get_world_rotation', 'get_world_scale', 'has_metadata', 'is_a', 'is_action_pressed', 'is_action_released', 'is_child_of', 'is_crouched', 'is_falling', 'is_flying', 'is_input_key_down', 'is_jumping', 'is_rooted', 'jump', 'launch', 'line_trace_multi_by_channel', 'line_trace_single_by_channel', 'play', 'play_sound_at_location', 'properties', 'quit_game', 'register_component', 'remove_from_root', 'save_package', 'sequencer_add_master_track', 'sequencer_find_possessable', 'sequencer_folders', 'sequencer_get_display_name', 'sequencer_master_tracks', 'sequencer_possessable_tracks', 'sequencer_possessables', 'sequencer_sections', 'sequencer_set_display_name', 'sequencer_track_sections', 'set_actor_label', 'set_actor_location', 'set_actor_rotation', 'set_actor_scale', 'set_metadata', 'set_name', 'set_property', 'set_relative_location', 'set_relative_rotation', 'set_relative_scale', 'set_simulate_physics', 'set_timer', 'set_view_target', 'set_world_location', 'set_world_rotation', 'set_world_scale', 'show_mouse_cursor', 'simple_move_to_location', 'stop_jumping', 'uncrouch', 'was_input_key_just_pressed', 'was_input_key_just_released', 'world_tick']
Awesome! Thanks for that! This should be really helpful!
I've asked Epic for the callbacks question. As soon as I get a reply, I'll let you know.
Epic got back to me and told me to look at
FEditorDelegates::FOnAssetPostImport FEditorDelegates::OnAssetPostImport;
And check the following example
\Engine\Source\Editor\Persona\Private\Persona.cpp(621): FEditorDelegates::OnAssetPostImport.AddRaw(this, &FPersona::OnPostImport);
They also said that there is no specific callback for the fbx importer and that this callback will be broadcast by any factory that import assets which I hope it's not a problem.
Ok, great i'll check it
Here it is:
import unreal_engine as ue
def post_import_hook(factory, u_object):
ue.log('PostImportHook !')
ue.log(factory)
ue.log(u_object)
ue.editor_on_asset_post_import(post_import_hook)
If you want to add more hooks, just base it from this commit:
https://github.com/20tab/UnrealEnginePython/commit/f9b16b95b53d2dd75ef50aa6d95b1c21cf33d08b
Thanks @rdeioris ! I've tried to add reimport support but I'm doing something wrong. It builds fine, but when I try to import something is stops at ~70% and then crashes, and if I reimport something, it says "reimport_hook() takes exactly 1 argument (2 given)"
That's the changes I've made:
PythonDelegate.h (inside the #if WITH_EDITOR ... #endif)
void PyFOnAssetReimport(UObject *u_object);
PythonDelegate.cpp (inside the #if WITH_EDITOR ... #endif)
void UPythonDelegate::PyFOnAssetReimport(UObject *u_object)
{
FScopePythonGIL gil;
PyObject *ret = PyObject_CallFunction(py_callable, (char *)"OO", ue_get_python_wrapper(u_object));
if (!ret) {
unreal_engine_py_log_error();
return;
}
Py_DECREF(ret);
}
UEPyModule.cpp (inside the #if WITH_EDITOR ... #endif)
{ "editor_on_asset_reimport", py_unreal_engine_editor_on_asset_reimport, METH_VARARGS, "" },
UEPyEditor.h (inside the #if WITH_EDITOR ... #endif)
PyObject *py_unreal_engine_editor_on_asset_reimport(PyObject *, PyObject *);
UEPyEditor.cpp (inside the #if WITH_EDITOR ... #endif)
PyObject *py_unreal_engine_editor_on_asset_reimport(PyObject * self, PyObject * args)
{
PyObject *py_callable;
if (!PyArg_ParseTuple(args, "O:editor_on_asset_reimport", &py_callable)) {
return NULL;
}
if (!PyCallable_Check(py_callable))
return PyErr_Format(PyExc_Exception, "object is not a callable");
UPythonDelegate *py_delegate = NewObject<UPythonDelegate>();
py_delegate->SetPyCallable(py_callable);
py_delegate->AddToRoot();
FEditorDelegates::OnAssetReimport.AddUObject(py_delegate, &UPythonDelegate::PyFOnAssetReimport);
Py_INCREF(Py_None);
return Py_None;
}
BTW, that's the python code
def reimport_hook(u_object):
ue.log("Reimport")
ue.log(u_object)
ue.editor_on_asset_reimport(reimport_hook)
Here it should be:
PyObject *ret = PyObject_CallFunction(py_callable, (char *)"O", ue_get_python_wrapper(u_object));
I thought so and I've tried that. It build fine but then Unreal stopped opening. I'll try again just in case I did something wrong.
Ok, it worked! Is there any case that VS is leaving stuff behind? I've noticed in a previous build that it was saying "Deleting old hot reload file", so what I did now (not sure if related), I've built it twice. At some point it was also kept crashing no matter the changes I was doing and this is when I built twice for the first time and that seemed to have fixed it. (I have a project for building the plugin and one working project that I copy the plugin to).
Yes, unfortunately you have to close the Unreal editor when you build a new version of the plugin, otherwise it will assumes an hot-reload. I have still not investigated if it is possibile to change this behaviour.
I don't see myself doing a lot of C++ dev, but that's good to know! :) Thanks
@sinokgr I am also looking to use the import and reimport hooks. Do you have a branch with this new functionality somewhere?
Hey @osstony, I'm afraid not. I don't have much experience with git so I don't want to mess anything up. I can confirm that the above code works though (with rdeioris fix). I've tested it on my project.
Hi @rdeioris, I was trying to assign the imported meta data to the Asset. I what I'm looking for is to add some AssetUserData to the UStaticMesh. It looks like we have access to AssetUserData property, but not to functions like AddAssetUserData, GetAssetUserDataArray() etc. Can you please expose them?
Hi guys,
I'm trying to export/import some data from 3dsMax file. I decided to save a .meta file for every FBX file we save (one FBX per geometry in our case).
I got it working for the selected Actors using the ue.editor_get_selected_actors() but I can't find a way to get all the level Actors (e.g. something like ue.editor_get_all_actors()). To be honest, I'm struggling to find a connection between the Assets and the Actors. I used for example the ue.get_assets_by_class('StaticMesh') to collect all the static meshes, I filtered the ones I wanted but then I couldn't find the Actors in the level.
Also, is there anyway to expose the "content" path? I want to scan the dir for my meta files (I assume what I'm looking for is the FPaths::GameContentDir()).
Last thing, is there any way to create callbacks? I might want to set a post_import callback to automatically load the meta files.
Thanks, Nick