C++/Functions

Usage of Asynchronous and Threaded Functions in Unreal C++.
Takes a while to get used to and can be rather frustrating without any prior knowledge.

The two important things for Logging are:

A good ressource (not including all edge cases) can be found HERE.

General: Casting

This is an example on how to get a Scene Component and than cast to it (cause we know it's a camera) to get its information.
In this case: we are a Scene Component attached to another Scene Component, which we know is a camera.

USceneComponent* ParentComponent = this->GetAttachParent();

const UCameraComponent* ParentCamera = Cast<UCameraComponent>(ParentComponent);

Additionally, the regular C++ style casting works as well. Here an example to go from a float to an int.

float FloatValue = 42.f;

int32 IntegerValue = static_cast<int32>(FloatValue);

Getter: Get World Context

Sometimes a static function requires a UWorld reference, like for example printing text to the screen, line-traces etc.

UWorld* World = GEngine->GameViewport->GetWorld();

Getter: Get Components by Class (from Actor)

If you need to get Components from an Actor, use the following:

TArray<USceneComponents*> Components;

this->GetComponents(Components);

The GetComponents() function will automatically get the correct Class and filter by it.

Getter: Get Actor of Class (from World)

If in the World you need to find an Actor by Class, use the following ():

AActor* CustomActor = UGameplayStatics::GetActorOfClass(

WorldContextObject, // UWorld*

ACustomActor::StaticClass()

);


ACustomActor* CustomActorReference = Cast<ACustomActor>(CustomActor);

Getter: Get Game Time

How to get the GameTime in seconds since BeginPlay:

double CurrentGameTime = GEngine->GameViewport->GetWorld()->GetTimeSeconds(); // get the game time

UFunction: Run External Executable

To start an executable within the Project/Game folder:

const FString RelativePath = FPaths::GameSourceDir() + "MyExecutable.exe";

const bool FileExists = FPaths::FileExists(RelativePath);

FString FullPath = IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*RelativePath);

const TCHAR* ProcPath = *RelativePath;


if (FileExists)

{

auto CommProc = FPlatformProcess::CreateProc

(

(ProcPath),

TEXT(""),

true,

false,

false,

nullptr,

0,

nullptr,

nullptr

);

}

To quit the executable (may not work, not yet sure why):

TerminateProc(CommProc);

UFunction - Specifier: Pass By Reference

If you want to edit values of variables directly in C++ using references from Blueprint, use the following as an example:

UFunction(BlueprintCallable)
static void EditInt(UPARAM(ref) int& EditorInt);

 Now if you change the variable in C++, it'll also change the variable in Blueprint, because it's using a reference as input.
The important part here is:

UPARAM(ref)

before the Variable Reference.
If you use it without that line, it'll be shown as an output-line in Blueprint.

UFunction - Specifier: Deprecated

If you want to declare one of your UFunctions as deprecated, use the following metadata specifiers:

UFunction(

meta = (DeprecatedFunction, DeprecationMessage = "Insert reason why it's deprecated and what to do."))

Info: BlueprintCallable, Tooltip etc. have been left out in this example.  Please do not forget about them. ;-)

UFunction - Specifier: Return Value Name

If you want the return value within a function to be named, instead of it just being displayed as return value:

UFunction(

meta = (ReturnDisplayName = "Delay"))

Now your return value will be displayed as "Delay" for the output pin. Important: really only does work for functions with an actual return value, that are not void!

UFunction - Exec Pins: Bool

There is a pretty nifty way to add a true and false exec pin to any UFUNCTION.
In this example we put in a pointer to an AActor and check, if it is valid and does not point to a nullptr.
Now to add the exec pins:

//.h


UFUNCTION(BlueprintCallable, meta = (ExpandBoolAsExecs = "IsValid"))

static void IsActorValid(AActor* Actor, bool& IsValid);

Now for the cpp file:

//.cpp


void AYourClass::IsActorValid(AActor* Actor, bool& IsValid)

{

if (Actor != nullptr)

IsValid = true;

else IsValid = false;

}

As soon as you define the IsValid, the execution pin in Blueprint will be triggered. This way you don't need to use a Branch or any other comparison, since it's already in here.

UFunction - Event: Custom Event

Example:

// .h

UFUNCTION((BlueprintImplementableEvent, BlueprintCallable, Category = "MyCategory")
void DoStuff();

This type of event/function is basically the same, as if you were to add a Custom Event via Blueprint.
To use it within Blueprint, simply right click and search for it. Voila!
But why use this instead? Well, in C++ it can easier be handled, categorized and called via C++ as well.

UFunction - Event: Custom Event with Variable(s)

Example, if you want a Custom event to use a Variable.

UFUNCTION((BlueprintImplementableEvent, BlueprintCallable, Category = "MyCategory")
void DoStuff(int32);

UFunction - Event: Custom Event with FString

Compared to other Variables, FString won't work out of the box. Long story short: to make it work, use the following:

UFUNCTION((BlueprintImplementableEvent, BlueprintCallable, Category = "MyCategory")
void DoStuff(const FString &MyString);

UFunction - Event: Call in Editor

Example:

// .h


FLinearColor RandomColor; // Define Random Color

UFUNCTION(BlueprintNativeEvent, BlueprintCallable, CallInEditor, Category = "MyCategory")
void  RandomColor();

// .cpp


void AMyClass::RandomColor_Implementation()

{

RandomColor = FLinearColor(

UKismetMathLibrary::RandomFloat(),

UKismetMathLibrary::RandomFloat(),

UKismetMathLibrary::RandomFloat(),

1.f);

}

This type of event/function will be displayed as a Button in the Details Panel of the Actor.
On click, it will do something: here create a random color (not used in this example).

Important: BlueprintNativeEvent will require it to be defined in C++, as of what to do when pressed (hence the .cpp file above).
If however you want it to be a Custom Event that can be used in Blueprint Graphs, use "BlueprintImplementableEvent" instead of "BlueprintNativeEvent". It then also won't require a definition in the .cpp file.

UFunction - Override Event: ConstructionScript (Overriding Members)

virtual void OnConstruction(const FTransform& Transform) override;

UFunction - Override Event: EndPlay (Overriding Members)

virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

UFunction - Override Event: Tip for Jetbrains Rider

In your .h file, right click anywhere: "Show Context Actions"/"Generate Code..."/"Overriding Members".
With "Ctrl + F" search for what you need (or scroll down), select box and click "OK".

UFunction - template <typename>

What templates are in C++ is a bit too much to cover here, but as an example on how to use typename templates, here's a good example.

Lets say, you created a fixed size TArray and want to call a function, that returns its length, that should then be printed to the screen:

TArray<TObjectPtr<AActor>, TFixedAllocator<16>> MyFixedArray {nullptr, nullptr, nullptr};

GEngine->AddOnScreenDebugMessage(

   -1, 10.f, FColor::Red, FString(

      "Length: " + FString::FromInt(GetArrayLength(MyFixedArray))));

In the .h file, create the following function definition:

template <typename T>

static int32 GetArrayLength(TArray<TObjectPtr<AActor>, T> &Array);

In the .cpp file, create the function itself:

template <typename T>

int32 UCPPSC_Systems_Projectiles::GetArrayLength(TArray<TObjectPtr<AActor>, T> &Array)

{

   return Array.Num();

}

Note: There is not .cpp required, a FORCEINLINE will also work, so that the function only lives within the header file.

Latent Action - Delay/Timer (Lambda)

Example:

float LoopDaly = 3.f;
bool LoopTimer = false;

FTimerHandle TimerHandle;
GetWorld()->GetTimerManager().SetTimer(TimerHandle, [&]()
{
UE_LOG(LogTemp, Warning, TEXT("This text will appear 3 seconds after execution and won't loop"));
}, LoopDaly, LoopTimer);

Here we use the Timer with a Lambda Function to display something after a certain amount of time.
A very good blog describes it in more detail: GeorgysBlog

Latent Action - Delay/Tick

Example for setting a Value for a Variable. The function itself is:

void GetAndSetActorTransform()

{

   LastKnownVehicleLocation = this->GetActorTransform(); // LastKnownVehicleLocation is an FTransform stored somewhere else

}


Now to call the function after one Tick:

GetWorld()->GetTimerManager().SetTimerForNextTick(this, &ThisClass::GetAndSetActorTransform);