不完全确定如何标记标题但我想在对象上每秒生成一个随机颜色。我也希望这种颜色与对象已有的旧颜色不相似。如果当前随机颜色与对象已有的颜色相同,则再次重新生成随机颜色。该对象只是一个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);
}
为了比较颜色是否相似,我移植并使用this中的函数回答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
循环。我已经注意到了很小的冻结,但这并不好。
在不冻结游戏或等待几秒钟的情况下,生成与对象的新颜色不相似的随机颜色的更好方法是什么?
答案 0 :(得分:3)
我会采取不同的方法:
示例:假设我们有C1 =(R1; G1; B1)=(0.71; 0.22; 0.83)
即使G2和B2与它们的前辈相同,当R2移位时,新颜色也会明显不同
更新代码
# set t1 to value 0 or 1, depending on the (x < 10) condition
slti $t1, $t0, 10 # t1 = 1 when x < 10 || 0 when 10 <= x
# now use the 1/0 value to adjust x by left-shifting it
sllv $t0, $t0, $t1 # shift left x by t1 bits (doing *= 2 or *= 1)
测试:
public static class RandomColorGenerator
{
public static Color GetNextPseudoRandomColor(Color current)
{
int keep = new System.Random().Next(0, 2);
float red = UnityEngine.Random.Range(0f, 1f);
float green = UnityEngine.Random.Range(0f, 1f);
float blue = UnityEngine.Random.Range(0f, 1f);
Color c = new Color(red, green, blue);
float fixedComp = c[keep] + 0.5f;
c[keep] = fixedComp - Mathf.Floor(fixedComp);
return c;
}
}
答案 1 :(得分:2)
这是另一个想法:
而不是生成RBG组件,而是生成HSV组合(并转换)。就人眼而言,色调的差异约为15度(在0-1等级上约为0.05)足以被认为是不同的颜色。这是唯一重要的价值。
例如,这里的图像是顶部带红色的图像(&#34; 0度&#34;)。沿着底部有4种颜色:沿着&#34; hue&#34; 7,15,30和60度。滑块。
7度差异可以看但看起来太近了。 15度转换绝对是一种不同的颜色(即使我将它和下一个同时称为#34;橙色&#34;它们至少不同的橙色)
您可以选择所需的任何阈值并生成新颜色,直到新颜色超过您的阈值(以度为单位)。对于值和饱和度,您几乎可以生成从0到1的任何值,因为即使值与前一颜色完全相同,最小强制色调差异也会导致颜色大不相同。
然后,converting from HSV to RGB非常简单。
我用两种不同的语言完成了这种事情,其中一种用于我特别希望生成两种或三种不同颜色的项目。同时还确保亮度足够高(即我不希望&#34;黑色&#34;可能),因此HSV是唯一明智的解决方案:我可以生成随机色调,设置值和饱和度朝向最大值(例如random range [0.8,1.0]
)。另一个项目是我将两个图像合并为一个纹理:我想保留第一个图像的相同色调和饱和度,但是根据第二个图像调整值。 / p>
您可能还想根据您的目标偏置饱和度和值数字,如果饱和度或值太低(低于0.5),色调将开始模糊并且太相似(颜色将全部变得混乱)。或者,您可以生成0到1之间的单个浮点数,并将饱和度设置为that number
,将值设置为one minus that number
。