I wrote a script for you that has a single function, GiveMeRandomColorCombinations(), which gives you an array of custom color structures of any length you want, with each combination containing between 3 - 5 colors, which you specify. Each combination structure contains five colors, color1/2/3/4/5. Only the first three are used if you ask for three per combination and only the first four are used if you ask for four per combination. Each color is a number 1 through 5: it’s up to you to decide what number is what color once you get the list of combination structures.
using UnityEngine;
using System.Collections;
//The consumer gets a list of these structures when they ask for color combinations.
public struct ColorCombination {
public int color1;
public int color2;
public int color3;
public int color4;
public int color5;
}
/*Attatch this script to whatever object need its information. When that object comes into existence, this script will automatically create
lists of every possible three, four and five color long combination, where every color can be one of five colors and repeats are allowed.*/
public class ColorCombinator : MonoBehaviour {
[SerializeField] private bool logExample = false;
//The lists of combinations
private int[] threeColorCombinations;
private int[] fourColorCombinations;
private int[] fiveColorCombinations;
//Build the lists of combinations automatically
void Start () {
//The indexes to keep track of where we are in each array of combinations while we fill them
int threeColorArrayIndex = 0;
int fourColorArrayIndex = 0;
int fiveColorArrayIndex = 0;
//The arrays of three, four and five color combinations using five colors, 1 through 5
threeColorCombinations = new int[125];
fourColorCombinations = new int[625];
fiveColorCombinations = new int[3125];
//The last combination we made, to be placed in the arrays
//This is here to prevent us from making thousands of local integers inside the for loops
int threeColorCombination;
int fourColorCombination;
int fiveColorCombination;
//For every possible combination, add it to the correct array
for(int color1 = 1; color1 <= 5; color1++){
for(int color2 = 1; color2 <= 5; color2++){
for(int color3 = 1; color3 <= 5; color3++){
threeColorCombination = color1 + (color2 * 10) + (color3 * 100);
threeColorCombinations[threeColorArrayIndex] = threeColorCombination;
threeColorArrayIndex++;
for(int color4 = 1; color4 <= 5; color4++){
fourColorCombination = color1 + (color2 * 10) + (color3 * 100) + (color4 * 100);
fourColorCombinations[fourColorArrayIndex] = fourColorCombination;
fourColorArrayIndex++;
for(int color5 = 1; color5 <= 5; color5++){
fiveColorCombination = color1 + (color2 * 10) + (color3 * 100) + (color4 * 1000) + (color5 * 10000);
fiveColorCombinations[fiveColorArrayIndex] = fiveColorCombination;
fiveColorArrayIndex++;
}
}
}
}
}
if(!logExample)
return;
//EXAMPLE OF USAGE. Stick this script on anything in your scene, run and examine the console.
//This is how you obtain a list. The first number is the amount of colors per combination and the second is how many you need.
ColorCombination[] tenThreeColorCombinations = GiveMeRandomColorCombinations(3, 10);
//The combinations are structures. .color1 to .color5 give you the colors in a combination structure. It's up to you
//to map each number to a meaningful color. In this example, 1 is red, 2 is blue, 3 is green, 4 is yellow and 5 is orange.
//"nocolor" is color 0. You'll only get a 0 if you try to access color4 or 5 on a three color combination or color5 on a four color combination.
string[] colors = {"nocolor", "red", "blue", "green", "yellow", "orange"};
//Using the numbers in the combination to get the color we want and print a string of them
//In example, a ColorCombination of 1 2 3 would print out "red blue green"
foreach(ColorCombination combo in tenThreeColorCombinations){
Debug.Log(colors[combo.color1] + " " + colors[combo.color2] + " " + colors[combo.color3]);
}
}
//Returns an array of "number" integers out of "choices."
//All choices are unique elements, unless "choices" contains duplicates.
private int[] PickRandomUniqueIntegers(int[] choices, int number){
//A safety check. Prevents us from going out of bounds if the array of choices is too small and such.
if(choices.Length == 0 || number > choices.Length || number < 1){
Debug.Log("The operation could not be completed.");
return new int[0];
}
//The array to return once we are done picking integers
int[] picked = new int[number];
//For as many numbers are requested, grab a random number, place it in the new array.
//We swap the chosen number with the last one in the array and shorten our random range
//by one each iteration so that no element can be chosen twice.
for(int i = 1; i <= number; i++){
int index = Random.Range(0, choices.Length - i);
int choice = choices[index];
choices[index] = choices[choices.Length - i];
choices[choices.Length - i] = choice;
picked[i - 1] = choice;
}
return picked;
}
//Returns an array of ColorCombination structures "numberOfCombinationsRequested" long.
//Each combination is made up of "numberOfColorsPerCombination" colors.
public ColorCombination[] GiveMeRandomColorCombinations(int numberOfColorsPerCombination, int numberOfCombinationsRequested){
//The raw integer form of our combinations at the start
int[] rawCombinations;
//The structured combinations we return at the end
ColorCombination[] completeCombinations = new ColorCombination[numberOfCombinationsRequested];
//We only handle combinations 3/4/5 colors long
if(numberOfColorsPerCombination < 3 || numberOfColorsPerCombination > 5){
Debug.Log ("We only can give out combinations three, four or five colors long.");
return new ColorCombination[0];
}
//Get a list of unique combinations from one of the arrays
if(numberOfCombinationsRequested == 3)
rawCombinations = PickRandomUniqueIntegers(threeColorCombinations, numberOfCombinationsRequested);
else if (numberOfCombinationsRequested == 4)
rawCombinations = PickRandomUniqueIntegers(fourColorCombinations, numberOfCombinationsRequested);
else
rawCombinations = PickRandomUniqueIntegers(fiveColorCombinations, numberOfCombinationsRequested);
//the index in the completeCombinations array that we are working on
int completeCombinationsIndex = 0;
//for every raw integer combination we had obtained, store it in the complete combination array correctly
foreach(int raw in rawCombinations){
//we can't alter the variable of a foreach loop, so copy it
int combination = raw;
//We use modulo arithmetic to obtain the colors in the order we put them in the integer
//We take advantage of division + truncation to "slide" the integer to the next position
completeCombinations[completeCombinationsIndex].color1 = combination % 10;
combination /= 10;
completeCombinations[completeCombinationsIndex].color2 = combination % 10;
combination /= 10;
completeCombinations[completeCombinationsIndex].color3 = combination % 10;
combination /= 10;
completeCombinations[completeCombinationsIndex].color4 = combination % 10;
combination /= 10;
completeCombinations[completeCombinationsIndex].color5 = combination % 10;
//Move to the next combination
completeCombinationsIndex++;
}
//Return the completed list of combinations
return completeCombinations;
}
}
In your project, wherever you store scripts, make a new C# script and name it ColorCombinator. Copy and paste the above code over the whole thing. Next, drag the script to whatever object needs the color combinations to add it as a component. When the object gets created, this script will automatically create and store three arrays containing all 3875 color combinations, three, four and five colors long, where a color is signified by a number from 1 to 5. Here’s an example of usage, which can be put in the Start() function of any other script on the same object the ColorCombinator is attached to.
//First, we get a reference to the ColorCombinator.
ColorCombinator combinator = GetComponent<ColorCombinator>();
//This is how you obtain a list. The first number is the amount of colors per combination and the second is how many combinations you need.
ColorCombination[] tenThreeColorCombinations = combinator.GiveMeRandomColorCombinations(3, 10);
//The combinations are structures. color1 to color5 give you the colors in a combination structure. It's up to you
//to map each number to a meaningful color. In this example, 1 is red, 2 is blue, 3 is green, 4 is yellow and 5 is orange.
//"nocolor" is color 0. You'll only get a 0 if you try to access color4 or 5 on a three color combination or color5 on a four color combination.
string[] colors = {"nocolor", "red", "blue", "green", "yellow", "orange"};
//Using the numbers in the combination to get the color we want and print a string of them
//In example, a ColorCombination of 1 2 3 would print out "red blue green"
foreach(ColorCombination combo in tenThreeColorCombinations){
Debug.Log(colors[combo.color1] + " " + colors[combo.color2] + " " + colors[combo.color3]);
}
This exact example is in the ColorCombinator itself already. If you want to demo it as quickly as possible, stick it on any game object in your scene and check the “Logs Example” box on the script in the inspector, then hit run. It’ll log out ten random three color combinations.
This script has to rebuild all its lists every time you destroy it and create another one, so it’s a good idea to stick it on some object you know will persist through multiple levels/etcetera. It does take a little over 7KB of memory to keep the colors cached, but it’s very quick if you need a large list of possible combinations. The only alternative I could think of would be to randomly generate them, but this would be very slow if you wanted, say, a list of a hundred unique three color combinations. If you ask for a list of combinations, the list will not contain duplicates at very little computational cost. So, if the list has the combination 1 1 1, which we’ll say means red red red, you won’t see it again in the array. Obviously, you could get it again in another call to the function since that would give you a new array/list.
The maximum amount of combinations you can get in one array is 125 for three color combinations, 625 for four color combinations and 3125 for five combinations. This is because there’s only that many possible combinations, period, so asking for that many actually gives you an array of every single possible permutation.
This was an interesting script to write. I hope it helps you. 