How to Make Global Functions and Structs?

Hi there,

So I’ve gone from zero to 60 in the last week in terms of understanding how to create UFunctions, UClasses, UProperties, etc. I’m also new to C++, but pretty comfortable with some other languages so programming is nothing new.

However, What I really am trying to grasp right now, I haven’t been able to find any good tutorials for.

I want to create some “BluePrint Function Libraries” so that I can have some global Blueprint Functions available for controlling motion and other stuff. However, I need to be able to handle some pretty complex unique coordinate system transformations - so I need to use C++ UFunctions to handle those.

Is there a way I can either make Global UFunctions or Global Structs that can appear in any Blueprint?

OR Conversely, can I make a Custom Class derived from a “Blueprint Function Library” to accomplish the same thing? Here’s what I tried that DID NOT work:

Creating New Class Based on Function Library

Name and Public/Private folders

Then here is the most simple example I could try (compiles fine):

Header:
#pragma once

#include "Kismet/BlueprintFunctionLibrary.h"
#include "avMyTestFunctions.generated.h"

USTRUCT(BlueprintType)
struct FTestStruct
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "TestStruct")
		float Avar;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "TestStruct")
		float Bvar;
};

UCLASS()
class AV_API UavMyTestFunctions : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
	public:
		UFUNCTION(BlueprintCallable, Category = "MyTestFunctions")
			float avFtestFct(float Xpos, float Speed, float timeVar);
	
	
};

Body:

#include "AV.h"
#include "avMyTestFunctions.h"

float UavMyTestFunctions::avFtestFct(float Xpos, float Speed, float timeVar)
{
	float Xnew = Xpos + Speed*timeVar;
	
	return Xnew;
}

This should in theory allow me to make BP Function Library from this new derived class… But when I reopen the project and look for it, nothing comes up:

There’s also no hint of “avMyTestFunction” anywhere in the project, nor the Struct I defined.

Anyway, I either want to know why this isn’t working - or some alternative for creating global “Uthings.”

Cheers

You just have to create the class of your custom BP function library and then you will be able to use those functions in your BPs, there is no need to create a new instance.

To create global structs I would encourage you to just create a simple header file in your public code, then include that header in your main project header to you will be able to have access to the structs from every where. This way you have visibility in both native code and BluePrints.

Native (C++) Blueprint Function Library


The next code is basically the same as in Ramas tutorial. We just add the header file (.h) and the implementation (.cpp). The next think is simple, compile your project.

//-----------------------------
// MyBlueprintFunctionLibrary.h
//-----------------------------

#pragma once

#include "MyBlueprintFunctionLibrary.generated.h"

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

public:
    UMyBlueprintFunctionLibrary(const FObjectInitializer& ObjectInitializer);

    /**
     * Saves text to filename of your choosing, make sure include whichever file extension
     * you want in the filename, ex: SelfNotes.txt . Make sure to include the entire file
     * path in the save directory, ex: C:\MyGameDir\BPSavedTextFiles
     *
     * Note: From Rama
     */
    UFUNCTION(BlueprintCallable, Category = "GS Function Library")
    static bool SaveStringToFile(FString SaveDirectory, FString FileName, FString SaveText, bool AllowOverWriting = false);
};


//-------------------------------
// MyBlueprintFunctionLibrary.cpp
//-------------------------------

#include "MyProject.h"
#include "MyBlueprintFunctionLibrary.h"

UMyBlueprintFunctionLibrary::UMyBlueprintFunctionLibrary(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
}


bool UMyBlueprintFunctionLibrary::SaveStringToFile(FString SaveDirectory, FString FileName, FString SaveText, bool AllowOverWriting)
{
    //Dir Exists?
    if (!IFileManager::Get().DirectoryExists(*SaveDirectory))
    {
        //create directory if it not exist
        IFileManager::Get().MakeDirectory(*SaveDirectory);

        //still could not make directory?
        if (!IFileManager::Get().DirectoryExists(*SaveDirectory))
        {
            //Could not make the specified directory
            return false;
        }
    }

    //get complete file path
    SaveDirectory += "\\";
    SaveDirectory += FileName;

    //No over-writing?
    if (!AllowOverWriting)
    {
        //Check if file exists already
        if (IFileManager::Get().GetFileAgeSeconds(*SaveDirectory) > 0)
        {
            //no overwriting
            return false;
        }
    }

    return FFileHelper::SaveStringToFile(SaveText, *SaveDirectory);
}

Now we have compiled the code (it hopefully went all ok :D). The next step is to simply launch the editor and you are ready to use your functions in your Blueprints. This might seam strange but you do not have to create a child of UMyBlueprintFunctionLibrary in fact the engine wont let you to do so. The next screenshot is directly after I compiled the engine, just right click in any Blueprint and search for your new functions.

44163-bplib.png

Notice the ‘Save String to File’ function?

Native structs to be used in Blueprints


When you setup a C++ project Unreal will create a main header file for your project (normally it’s just the name of the project itself). You will have something like this:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Engine.h"

What I normally do for structs that I consider global and so I will use them a lot in my code and in Blueprints (if it’s only for Blueprints you can add them nearly everywhere but the sake of clearness we will discuss the nice way here) is to add them in a separate header. The next code outlines the use of the types header and the projects main header file.

//
// MyProject.h
//

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Engine.h"

// Your types that you in runtime (non-editor)
#include "MyTypes.h"

// Your types that needs editor stuff (done exactly the same way as MyTypes.h)
#if WITH_EDITOR
#include "MyEditorTypes.h"
#endif

//
// MyTypes.h
//

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

USTRUCT(BlueprintType)
struct MYPROJECT_API FNameItem
{
    GENERATED_USTRUCT_BODY()

    /** Name of the item */
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Item)
    FName ItemName;

#if CPP
    FNameItem() :
        ItemName(NAME_None)
    {}
#endif
};

FNameItem is a struct you can use nearly from every where in your code and in Blueprint.

Thanks, can you provide any example for creating the class? Does that mean something like an inititalizer like this:

AClassName::AClassName(const FObjectInitializer &ObjectInitializer) : Super(ObjectInitializer) { stuff }

Thanks for pointer on global structs!

Sure, I’ll post a full example of both a BP function library and a globally visible struct. Give until tomorrow ^^

Looking forward to it - I 'm still not sure what I’m doing wrong / different from this though:

Your are trying to create a child Blueprint from your native function library, you do not have to do that, it will just work our of the box.

I think to be a UCLASS it needs to be a child of something,

Would just UObject work?

class AV_API UavKep2Cart : public UObject

Or is there way to make UClass which isn’t child?

An UCLASS is just a class, you add the UCLASS macro in front ouf any UOBJECT to that UHT (the header tool) generates the extra code needed so that your class is conformed with the engine.

I’m adding some sample code and screenshots so you see the whole process.

Do you still need assistance on the issue?

I tried the example above on ver 4.12.5 but it does not want to compile…
Is there some changes or was this not the example you were going to post?

Hi Moss! :slight_smile:

I tried to create a global struct in C++ like your example, but the compiler can’t complete:

Error C3646 ‘FName’: unknown override specifier

I created the same header file that you and include to main header. Also I tried to close UnrealEd and delete all folders except “Content” and “Source” and tries to compile again, but the same problem :S

I upload a image to show the distribution of files in the solution. I think they are good.

Can you help me please? Thanks!

TerrorJam.h
#pragma once

#include "Engine.h"
#include "GlobalStructs.h"

You might need to include the the following headers before defining your struct:

#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"

so you where missing that one? You may want to start with the Getting Starter guide programmers.

With these includes the problem continues. However, I found the solution:

UEHeaderTool generates the “X.generated.h” files before to compile the source files, so, just adding these include, where X is the name of the header, the problem is solved.

In my case, between line 1 and line 2 I added:
#include “GlobalStructs.generated.h”

Sorry for my english… maybe I don’t express well. The “one” missing was the autogenerated X.generated.h file that UEHeaderTool generates.

the header ObjectMacros.h it’s not necessary, since UE brings it for us. About CoreMinimal I haven’t idea.

I read a time ago the Getting Started, but yes, is not a bad idea read it again :slight_smile: