Returning a TArray from function

So i have this function

UFUNCTION(BlueprintCallable, Category = "CombatStatus")
		TArray<UUnitCombatModule*> FindAttackable(UUnitCombatModule* attacker);

that is defined like that:

TArray<UUnitCombatModule*> UCombatBlueprintWidget::FindAttackable(UUnitCombatModule* attacker)
{
	TArray<UUnitCombatModule*>* attackableUnits = new TArray<UUnitCombatModule*>();
	return *(attackableUnits);
}

So for now there is no functionality in it i just try to get it to create and return a pointer to Tarray. Now i have a few problems with it.

  1. It can’t return a pointer because TArray can’t be returned as exposed pointer apparently.
  2. I can’t return it like i just wrote because there are multiple compile errors.

So how it can be done?

There are many ways on doing it: using shared pointers, using references, using out arguments instead of a return value (then you can return true/false depending on the result, this is just add a simple branch later). The best way is to check for examples in the engines git repo. This way you will see in which use cases Epic uses which procedure.

Most compilers support RVO: Copy elision - Wikipedia

So this simple approach should work for you and thanks to RVO it’s fast too:

TArray<UUnitCombatModule*> attackableUnits;
// Filling the array somehow
return attackableUnits;

it is also short and keeps your interface clean.

But you may get problems if your array is not temporary, because the pointers inside the TArray may transform into an invalid state between frames (if an Actor gets destroyed for example). If you need this TArray over multiple frames you should consider Omnicypher’s solution and annotate the TArray attribute with an UProperty annotation.

Have a nice Day

DarthB

If anyone wonders how to do it in BP functions, just drag the variable to return node and it will automatically create an output pin. also works for other types (not only arrays)

if you don’t have a variable, just create one to make the output and delete afterwards, or use makeArray node for that :]

230975-screenshot-2.png

Could you give an Example that is up-to-date (UE5 Today) since I am kinda new to C++ and I am still not getting it to work

One possibility is to pass array as reference instead of returning it.
This leaves allocation concerns to the caller, and avoids unnecessary copies.
The downside is it makes calling the function on C++ side a bit more annoying as you have to declare the array to pass it to the function.

//.h
UFUNCTION(BlueprintCallable, Category = "CombatStatus")
void FindAttackable(UUnitCombatModule* attacker, TArray<UUnitCombatModule*>& Result);

//.cpp
void UCombatBlueprintWidget::FindAttackable(UUnitCombatModule* attacker, TArray<UUnitCombatModule*>& Result)
{
    Result.Add(NULL);    //dummy
    //return;    // no need to return anything
}

//usage
TArray<UUnitCombatModule*> attackables;
unitCombatModule->FindAttackable(attacker, attackables);
for (auto& attackable : attackables)
{
    UE_LOG(LogTemp, Log, TEXT("attackable: %s"), *AActor::GetDebugName(attackable));
}
1 Like