Using item from an array only once

Hi,

I’m trying to implement function that picks random names from an array and assign it to characters.

All names are fed from external txt file and stored in array. Array is part of a player blueprint. Then I’ve got other actors calling this array and picking random names, while every time name is picked, it is also removed from array, to prevent duplicate use of the name.


This is how blueprint inside BPRandomCharacter looks like. At event start, names are assigned to each character, then on key press it will execute whole code again and randomize characters. It will return current name back to the array first, then pick random name again and remove it from array. Everthing works as it is supposed to, characters picking random names and none of the names are used twice. Issue is that sometimes some random characters are assigned no name at all. Array itself is updating as it is supposed to, so it will not probably be an issue inside player blueprint. Also PrintString says nothing when this issue occurs. While it prints name and array index properly on the screen for characters with name, it shows no name or array index for affected characters. I’ve spent all day trying to figure out why it happens, but I’m out of ideas.

A few things.

I would do this on the level bp, since the actors aren’t something directly related to the player.

Why the Button press? Should it not just go through the array and spawn one NPC per name? Mostly curious here. The issue could be the button press.

Why not a recursive function? Recursion is really your friend. Especially when working back a call stack. Thats exactly what you have here. It may not be memory pointers, but you have data in an array that needs to be used and discarded just the same.
Thus, a small recursive function that pops the array at the end, and repeats if array length is > 0 will parse the whole array.
To do it right.
this will also solve the issue you have with the array using an invalid index because the miced call stavk process popped the array before it was actually used - if thats (what i supect) is happening.

Keep the function entierly self contained. Feed it an array only. Let it set the full name/data. Do not store local variables, just get the data right from the array.

also, getting the random index should really be length -1 which is probably your real issue?
An array starts at 0, so 0B1 is common and is the Droid you are looking for to boot.

Whats the point of addunique? Seems redundant/useless and a potential error if the variable is still set to an old name.

TLDR
you are off by one on your random integer max.

“Why the Button press? Should it not just go through the array and spawn one NPC per name? Mostly curious here. The issue could be the button press.”

It is purely just for testing purpose and will be removed from final version.

“also, getting the random index should really be length -1 which is probably your real issue?
An array starts at 0, so 0B1 is common and is the Droid you are looking for to boot.”

I’ve been using array length -1 as a max value for random integer in range all the time, but had been advised by other user here on forums to use RandomInteger instead. However, both methods works fine for me and none of them returning values out of array length.

I’ve managed to fix it, it was actually caused by one node not being connected to the “name” input on CharacterInfo structure inside another function that modifies same structure file. Now it works without any issues.

Using Length without a -1 in random integer will cause out of range exceptions.
in an array with 4 entries the index will be 0 to 3.
random integer with a max of 4 has the potential of returning 4, which is out of range.

I agree with other stuff I’ve seen here about out of range indexes, but the main thing would be to put this somewhere central. Level BP might not be best, as it’s not easy to access, but game instance would be probably better.

Also, ‘black box’ it, so all the character can do it ask for a name, and doesn’t know how it works.

Inside the game instance you can have to code the read the next name, and the player calls it from there.

Not in this case, this node does -1 internally. It’s fine as is.

Also, @**Artyom_87, **consider looking into the Set Members in Struct node when dealing with structs, the unnecessary wiring can be easily avoided:

Expose what you need to modify, the rest remains unchanged.

@Everynone Thanks for advice, will have a look at it. Rewiring every single input every time some function uses struct is real pain… :rolleyes: