Download

Random array without 'twins'

Need help with some very basic Array manipulation.
Lets say I have 5 unique Static Meshes a,b,c,d,e defined as an array in the editor.
And I need to populate a 2nd array or arraylist with 1000 of these picked randomly such that there are never two consecutively identical
ie
Instead of
[b,c,a,a, c,e,d,d, etc]

I need
[b,c,a,c,a,d, etc ]

What is the logic to do this in BP and which specific nodes should I be using?

You could use a really big hammer for this:

1 Like

Why don’t you just check a this moment, if the entry you’re adding is different from the last one in the array ? If so, add the random picked one, if it is the same, do the loop again, until the array is 999 index

@eco_bach2 And now you have commented script!

Ahah, I have a simpliest version in mind. Giving my shot when i’m home

It’s not very efficient, I’ll agree on that. I mean, this can be done in many ways, this is brute force. We’re reinventing the wheel here :slight_smile:

I know. But I just wanna see if i’m able to do it my way (learning purpose). You’re way more skilled than me that’s sure

1 Like

Here’s another approach.

No idea how efficient this will be. Haven’t tested it.

This approach adds Temp Array manipulation, but negates additional looping.
#! All variables used are Function Local other than 5Array.

Long Loops are bad for FPS, they are Tick/Frame bound.

This is my one :

Edit : does not seem to work in fact :confused: working on it

1 Like

Just keep hammering until it does! While loops are scary.

Welp:

This can be done in 9 nodes with an inverted look-behind condition while loop nested in a for loop to “Keep picking an index if I am trying a duplicate”. Abusing the fact that a node value can fall out of a while loop’s scope in blueprints is nice, too, because that’s how we get the index out of the while loop directly.

image

Make sure this goes in BeginPlay:

And here are the Actor variables:

image

I suggest you to use a Niagara GPU mesh renderer instead for this many static meshes. But, what ever floats your boat, its what you asked for. Enjoy the spaghetti.

Just have the selectable range be from 1 to the last index, and have index 0 acts as a “last selected; don’t use” variable. On each loop, swap the selected item with index 0, then swap it back in on the next loop. This removes it from the selectable range so that it can’t be selected in the next loop, and on the next loop, the swap adds it back in.


Edit: simplified by using index 0 instead of the last index


Made a better one: It offsets the selected index by 1 if it is greater than or equal to the last selected index, in effect, removing the last selected index from the array. This one is better than the last one because it has less array operations and doesn’t modify the original array.

1 Like

Never thought of swap! Thanks for the improvements!

To OP:

Now that this question has been properly answered - This is a very resource intensive task. As stated, due to the amount of physics and collision calls doing it this way would generate to spawn copies, you run the risk of turning your game into a slideshow. You can resolve this in a few ways:

A. Keeping this many actors only in memory by a struct that holds onto their transforms and a pointer to the static mesh they implement with collision and physics turned off, and setting up cull distance to cull objects out at a distance, which will also as a caveat freeze them in time, and most likely require a complex state machine to work correctly.

B. Put the task into Chaos, Cascade, or Niagara’s (depending on Engine version) static mesh options, for things like crowds, mobs, flocks of birds, bullets, etc. and do the draw/physics calls that way on the GPU. Keep in mind this also hikes your game’s base system requirements, and doesn’t make it accessible on Mobile devices, because the player needs a decent graphics card and most likely a PC.

It is up to you to explore your optimization options in this regard, as well as weigh the pros and cons of each. This is one task where it most definitely pays to learn some optimization techniques, and the options that Unreal provides for that.