Creating a Blueprint Function Library is a Fun Way to Get Started with C++ Inside UE5

Getting started with C++ inside of Unreal Engine 5 can be a challenging and daunting task sometimes. However, I found creating a Blueprint Function Library is a fun way to start programming inside the engine.

Creating a new C++ BlueprintFunctionLibrary class inside Unreal Engine 5
Creating a new BlueprintFunctionLibrary

Updated: Oct. 30, 2024

Software Versions: Unreal Engine 5.4.4 | Rider 2024.2.7

Project Name: MyProject

Writing C++ in Unreal Engine 5 can be an incredible and exciting experience that can really open up a lot options inside the engine. However, getting into UE5 C++ can be daunting at times. Even when I have to get back into it I get scared sometimes 😨. Jumping into the code base and then immediately trying to create custom classes can be difficult. Depending on experience, the learning curve can be steep and you'll typically crash the engine many times while programming and testing new features. Although C++ is great, we also don't want to abandon the wonderful world of Blueprints that are extremely powerful throughout Unreal projects. Balancing Blueprints and C++ in Unreal has always been a ballet where each project is different in how they handle their strengths and weaknesses. In my experience I found that a Blueprint Function Library is a great way to start writing C++ inside UE5. They're fun, simple, and pure and greatly help in reducing some of the complexity that can arise while working in Blueprints.

Epic has a great write up on Blueprint Function Libraries here. Overall they're a set of stateless functions that can be used throughout the project. A Blueprint Function Library can be a lot of fun to use because you get to continue using Blueprints while also writing some awesome C++ code. In the past I found that a Blueprint Function Library was a great place to reduce the large parts of my massive spaghetti interweaved Blueprint scripts that I somehow managed to shove all in one place.

The example in this post is using the BP_Door Blueprint from the Content Examples and moving some of the logic into a Blueprint Function Library. This isn't the most practical example, the Blueprint is already great as it is, but I thought it be a fun example of how to extract some logic and write some C++.

I really like the BP_Door Blueprint, it's simple and works very well. You can find the BP_Door Blueprint in the Epic's Content Examples Project inside the Blueprints_Advanced level. I Migrated the asset to my project so I could work on it without affecting the example and then I created a new C++ Blueprint Function Library.

Inside Unreal Engine 5 right clicking the BP_Door blueprint with the Asset Actions and Migrate options highlighted
Migrating BP_Door from the Content Examples to my project
Creating a new C++ BlueprintFunctionLibrary class inside Unreal Engine 5
Creating a new C++ BlueprintFunctionLibrary class
Naming a new C++ BlueprintFunctionLibrary class inside of Unreal Engine 5
Simply named the new class MyBlueprintFunctionLibrary

For this quick exercise I wanted to extract some Blueprint logic away from BP_Door and add it to a C++ function. Inside the Trigger Box's BeginOverlap function I decided to rewrite some of the portions before and after the SwingDoor timeline. Again, not the most practical example, the Blueprint is already very clean, but this technique can definitely help out when the Blueprint logic gets very large and becomes tough to manage through visual scripting.

Unreal Engine 5 Blueprints for BP_Door from the Content Examples with highlighted sections
BP_Door Blueprint code. The sections before and after the SwingDoor timeline will be rewritten in C++

Once inside the IDE the code was't too difficult to rewrite. I wrote two functions that accept a few arguments that just replicate what the Blueprint was already doing. I included the KismetMathLibrary in the .cpp file to utilize it's RLerp function.

MyBlueprintFunctionLibrary.h

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyBlueprintFunctionLibrary.generated.h"

/**
 * 
 */
UCLASS()
class MYPROJECT_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

	// Static functions do not require a target and they will appear in Blueprints when Context Sensitive is checked
	UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Door Functions")
	static bool IsActorInFront(FVector ActorLocation, FVector OtherActorLocation, FRotator OtherActorRotation);

	UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Door Functions")
	static FRotator GetRotateValue(FRotator ActorRotation, float Alpha, bool OpenDirection, float RotateDegrees);
};

MyBlueprintFunctionLibrary.cpp

#include "MyBlueprintFunctionLibrary.h"
#include "Kismet/KismetMathLibrary.h"

bool UMyBlueprintFunctionLibrary::IsActorInFront(FVector ActorLocation, FVector OtherActorLocation, FRotator OtherActorRotation)
{
	FVector NewLocation = ActorLocation - OtherActorLocation;
	FVector UnrotatedVector = OtherActorRotation.UnrotateVector(NewLocation);
	
	return UnrotatedVector.X > 0 ? true : false;
}

FRotator UMyBlueprintFunctionLibrary::GetRotateValue(FRotator ActorRotation, float Alpha, bool OpenDirection, float RotateDegrees)
{
	float Direction = OpenDirection ? RotateDegrees : -RotateDegrees;
	FRotator NewRotation = FRotator(0.0f, Direction, 0.0f);
	FRotator FinalRotation = UKismetMathLibrary::RLerp(ActorRotation, NewRotation, Alpha, true);

	return FinalRotation;
}

After writing these two functions and recompiling I was able to add them to the BP_Door Blueprint. Next, I added a new float variable to BP_Door called RotateDegrees and defaulted the value to 90 that will be passed to the GetRotateValue function. These two library functions are pretty Door Blueprint specific, so they're not very re-usable, but for this simple exercise it's fine, we're just having fun.

UE5 BP_Door Blueprint utilizing two functions made inside a Blueprint Function Library
BP_Door after adding the two functions from the Blueprint Function Library

Replacing some of the Blueprint logic with the library functions make this Blueprint a little bit cleaner, but not by much. Again, not the most practical example, but this can help out when Blueprints get overwhelming with multiple if statements or vector conversions.

UE5 scene with BP_Door opened in front of the default ThirdPerson character
BP_Door inside of the scene using the new library functions

Conclusion

When I have complex Blueprints that are getting difficult to manage I find it fun to create static pure functions that do most the heavy lifting. I don't have to recreate the entire Actor class or re-parent the Blueprint, I get to use all the wonderful features of Blueprints while also having fun with C++. Furthermore, Blueprint Function Libraries are great at getting your feet wet in writing C++ inside UE5 because they don't require as much overhead or learning as other UE5 classes. You can simply just start writing C++ and begin getting use to UE5's C++ coding style and just start having fun without having to worry too much about drastically changing your project's structure.

Loading...