How to get a random element of an array with probability in Unreal Engine

May, 8 2021— #advanced

We'll be using C++ for this tutorial, but it can be easily adapted for Blueprints.

Let's imagine we have a FExampleStructure structure, which contains any properties and Probability field:

USTRUCT(BlueprintType, Category = "Sample Category")
struct FExampleStructure
{
	GENERATED_BODY()

	UPROPERTY(BlueprintReadWrite, Category = "Sample Category")
	TSubclassOf<AActor> ObjectSample;

	UPROPERTY(BlueprintReadWrite, Category = "Sample Category", meta = (ClampMin = "0.0", ClampMax = "1.0", UIMin = "0.0", UIMax = "1.0"))
	float Probability;
};

This structure will be used as TArray<FExampleStructure>. Depending on this property, a certain element of the array is more likely to be selected than others, and vice versa.

You can think of any algorithm, but one of the most intuitive is the following. First, you need to generate a random number between 0 and 1, which will determine the selected item. You need to go through the entire array and determine if the random number is greater than the decrement values of the current iterated element. If more, then the algorithm has successfully found a random element.

The algorithm looks like this:

	// Here we already have initialized ExampleArray, which is TArray<FExampleStructure>
	float ProbabilitySubtraction = 1; // How much to reduce the probability of each iteration
	const float RandomNum = FMath::FRandRange(0.0f, 1.0f); // A random float from 0 to 1

	for (int32 ExactObjectIndex = 0; ExactObjectIndex < ExampleArray.Num(); ExactObjectIndex++) // Loop through all of the objects
	{
		ProbabilitySubtraction = ProbabilitySubtraction - ExampleArray[ExactObjectIndex].Probability; // Subtract the chance

		if (RandomNum >= ProbabilitySubtraction) // Check if the random number is bigger or equal than the subtraction, if it is then that is your item
		{
			// Do stuff with your selected object (ExampleArray[ExactObjectIndex].ObjectSample)

			break; // You need to break the for loop here, or else you'll get the rest of the items as the right one
		}
	}
By Georgy Treshchev

Unreal Engine Developer. Contact for any questions. Telegram chat, e-mail, Github.