How to get my gamemode in a C++ function library?

Hi! I have a blueprint function library with some common functions and I want to write the same in C++. I know for function libraries in C++ is important to mark the functions STATIC.

in my BLUEPRINT function library I have a very simple function that gets the gamemode, casts it and sends my gamemode casted like this:

note get gamemode has a node ‘world context object’ because I am using this get mode from a function library.

What is the way to write the same in a C++ library?
I want something like this:

.h :

	UFUNCTION(BlueprintCallable,BlueprintPure)
	static AmyGamemodeCPP* myGamemode();

.cpp:

AmyGamemodeCPP* UMyBlueprintFunctionLibrary::myGamemode()
{
	return Cast<AmyGamemodeCPP>(UGameplayStatics::GetGameMode(this));
}

I cant put ‘this’ as context.
any help?

Because this is not a UWorld, but your function library. Use GetWorld() instead of this.

Alternatively, instead of UGameplayStatics::GetGameMode(GetWorld()); you can just use GetWorld()->GetAuthGameMode(); and not include GameplayStatics.h

:frowning:

same

Aah, yes, I remember, GetWorld() is unavailable in function library like that…

Try #include "Engine/World.h" to the library first; if it doesn’t work, modify the function:

.h:

UFUNCTION(BlueprintCallable,BlueprintPure)
static AmyGamemodeCPP* myGamemode(UWorld* InWorld);

.cpp:

AmyGamemodeCPP* UMyBlueprintFunctionLibrary::myGamemode(UWorld* InWorld)
{
	return Cast<AmyGamemodeCPP>(InWorld->GetAuthGameMode());
}

And when you call this function by actors, use UMyBlueprintFunctionLibrary::myGamemode(GetWorld());

P.S. I remember trying to create this function in a function library, but I ended up just using something like
AmyGamemodeCPP* GMRef = Cast<AmyGamemodeCPP>(GetWorld()->GetAuthGameMode());
directly in actors. It’s not like you need to do that often, probably once on BeginPlay() and that’s it.

Thanks but in the blueprints is a bit different.

gives this:

image

a pure clean function

and the code you suggest (thanks again!) gives this:

image

still need to plug/select something

That’s because blueprints basically have access to every library at any point, so it can gets World automatically in GetGameMode. GameplayStatics includes a lot of libraries itself. In c++ it’s a bit different.

If you run in game you can use the GEngine global pointer (GEngine->GetWorld())
If you run in editor you can use the GEditor global pointer to editor engine (GEditor->GetEditorWorldContext().World())

the last need #include “Editor.h” and UnrealEd as module depency.

2 Likes

oh ok…I use my own gamemodes and playercontrollers A LOT . mostly gamemode for general game mechanics and as a communication tool in between different actors. Thats why I use to implemente miGamemode and miPlayer in a blueprint library function… it saves me a couple nodes each time I need it.

some times as you said its just in the beginplay of actors and instead of

getgamemode—>cast_to_mygamemode—>Promote_to_gamemode_variable

I do: miGamemode—>Promote_to variable or migamemode–>get/use something

Yes, this compiles fine:
return Cast(GEngine->GetWorld()->GetAuthGameMode());

Thanks, @matrem84 , I always forget about GEngine for some reason =\

AmyGamemodeCPP* UMyBlueprintFunctionLibrary::myGamemode()
{
	return Cast<AmyGamemodeCPP>(GEditor->GetEditorWorldContext().World());
}

this gives me some errors. I included “Editor.h” and “UnrealEd.h”

  unresolved external symbol "__declspec(dllimport) public: struct FWorldContext & __cdecl UEditorEngine::GetEditorWorldContext(bool)" (__imp_?GetEditorWorldContext@UEditorEngine@@QEAAAEAUFWorldContext@@_N@Z) referenced in function "public: static class AmyGamemodeCPP * __cdecl UMyBlueprintFunctionLibrary::myGamemode(void)" (?myGamemode@UMyBlueprintFunctionLibrary@@SAPEAVAmyGamemodeCPP@@XZ)
  unresolved external symbol "__declspec(dllimport) class UEditorEngine * GEditor" (__imp_?GEditor@@3PEAVUEditorEngine@@EA) referenced in function "public: static class AmyGamemodeCPP * __cdecl UMyBlueprintFunctionLibrary::myGamemode(void)" (?myGamemode@UMyBlueprintFunctionLibrary@@SAPEAVAmyGamemodeCPP@@XZ)
  2 unresolved externals
  Microsoft.MakeFile.targets(45, 5): [MSB3073] The command ""C:\Program Files\Epic Games\UE_4.26\Engine\Build\BatchFiles\Build.bat" BlockardsEditor Win64 Development -Project="F:\00 UE\Blockards\Blockards.uproject" -WaitMutex -FromMsBuild" exited with code 6.

and an extra question (lol) you said if you use in the game or in editor…can’t use same in both? how do I do? what is in the editor will be in the game somehow :slight_smile:

Did you #include "myGamemodeCPP.h" though?

I replicated this error if I don’t include the GameMode to which I’m trying to cast. I guess it’s the same in your case.

yes I did

h:

#pragma once
#include "CoreMinimal.h"
#include "myGamemodeCPP.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyBlueprintFunctionLibrary.generated.h"

UCLASS()
class BLOCKARDS_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

public:
	
	UFUNCTION(BlueprintCallable,BlueprintPure)
	static AmyGamemodeCPP* myGamemode();
};

cpp:

#include "MyBlueprintFunctionLibrary.h"
#include "Editor.h"
#include "UnrealEd.h"

AmyGamemodeCPP* UMyBlueprintFunctionLibrary::myGamemode()
{
	return Cast<AmyGamemodeCPP>(GEditor->GetEditorWorldContext().World());
}

I’m sorry, please disregard my previous message. The thing is, GetEditorWorldContext() not only requires #include "Editor.h", but also an "UnrealEd" module

Open %YourProjectName%.build.cs, and in PublicDependencyModuleNames add "UnrealEd". Then it should work.

You can conditionnaly compile thanks to :
#if WITH_EDITOR

#endif
It’s often used in UE source code to do things only in editor.

ps:
The passing a context to your static function way, is another solution that could perhaps be better for you. At least you have the choice :slight_smile:

2 Likes

image

closer!

Now I have the node exactly as I want but I get Null (I think is not passing the casting).

I swear the gamemode I am using is child of myGamemodeCPP

image

It’s not the world you have to cast :wink:

2 Likes

you’re right :slight_smile:

anyway cast keeps failing…I get:

"Accessed None trying to read property CallFunc_myGamemode_ReturnValue".

using:

AmyGamemodeCPP* UMyBlueprintFunctionLibrary::myGamemode()
{
	return Cast<AmyGamemodeCPP> (   GEditor->GetEditorWorldContext().World()->GetAuthGameMode());
}

or

AmyGamemodeCPP* UMyBlueprintFunctionLibrary::myGamemode()
{
	return Cast<AmyGamemodeCPP> (   UGameplayStatics::GetGameMode(GEditor->GetEditorWorldContext().World()));
}

How did you declare your AmyGamemodeCPP class?

#pragma once
#include "CoreMinimal.h"
#include "myGamemodeCPP.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyBlueprintFunctionLibrary.generated.h"

UCLASS()
class BLOCKARDS_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

public:
	
	UFUNCTION(BlueprintCallable,BlueprintPure)
	static AmyGamemodeCPP* myGamemode();
};

in the game I am using a blueprint gamemode (miGamemode) that is child of myGamemodeCPP

image