Download

Why can't I call a plugin method from a actor?

Hi!
I was messing with plugins, and I can’t understand what’s the problem I’m facing:
First I created a plugin from the “editor stand alone window” preset and added the following code to the MyPlugin.h :

public:
	void UpdateMyTextBlock(FString MyNewContent);

	static inline FMyPluginModule& Get() { return FModuleManager::LoadModuleChecked <FMyPluginModule>("MyPlugin"); };

private:
	TSharedPtr<STextBlock> MyTextBlock;

and implemented UpdateMyTextBlock on my cpp file, and altered the SNew(STextBlock) to SAssingNew, like this:

TSharedRef<SDockTab> FMyPluginModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs)
{
	FText WidgetText = FText::FromString("OldText");

	return SNew(SDockTab)
		.TabRole(ETabRole::NomadTab)
		[
			// Put your tab content here!
			SNew(SBox)
			.HAlign(HAlign_Center)
			.VAlign(VAlign_Center)
			[
				SAssignNew(MyTextBlock, STextBlock)
				.Text(WidgetText)
			]
		];
}

void FMyPluginModule::UpdateMyTextBlock(FString MyNewContent)
{
	MyTextBlock->SetText(FText::FromString(MyNewContent));
}

And on my actor class I added the following:

MyActor.h:

private:
	FVector MyPosition;

MyActor.cpp:

#include "MyPlugin.h"

void AMyActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (MyPosition != GetTransform().GetLocation())
	{
		MyPosition = GetTransform().GetLocation();
		FString NewPosition = "X=" + FString::SanitizeFloat(MyPosition.X) + ", Y=" + FString::SanitizeFloat(MyPosition.Y) + ", Z=" + FString::SanitizeFloat(MyPosition.Z);
		FMyPluginModule::Get().UpdateMyTextBlock(NewPosition);
	}

}

Like this I get a link error. I tried adding the plugin module to the project dependencies, changing the slate private dependencies to public on the MyPlugin.Build.cs.
The only way I got this to work was to enable the slate dependencies on my project build.cs and moving the definition of UpdateMyTextBlock to the MyPlugin.h file.

I guess I can make a interface class to store actor calls and probe it with the plugin to make updates. But i wanted to understand why I can’t make it work in the original way.

Thanks in advance for any help or clues!

I’ve had similar problems in the past. The solution for me was to use the MYMODULE_API macro. These macros seem to mark certain classes (and I believe functions aswell) for DLL export.

In your case, you may need something like:

class MYPLUGIN_API FMyPluginModule : public IModuleInterface
{
...
public:
	void UpdateMyTextBlock(FString MyNewContent);

	static inline FMyPluginModule& Get() { return FModuleManager::LoadModuleChecked <FMyPluginModule>("MyPlugin"); };

private:
	TSharedPtr<STextBlock> MyTextBlock;
...
}

Here is the very limited documentation on these macros Module API Specifiers

Here is an Unreal Answers forum thread discussing them: What does the macro ProjectName_API do?

Hope this helps!

1 Like

It really helped!
And it worked!

These are actually very usefull specifiers, very nice to know.

Thank you very much :smiley:

1 Like