Every Possible Combination from several Lists of GameObjects

So this seems straightforward but I;m having trouble wrapping my head around the code. I assume it would involve permutations and hash sets, but I just can’t crack it.

SO: I have an NPC randomization system, which uses 15 Male variations, and 15 Female variations.
On top of that, I have maybe 200-300 possible clothing pieces that can randomly be selected at runtime, and then combined into a single Skinned Mesh.
However, generating LODs at runtime is giving me major lag spikes for each NPC, so Ii’ve decided i need to randomize and then Generate LODs for them at in the Editor, and then load the random “LOD Meshes” into the skinned renderers instead at runtime.

Right now i can manually “randomize” them with a custom Inspector function, and that works fine, but i don’t want to just do that over and over and over, possibly hundreds of times (15 x 15 x 200+ etc)
So my question is, is there a way I could possibly run a function that takes all my Lists of “Shirts” “Pants” “Boots” etc as well as “MaleBodies” and “FemaleBodies” of GameObjects, and gets EVERY POSSIBLE combination, and adds them to a new List or HashSet that I can then go down the line and iterate through?

Basically I just want to make sure I generate LODs for every single possible NPC combination, and I don’t wanna sit there and spend like 2 days hitting “Randomize” and “GenerateLOD”, only to accidentally get some of the same combinations without noticing.
I’d like to fill a new List with each combination, using some kind of serialized class like this:

        public List<RandomCombination> NewRandomNPCVariations;
 
        [System.Serializable]
        public class RandomCombination
        {
              public GameObject BodyMesh;
              public GameObject HeadMesh;
 
              public GameObject ShirtMesh;
              public GameObject PantsMesh;
              public GameObject BootsMesh;
 
        }

and then I can just write a custom inspector button to Cycle through them and generate LODs.
Anyone have any idea how i might go about this?

I manually fill the Lists in the script currently, so I have a List already of “AllShirtObjects”, “AllPantsObjects”, and “AllBodyObjects” etc. I’d like to get every combination of THOSE lists, and send them to the above “RandomCombination” class variables, and then fill the NEW List with all those RandomCombinations, etc.

Isn’t this just a bunch of nested foreach loops?

foreach (var shirt in allShirts)
{
   foreach (var pants in allPants)
   {
      ...
      NewRandomNPCVariations.Add(new RandomCombination(shirt, pants, ...));
   }
}

Am I missing something here?

1 Like

I’m not sure, this seems too simple?
Basically I have 15 Bodies.
I have maybe 20 Shirts, 30 Pants, 15 Boots, 25 Hats.

I need to get every POSSIBLE combination of Bodies, Shirts, Pants, Boots, Hats, and add them to a “newRandomCombination,” and fill a new List with each possible combo with no repeat combos.

Wouldn’t a nested foreach just add them all?

basically each new RandomCombination class in the List would need to have its own Body, Shirt, Pants, Boots, etc. Without repeating the combinations from the other RandomCombinations.

Just because it’s simple doesn’t mean it’s wrong, it’s the correct solution.

If you’re having trouble wrapping your head around it, try downscaling the problem. Imagine you have 3 shirts, 3 pants, and 3 shoes. Just walk through the code using nested for loops on paper (or just code it), and you can see how it works.

Wow, Thanks guys this worked so easily! I cant believe I spent so long trying to overcomplicate this. Now I have to grapple with having thousands of possible combinations of things…

Well, as others have already said, it’s just nested for loops. However are you sure you even have the slighest idea how many combinations you get with 15 Bodies, 20 Shirts, 30 Pants, 15 Boots and 25 Hats? It’s 3375000 combinations. That’s over 3 million. I still don’t quite get why you actually want to do that. What is your actual goal in the end? Generate gigabytes of mesh data? Why would you need all combinations at once?

Note there’s a difference between combinations and permutations. Permutations are mainly about the order of items. Since you have distict categories there’s no order to them So the combination body #5, shirt #2, pants #7, boots #1 and hat #12 is the same combination, even when you list them in a different permutation like hat #12, shirt #2, boots #1, pants #7 and body #5. You can not use a hat as pants or a shirt as a body. Also you always have exactly one item from each category. Even when you add the possibility to not equip a certain category, that’s just one more item in that category that says: “none”.

1 Like

Well the issue is i have a completely NPC Randomized system that randomly selected Clothing pieces, and combines them at runtime. This lets me randomize all levels, stats, names, clothing, bodies, gender, skin texture (atlased) and everything you can imagine for my NPCs. The only PROBLEM is, I can’t generate LODs for each one without a major lag spike. And I have 50-100 NPCs on screen at once.

So I realized I’d need to randomize and generate LODs beforehand, and then just randomly get a ScriptableObject asset that contains the LODs and randomize THOSE instead of each clothing piece.

And I actually have way more clothing pieces than that, I’ve got about 50 each for Head, Shirts, Pants, Boots, Shoulders, etc.

I ended up writing a custom script using coutourines to let me just click one button and Randomize Meshes > Combine them > Generate LODs and save new mesh assets > Create new Scriptable Object > Reset the whole system without deleting the mesh LODS > repeat.