Spawning pseudo-random BP objects from an array

I’ve checked a lot of threads but can’t find anything that addresses exactly what I want to do.

I want to create a spawn node which has a pseudo-random chance of spawning 1 of several different types of object.

I’m currently using a multigate which doesn’t let me change the chance that something will spawn. So is there a way of setting it so that it has 3 objects. and one object has a 60% chance to spawn and the other 2 have 20% each Also I wanted to create an array of each type of object e.g sword, armour, food, material. so that it would first randomize the type of object it would spawn then choose which object of that type.

e.g: I want it to decide whether to spawn a plant, sword or armour.

if it chooses a plant then I want it to choose from an array of plants. which includes mushrooms, tree or algae.

…does that make sense…

Well you have random integer and float nodes:

And you also have stream version of those nodes which let you control seeding

https://docs.unrealengine.com/latest/INT/Engine/Blueprints/UserGuide/RandomStreams/

From those you can apply randomness in many way, for starters you can randomize index of array and get random item for it (in random in node obviously you would plug size of array-1 in to max pin)

There switch node which let you control exec flow by variables and there also quite ot documented select node which let you direct specific varable depending on input varbale

It a lot more default to apply odds, you would need to do some math. Common practice in programing is to have random float between 0 and 1 and then apply math to it for needs of your application needs, for example you multiply it to 10 and it will be float between 0-10.

You could use data tables to achieve this. Data Tables will allow you to use a CSV file that can be loaded to memory during game play and iterated. While iterating the data table you can use the “Weight” CSV column to determine the “weight” or likelihood of the current row being selected.

The nice thing about this is being able to separate this type of configuration (which is normally tweaked for game balancing) from your code so in the future you only have to change a CSV file instead of code. This can reduce the amount of regression bugs.

Read more about data tables here Data Driven Gameplay Elements in Unreal Engine | Unreal Engine 5.1 Documentation

Please note, I didn’t actual run this code/blueprints so you may have to iron out kinks. It will get you moving in the right direction.

Step #1 - Create CSV Data Table

Create a CSV file that looks like this (note the header name of the first column should be a blank string, each row thereafter requires a unique value for the first column). UE4 engine uses this column as an “ID” to reference this row.

Also note the BlueprintGeneratedClass’PATH_TO_CLASS’ is critical. When the Data Table is loaded from the CSV into the DataTable object, each DataTable row will be loaded into our Structure we create during the next step. This Structure will contain a “ActorClass” variable that is actually of type “Actor” class so we can use this value for the Spawn Actor From Class node.

Step #2 - Create Data Table and Data Table Row Structure

Create a Structure that represents each row of your data table (CSV column names and Structure variable names must match as well as CSV column value types and Structure variable value types).

Create a new DataTable and select your newly created Structure as the row Structure. Select your CSV file as your Data Table source.

Here’s what your Data Table and Structure would look like.

Step #3 - Load the Data Table

Create a GameState replicated variable of type Array (an array of our Data Table row structure).

Load the Data Table into our new GameState replicated variable. This should be a performance improvement so we don’t have to reload the data table over and over.

NOTE: I cropped out the class name, but this loading is in my GameState::BeginPlay event so it’s only run during GameState’s BeginPlay (hopefully once during map load). You shouldn’t alter this array structure after the data table is loaded.

Step #4 - Provide a Public Method on the GameState to get a random row

This method can either return an instance to a newly spawned Actor, or you can return the SObjectType structure or the Actor class name. You choose.

(Ran out of available photo upload slots so you have to view the last image on Imgur)


Random Probability reference: https://forums.unrealengine.com/showthread.php?75982-Weighted-random-number&p=329872&viewfull=1#post329872

I’m using the first answer for the sake of simplicity. But I’ve made a note on how to do both because both of these answers are amazing and useful.