Globals and blueprint function library

In this tutorial we are focusing two things. First we are going to check out the globals. How they work and how you can use them. Global functions and variables allows us to run functions or get/set variables without even creating a object from the class. This can be a huge time saver depending what are you trying to do! In second part we are going to see how to create a blueprint function library. Library allows us to create a functions that are instantly exposed in blueprint in way that you can access then in any blueprint at any given moment.


Globals

Go ahead and create a C++ class based on None. You can call that something like C_GlobalHelperClass. First, let’s create a variable that we can access any given time in other classes. Inside public lets create two variables. One is with keyword const and one is without.

// const variables cannot be changed, ever.
static const int32 MyStaticGlobalConstInt;
// Ths variable can be changed by other classes.
static FString MyStaticGlobalString;

Inside .cpp we set them. Remember to set them outside of the scope! Above constructor is good place.

const int32 C_GlobalHelperClass::MyStaticGlobalConstInt = 3;
FString C_GlobalHelperClass::MyStaticGlobalString = "SomeText";

Now, in any other class that  #includes C_GlobalHelperClass we can Get our int32 variable and we can Get/Set our FString variable. This can be done without ever creating a object from our class!

int32 NewInt = C_GlobalHelperClass::MyStaticGlobalConstInt;
C_GlobalHelperClass::MyStaticGlobalString = "NewString";

And that’s how you do it! Let’s make quick example of how to put this in good use. Instead of variables, we create a function. Our function will take FAssetData and returns AActor that user can later cast to something else. We need to include ”AssetRegistryModule” first to be able to use FAssetData

#include "AssetRegistryModule.h"
#include "ARFilter.h"// For filtering
#include "ModuleManager.h"

 

// Function takes FAssetData and reference of TSubclassOf<AActor>
static void AssetDataToActor(FAssetData data, TSubclassOf<AActor>& actor);

In our function declaration.

void C_GlobalHelperClass::AssetDataToActor(FAssetData data, TSubclassOf<AActor>& actor)
{
  auto GeneratedClassPathPtr = data.TagsAndValues.Find(TEXT("GeneratedClass"));
  const FString ClassObjectPath = FPackageName::ExportTextPathToObjectPath(*GeneratedClassPathPtr);
  actor = FStringClassReference(ClassObjectPath).TryLoadClass<AActor>();
}

Great! Now when we are handling the FAssetData and want to convert it to Blueprint classes we can actually use, we have a function that is always available! Next we are using the code we seen in Asset Registry tutorial.

So create a new class and add #includes.

#include "AssetRegistryModule.h"
#include "ARFilter.h"
#include "ModuleManager.h"

We create module and then scan our Blueprints path. When we get reference to our asset we are using our global function for converting purposes. To learn what all this means. Please check the link i provided about Asset Registry.

  FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
  TArray<FAssetData> AssetData;
  FARFilter Filter;
  TArray<FString> PathsToScan;
  PathsToScan.Add(TEXT("/Game/Blueprints/"));
  AssetRegistryModule.Get().ScanPathsSynchronous(PathsToScan);
  Filter.PackagePaths.Add("/Game/Blueprints");
  AssetRegistryModule.Get().GetAssets(Filter, AssetData);

  // When we have all the assets we want inside the FAssetData array we can loop them
  for (auto asset : AssetData)
  {
    TSubclassOf<AActor> MyActor; // Temp class
    // Magic happens here! Conversion is outsourced
    C_GlobalHelperClass::AssetDataToActor(asset, MyActor);
    // We print results.
    UE_LOG(LogTemp, Warning, TEXT("Assets received using Global Function: %s"), *MyActor->GetName());
  }

Another way to create a global variable is to create a variable outside of the scope and then use keyword extern in other classes to get reference to same variable. So inside some class we can example declare int32. We can set that above the constructor.

int32 SomeIntValue;

Now inside the constructor we can set value to it.

SomeIntValue = 500;

Now, no matter what class, we can get the same int32 using extern. Again, do this outside the scope.

extern int32 SomeIntValue;

And thats it! Nothing more is needed to do. You don’t need to do anything in header files. All code is in .CPP. extern check is done while compiling and that way your game knows about the variable when it is run. If you change the variable in one class, it will change within all the other classes as well.

And that’s it about globals! Have fun using them and adding reused code into global functions!


Blueprint function library

We start by creating a new C++ class based on BlueprintFunctionLibrary. Inside code we can create a function

UFUNCTION(BlueprintCallable)
  static void SomeBlueprintFunction(float InFloat, FString& Mystring, int32& Myint);

Declaration. We just type something, just to test it.

void UC_GlobalLibrary::SomeBlueprintFunction(float InFloat, FString & Mystring, int32 & Myint)
{
  Mystring = FString::SanitizeFloat(InFloat);
  Myint = Myint + InFloat;
}

When we compile our game and go to any blueprint. We can see our node. Note that references(&) are returns values. You can have as many return values as you like.

a1

If you want to pass values to function by reference you need to use UPARAM specifier. Lets build another function.

UFUNCTION(BlueprintCallable)
static void SomeOtherBlueprintFunction(UPARAM(ref) bool& RefInBool, UPARAM(DisplayName="NonRefInputTexture") UTexture2D* MyTexture);

When you declare this function and compile the project. You will see function in blueprints. Note that bool is different cause it is pass by reference and UTexture name is set in UPARAM!

a1

That’s it! Now you can create any kind of logic and use that in blueprints!

 

 

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *