我不确定如何准确表达标题的意思,但我想在对象上每秒生成一种随机颜色。我还希望这种颜色与对象已有的旧颜色不相似。如果当前随机颜色与对象已有的颜色相同,则重新生成随机颜色。该对象仅是一个Text
组件。
这是我用来生成颜色的函数:
public Color genRandomColor()
{
float r, g, b;
r = UnityEngine.Random.Range(0f, 1f);
g = UnityEngine.Random.Range(0f, 1f);
b = UnityEngine.Random.Range(0f, 1f);
return new Color(r, g, b);
}
为了比较颜色是否相似,我将从此答案中的函数移植并用于C#。
public double ColourDistance(Color32 c1, Color32 c2)
{
double rmean = (c1.r + c2.r) / 2;
int r = c1.r - c2.r;
int g = c1.g - c2.g;
int b = c1.b - c2.b;
double weightR = 2 + rmean / 256;
double weightG = 4.0;
double weightB = 2 + (255 - rmean) / 256;
return Math.Sqrt(weightR * r * r + weightG * g * g + weightB * b * b);
}
我将随机颜色生成器放在while循环中的协程函数内,以使其一遍又一遍地运行,直到生成的颜色不相似。我使用“yield return null;”每次生成随机颜色时等待一帧,以确保不会冻结程序。
const float threshold = 400f;
bool keepRunning = true;
while (keepRunning)
{
Text text = obj.GetComponent<Text>();
//Generate new color but make sure it's not similar to the old one
Color randColor = genRandomColor();
while ((ColourDistance(text.color, randColor) <= threshold))
{
Debug.Log("Color not original. Generating a new Color next frame");
randColor = genRandomColor();
yield return null;
}
text.color = randColor;
yield return new WaitForSeconds(1f);
}
所有东西看起来都运转正常,只有一个小问题。
问题是有时需要1到3秒钟才能重新生成与旧颜色不相似的颜色。我删除了yield return null;
以防止它在每帧等待,现在似乎可以工作,但我冒着整个游戏冻结的风险,因为现在我正在使用随机函数控制while
循环。已经注意到了微小的停顿,这不好。
有没有更好的方法来生成一个与对象新颜色不相似的随机颜色,而不会冻结游戏或等待几秒钟?