C
C#2y ago
Ramune

❔ Select next/previous item from a list when function called

So I have a list of colors, I want to check if the current color is equal to an array item, find the position of that item in the array, then set it to the next item in the array. Basically a rainbow loop, so it returns red on first run, green on second run, blue on third run, red on fourth run
public Color GetRandomColor()
{
Color current = light.color;

List<Color> colors = new List<Color>
{
Color.red,
Color.green,
Color.blue,
};

return newColor;
}
public Color GetRandomColor()
{
Color current = light.color;

List<Color> colors = new List<Color>
{
Color.red,
Color.green,
Color.blue,
};

return newColor;
}
newColor is not yet defined but will be defined as the resulting next color in the array
7 Replies
Ramune
Ramune2y ago
I just can't really figure out how to go about it, don't know much C#, and I should probably have gone to sleep many hours ago
TheRanger
TheRanger2y ago
you can do
int i = 0;
public Color GetRandomColor()
{
Color current = light.color;

List<Color> colors = new List<Color>
{
Color.red,
Color.green,
Color.blue,
};

i = (i + 1) % 3

return colors[i];
}
int i = 0;
public Color GetRandomColor()
{
Color current = light.color;

List<Color> colors = new List<Color>
{
Color.red,
Color.green,
Color.blue,
};

i = (i + 1) % 3

return colors[i];
}
% is the modulo operator what do u mean by check if current color is equal to an array item
Ramune
Ramune2y ago
I'm not even quite sure myself tbh (needa sleep)
Ramune
Ramune2y ago
But works as intended Thanks!
TheRanger
TheRanger2y ago
u can use colors.FindIndex(c => c == current); to get the index of the current color in the list
public Color GetRandomColor()
{
Color current = light.color;

List<Color> colors = new List<Color>
{
Color.red,
Color.green,
Color.blue,
};
int i = colors.FindIndex(c => c == current); // gets the index of the current color in the list
i = (i + 1) % colors.Count;

return colors[i];
}
public Color GetRandomColor()
{
Color current = light.color;

List<Color> colors = new List<Color>
{
Color.red,
Color.green,
Color.blue,
};
int i = colors.FindIndex(c => c == current); // gets the index of the current color in the list
i = (i + 1) % colors.Count;

return colors[i];
}
rotor_
rotor_2y ago
Hi @RamuneNeptune I'd just like to propose an alternate approach:
private IEnumerable<Color> GetColorLoop(List<Color> colors) {
while (true) {
foreach (var color in colors) {
yield return color;
}
}
}

private IEnumerator<Color> colorLoop = GetColorLoop(
new List<Color>{ Color.red, Color.green, Color.blue });

public Color GetNextColor() {
var loop = colorLoop.GetEnumerator();
var oldColor = loop.Current;
loop.MoveNext()
return oldColor;
}
private IEnumerable<Color> GetColorLoop(List<Color> colors) {
while (true) {
foreach (var color in colors) {
yield return color;
}
}
}

private IEnumerator<Color> colorLoop = GetColorLoop(
new List<Color>{ Color.red, Color.green, Color.blue });

public Color GetNextColor() {
var loop = colorLoop.GetEnumerator();
var oldColor = loop.Current;
loop.MoveNext()
return oldColor;
}
This code creates an infinite loop of your chosen colors and then just gets the next one every time you ask. It should be more efficient as you don't have to redeclare the list of colours every time you call the function, nor do you have to find where you were each time. It would also let you repeat colors if you wished, which your existing solution cannot. On the other hand if you think that's too weird a solution try this on for size
private List<Color> AllColors = new List<Color>{ Color.red, Color.green, Color.blue };

private int position = 0;

private Color GetNextColor() {
position = (position + 1 == AllColors.Length)
? 0
: position + 1;
return AllColors[position];
}
private List<Color> AllColors = new List<Color>{ Color.red, Color.green, Color.blue };

private int position = 0;

private Color GetNextColor() {
position = (position + 1 == AllColors.Length)
? 0
: position + 1;
return AllColors[position];
}
This is also efficient and easy to maintain
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.