Custom blueprint nodes defined in python need to be refreshed every time I reopen the editor

I have two python files of interest here: “dapi” and “init_unreal”

“dapi” contains code for custom blueprint nodes (like “Launch UI” in the screenshot). “init_unreal” only contains two statements : “import unreal” and “import dapi”. The init file seems to be running on editor startup like I would expect, but the editor utility widget blueprint still fails to compile. Using “Refresh all nodes” will work and then any custom nodes will work again, but that should only be a temporary workaround.

Is there something obvious I’m missing?

In the output log on editor startup, I’m noticing these errors being logged before the python modules are imported. Could that be the issue?

This is a module lifecycle issue.
By the time “ReconstructNode” method is called by the Blueprint graph, the custom function object in python scripting module were not created yet so pins can’t be reconstructed correctly when launching the editor.

You are then forced to refresh the node, by then the “ClassDefaultObject” have been finally loaded from whatever function library class they use, so when you refresh all nodes it can capture function signatures and rebuild pins accordingly.

That can be avoided when the function signature comes from C++, for generated functions like the ones created by python code, I will pay attention if Epic ever fix this structural problem because I face the same limitations while working on systems where I have to find function signatures but the Function Library default object wasn’t loaded yet on engine startup.

I’m having the same issue. Is there any feasible workaround other than writing C++? This problem makes this extremely useful feature unusable.

@VictorLerp

[USER=“9”]Stephen Ellis[/USER]

[USER=“4894”]Tim Hobson[/USER]

In case Python scripting team is still in trouble with this:

I have solved this problem on MagicNode plugin with custom serialization of pin type info to a temp *.node * file stored into project’s Intermediate folder.

Then in node’s Reconstruct() function, I restore pin data once to a in-memory struct from the file IF a node compilation happened or when Editor just launched.
I do the call to read the file from within “CreatePinsForScript()” in a case like this. Node is reconstructed successfully even though there isn’t any real UFunction existing at the time Unreal Editor is booting and Python nodes must be reconstructed… Blueprint serialization happens much later, so when the editor is finished launching, all serialized values are set back onto Pin->DefaultValue as if the pin always existed.

All hail the Json struct serializer:



void UKCS_MagicNode::PostReconstructNode()
{

    Super::PostReconstructNode();

    AllocateDefaultPins();

    CreatePinsForScript(GetScriptSource());

}


“ScriptData” is the struct that was loaded from file at Editor startup, then I convert it back to pins:



Script->LoadIntermediateData();  // <-- reads pin type info from file into a struct..

for (auto Info : Script->GetScriptData().PropertyInfo)
{
    if ( Info.ParamType == EParamType::Input )
    {
        if ( FindPin(Info.Name) == nullptr )
        {
            if ( UEdGraphPin * Pin = CreatePin( EGPD_Input, NAME_None, Info.Name ))
            {
                SetPinArchetype( Pin, Info.DataType );
                NewClassPins.Add( Pin );

                ///... ...
    }
}

K2_Schema->SetPinAutogeneratedDefaultValue( FindPin( Info.Name ), Info.DefaultValue );


Thanks I’ve notified the team :slight_smile:

Hi there!

Did this suggestion ever make it back into the code?

I’m still facing this issue on 4.27.1

Is there any alternative to force the python libraries to load before they get loaded now?

I ran into the same issue, and find a work around. Instead of wrap it with a blueprint node, I copy and paste the entire script into a Python Script Command node in the blueprint and run the script directly from there. Is it clean and nice? No. Does it work? YES~~

1 Like

Our team ran into the same issue. It would be great if it was adressed.

I haven’t tested this myself yet, but in speaking to a friend today we may have been pointed to a solution!

Apparently, you can define when a plugin module loads (and make it load earlier) as a part of the plugin descriptor file (.uplugin) by modifying the “LoadingPhase” value, which should fix the issue.

It’s not well documented, but you can find a descriptor file example here and some more useful info about modules below it.

I believe this link documents the different values you can use for the LoadingPhase of a specific module.

In short, I’m told that by adding your python functions to a plugin module that’s set to load earlier, you’ll avoid this issue entirely.

Hope this helps!

I’ve just tried that. It doesn’t work for me.
The loading of python modules always happen after all plugins are loaded, even if it’s inside a plugin which should load with EarliestPossible or PreDefault

Does anybody has any workaround ? I’ve tried having a dummy editor utility blueprint run early in loading doing a python command. The import still ends up after all plugins are loaded.

And @VictorLerp any update from the team ?