Download

What could cause my runtime plugin's UCLASSes to not show up in the editor?

Hello again everyone!

I’ve been working on my plugin again, but run into yet another problem that I was hoping someone might be able to shed some light on.
What parts of a plugin governs whether UCLASS:es defined in the plugins Classes / Private folders show up as possible parent classes when creating a new blueprint in the editor?

I’ve been looking at some other plugins for reference (for example the excellent hydra plugin A new, community-hosted Unreal Engine Wiki - Announcements and Releases - Unreal Engine Forums) and emulated most parts of it, but the config, build file and folder structure does not seem to be enough.

Does anyone have any immediate ideas of what might affect this?
For reference, my plug-in code is open source and can be found on:

Best regards,
Temaran

Forget about the Classes folder, that’s considered legacy at this point, but that’s not the cause of your problem. Try declaring the classes you want exposed as UCLASS(MinimalAPI, Blueprintable, BlueprintType), I would’ve expected the blueprint stuff to be inherited from APawn already so maybe you’re just missing the MinimalAPI.

Hello Enlight_2014!

Thank you for the suggestion, unfortunately this didn’t seem to solve the problem. I was not aware of the choice to abandon the current folder structure though (admittedly I haven’t fetched and checked out master in a while).

I’ve been investigating this since yesterday, and it seems like my plugin-classes are not even loaded into the class viewer. I followed the construction of the SClassViewer widget (the UI element that is responsible for enumerating and displaying all available classes when creating a new blueprint it seems). Providing logging in the class’s AddChildren_Tree function to spit out every class it considers seems to enumerate all my other classes defined in my root project, as well as the HydraPlugin classes if I have added and referenced it in the Project.Build.cs, but not any of my Plugin UCLASSES appear.

I’ve tried to figure out how all classes that are considered are loaded (to see if I have some malformed paths or maybe accidental filters or whatnot) so I’ve been playing around in the AssetRegistry.cpp class, but still to no avail. It just doesn’t seem to consider the UCLASSes in my plugin.

I can still statically link against all the plugin code if I add proper build / includes, and I can resolve the plugin interface and use the core functions (serve data through the hardware). It’s just that the classes refuse to show up through the SClassViewer :frowning:

Best regards,
Temaran

Hello again!

So I’ve been debugging this over the last day, but I still haven’t been able to find the problem. Stepping through the PluginManager / ModuleManager code, more specifically, the most interesting parts happen around ModuleManager.cpp:347; this is where the engine eventually does LoadLibrary, which in turn is what is supposed to instigate the execution of the static parts of my dll (more specifically the generated .inl files that perform UOBJECT registrations). For some reason though, my dll:s .generated.inl is not called into. The DLL itself seems to load fine (The handle is valid after LoadLibrary) but no symbols have been loaded (I can’t put breakpoints in my .inl file).

When studying the Hydra plugin in more detail however, I came across something curious, in this plugins build file, it seems like he first tried to go the statically linked lib route, but then changed his mind, commented out the lib reference and settled on loading the sixense dll dynamically at moduleinit. Does UE4 have some problem with statically linked 3rd party libs in plugins perhaps?
I was about to try and try this new route; to load the DLL myself and then get all function pointers I need to try and see if it would work for me too, but unlike the sixense libs, the lib I’m working with has tens of functions, and replacing everything will take some time, so I thought I’d post here first and see if anyone has any wisdom to share, or some light to shed on the situation.

edit:
To elaborate a bit; what I mean by “Does UE4 have some problem with statically linked 3rd party libs in plugins perhaps” is something in the lines of, since the lib is probably only a wrapper that calls into the dll anyways, and it would then have to look in the working directory of the project, which happens to be in the engine’s bin folder, I was up to this point just placing my client dll in that bin directory. But it occurred to me now that maybe UE doesn’t like plugin dll’s residing in the main bin directory (as it should, I just couldn’t find another workaround at that point). It did work when I did that though, but maybe when it is loading the plugin dll from my plugin’s bin folder, it needs the same reference again? I tried copying the dll to this location too, but it did not seem to work, so maybe there is some double load problem here. Anyways, my best lead atm is that UE4 has some problems with wrapper libraries such as this and that the solution might be to ignore the lib and load the dll manually in runtime.

Best regards,
Temaran

Hi Tamaran, which UE version is that?

We’ve had some problems with 4.2 where files that contained generated code were stripped at link time if nothing from the plugin code used it. For example: UCustomMeshComponent would not be available in cooked game (no-editor, monolithic exe) until you added UCustomMeshComponent::StaticClass(); call in UStaticMeshComponent constructor. This was mostly related to the fact we dropped generated.inl files in favor of generated.cpp files which are now automatically compiled by UnrealBuildTool. To be honest we’ve not had problems in the editor (which would load the plugin as a DLL) but you could give it a try and use the same trick I described above.


UYourPluginClass::UYourPluginClass(const FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
	UYourPluginClass::StaticClass();
	// Your constructor code goes here
}

Also, try adding YOURPLUGIN_API to your class declaration, like so:


class *YOURPLUGIN*_API UYourPluginClass : public USomeBase

Hello Robert!

Thank you for your response, I started out using 4.1 and then moved to 4.2, but I haven’t tried it on master yet.
Your suggestion fixed the problem! Thank you! The only remaining problem is that of working directory and dlls…
Since my lib is referencing a dll from the working directory, it doesn’t seem to be enough to put the dll in the plugins/MYPLUGIN/Binaries/Win64 folder (even though I can see that those dlls should be loaded in the modulemanager).

The workaround that seems to do the trick right now is to put the dll in the Engine/Binaries/Win64/, which makes it load correctly, but this is obviously not a very modular way to distribute.

But that is a much more minor problem! Thank you again for the response.

Best regards,
Temaran

Yeah, I’ve heard that working directory complaint from someone else too. It’s on my list :slight_smile: