The inability to sort an array by any property of a class in blueprint is extremely problematic. This thread has shown up multiple times in my search for a generic solution. I’m here to share my own solution to this problem.
TLDR, this solution will require you to have a cpp project (you can easily convert from blueprint only to a cpp project). You dont need to understand the logic if you’re not a programmer, just copy and paste it into your project and use only the blueprint portion.
The idea is that you’re using cpp underneath to do the sorting, but the way that mechanism is exposed in blueprint allows you to sort by any property. So what is the secret sauce? We just sidecar our actor and its value in a tuple, and let cpp do the sorting base on value. Now our actors are sorted accordingly.
Here is a screenshot of what it looks like in blueprint:
And here is the cpp code that you need.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include <tuple>
#include <vector>
#include <algorithm>
#include "TupleSorter.generated.h"
UCLASS(BlueprintType, Blueprintable)
class TRDECKBUILDER_API USortableTuple : public UObject
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite, EditInstanceOnly, Category="Default", meta=(ExposeOnSpawn="true"))
TObjectPtr<AActor> Actor;
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Default", meta=(ExposeOnSpawn="true"))
int32 Value;
};
UCLASS()
class TRDECKBUILDER_API UTupleSorter : public UObject
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "Tuple Sorting")
static void Sort(UPARAM(ref) TArray<USortableTuple*>& TupleList) {
TupleList.Sort([](const USortableTuple& A, const USortableTuple& B){
return A.Value < B.Value;
});
}
};
Additional notes, you can use this to sort basically most things. Just pass in a blueprint actor and some integer value that represent the order/priority of that actor. If you need to sort by floats, you can easily just convert those into an int (x100 or however many decimals you want to shift).
If you need to sort by strings, you’ll need to do a bit more work but can simply follow this same schematic. Hope this helps!
