You can do this faster than a Hashset with a simple linear scan:
var randomObjects = new GameObject[waypointsCount];
for(i = 0; i < waypointsCount; i++) {
// Take only from the latter part of the list - ignore the first i items.
int take = Random.Range(i, Nodes.Length);
randomObjects[i] = Nodes[take];
// Swap our random choice to the beginning of the array,
// so we don't choose it again on subsequent iterations.
Nodes[take] = Nodes[i];
Nodes[i] = randomObjects[i];
}
This is effectively a Fisher-Yates shuffle (also called a Knuth shuffle) that terminates early.
Doing it this way has a couple of advantages:
we can build the output array in-place (even just using the same memory as the input
Nodesarray if we want to), without setting aside extra memory for the hash structure for membership tests.if we want 49 items from a list of 50, we finish in exactly 49 iterations, every time. The Hashset method will take on average 3-4 times longer in this scenario, because its probability of choosing a duplicate and retrying goes up the longer our output list gets in proportion to the input. To pick the last random item in this scenario, the Hashset would need to try 25 times on average, since the list only contains 2 valid non-duplicate choices out of 50. The linear scan guarantees that we pick each item in a single try while avoiding duplicates through the re-ordering trick.