Invalid enum from c++ code

I wrote a code that finds a random value by weight, but returns invalid . Only the first value returns normally
Enum was created in blueprint

void UFLRandomNumberGenerator::GetRandomWeightedEntryFromMap(const TArray<UProperty*>& KeyArray, const TArray<int32>& WeightArray, UProperty*& Key)
{
    Key = nullptr;

    if (KeyArray.Num() == 0 || WeightArray.Num() == 0 || KeyArray.Num() != WeightArray.Num())
    {
        if (GEngine)
            GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("Invalid input arrays."));
        return;
    }

    int32 TotalWeight = 0;
    for (const auto& Weight : WeightArray)
    {
        TotalWeight += Weight;
    }

    float RandomValue = FMath::RandRange(0, TotalWeight);;
    if (GEngine)
        GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("RandomValue Start: %f, TotalWeight: %d"), RandomValue, TotalWeight));

    for (int32 i = 0; i < WeightArray.Num(); ++i)
    {
        if (RandomValue <= WeightArray[i])
        {
            Key = KeyArray[i];
            if (GEngine)
                GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Choose Weight: %d"), WeightArray[i]));
            return;
        }
        RandomValue -= WeightArray[i];
        if (GEngine)
            GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("RandomValue: %f, Weight: %d"), RandomValue, WeightArray[i]));
    }
    if (Key == nullptr && WeightArray.Num() > 0)
    {
        Key = KeyArray.Last();
    }
}

image
Rarity is Key, Amount is Value
image

What’s keeping the Array of UProperty alive after the function returns? You’re returning one of the elements, so the array (or more importantly the original container of the UProperty pointers) must stay alive after the function returns.

I would suggest creating local variables in your BP for your arrays and see if that fixes it (then you’ll know it’s a lifetime issue)… OR

Could try using TObjectPtr<UProperty> &Key as the last argument for returning the value to keep it alive (not sure if this would work with BP)… OR

Why not just write a static function with the proper types? Making the enum in C++ is trivial. Then you don’t need to deal with UProperty pointers.

1 Like