超时随机更改相机背景颜色
Change camera background color randomly overtime
我正在尝试在随机选取的两种颜色之间平滑地更改相机的背景颜色。 I've already achieved that, but then I started noticing that there is a flash whenever a new color is picked.我已经在此 link 上上传了有关该问题的视频。这是我目前正在使用的脚本:
public Color color1;
public Color color2;
float time;
float time2;
float transition;
int firstColor = 0;
void Update()
{
if (firstColor == 0)
{
color1 = Random.ColorHSV(Random.value, Random.value);
color2 = Random.ColorHSV(Random.value, Random.value);
firstColor = 1;
}
Camera.main.backgroundColor = Color.Lerp(color2, color1, transition);
time += Time.deltaTime;
time2 += Time.deltaTime;
transition = time2 / 5;
if (time > 5)
{
color2 = color1;
color1 = Random.ColorHSV(Random.value, Random.value);
time = 0;
time2 = 0;
}
}
非常感谢任何帮助。
我的猜测是错误在这里:
if (time > 5)
{
color2 = color1;
color1 = Random.ColorHSV(Random.value, Random.value);
time = 0;
time2 = 0;
}
如果您注意到,播放时间开始后约 5 秒闪烁,播放时间约 3 秒开始,绿色闪烁发生在播放时间约 7-8 秒。
我认为 color2 = color1;
行有问题。
基本上,您在前 5 秒内通过在 2 种颜色之间插值来平滑颜色,然后随机强制颜色。这会产生闪烁效果。
您需要使用协程来完成此操作。然后,您可以轻松地对当前过渡结束后何时更改新颜色进行编程。任何你必须加班的事情,你都应该考虑使用协程。它消除了对大量布尔变量和混乱的需求。
您可以在没有布尔变量的协程函数中等待,但不能在像 Update
函数这样的空函数中等待。您已经在使用 Time.deltaTime
和 Lerp
函数,因此您知道自己在做什么。这是执行此操作的正确方法:
//2 seconds within each transition/Can change from the Editor
public float transitionTimeInSec = 2f;
private bool changingColor = false;
private Color color1;
private Color color2;
void Start()
{
StartCoroutine(beginToChangeColor());
}
IEnumerator beginToChangeColor()
{
Camera cam = Camera.main;
color1 = Random.ColorHSV(Random.value, Random.value);
color2 = Random.ColorHSV(Random.value, Random.value);
while (true)
{
//Lerp Color and wait here until that's done
yield return lerpColor(cam, color1, color2, transitionTimeInSec);
//Generate new color
color1 = cam.backgroundColor;
color2 = Random.ColorHSV(Random.value, Random.value);
}
}
IEnumerator lerpColor(Camera targetCamera, Color fromColor, Color toColor, float duration)
{
if (changingColor)
{
yield break;
}
changingColor = true;
float counter = 0;
while (counter < duration)
{
counter += Time.deltaTime;
float colorTime = counter / duration;
Debug.Log(colorTime);
//Change color
targetCamera.backgroundColor = Color.Lerp(fromColor, toColor, counter / duration);
//Wait for a frame
yield return null;
}
changingColor = false;
}
尽管@Programmer 的回答是当场的并且它工作得很好,但我设法在上面的代码中找到了问题。
发生的事情是,在我将第 29 行中的 color1 设置为新的随机颜色后,transition 的值为 1 (夹紧)。
因此,在第 25 行的下一帧中设置 transition 之前,第 21 行执行,并且由于 transition = 1,新的 color1 被返回,因此新 color1[=29= 的 "flashing" ].所以我干脆把transition重新设置为0后重新设置time 和 time2.
用于闪烁
使用这个
if (time > 5)
{
color2 = color1;
color1 = Random.ColorHSV(Random.value, Random.value);
time = 0;
time2 = 0;
}
else
{
time += Time.deltaTime;
time2 += Time.deltaTime;
transition = time2 / 5;
background.color = Color.Lerp(color2, color1, transition);
}
我正在尝试在随机选取的两种颜色之间平滑地更改相机的背景颜色。 I've already achieved that, but then I started noticing that there is a flash whenever a new color is picked.我已经在此 link 上上传了有关该问题的视频。这是我目前正在使用的脚本:
public Color color1;
public Color color2;
float time;
float time2;
float transition;
int firstColor = 0;
void Update()
{
if (firstColor == 0)
{
color1 = Random.ColorHSV(Random.value, Random.value);
color2 = Random.ColorHSV(Random.value, Random.value);
firstColor = 1;
}
Camera.main.backgroundColor = Color.Lerp(color2, color1, transition);
time += Time.deltaTime;
time2 += Time.deltaTime;
transition = time2 / 5;
if (time > 5)
{
color2 = color1;
color1 = Random.ColorHSV(Random.value, Random.value);
time = 0;
time2 = 0;
}
}
非常感谢任何帮助。
我的猜测是错误在这里:
if (time > 5)
{
color2 = color1;
color1 = Random.ColorHSV(Random.value, Random.value);
time = 0;
time2 = 0;
}
如果您注意到,播放时间开始后约 5 秒闪烁,播放时间约 3 秒开始,绿色闪烁发生在播放时间约 7-8 秒。
我认为 color2 = color1;
行有问题。
基本上,您在前 5 秒内通过在 2 种颜色之间插值来平滑颜色,然后随机强制颜色。这会产生闪烁效果。
您需要使用协程来完成此操作。然后,您可以轻松地对当前过渡结束后何时更改新颜色进行编程。任何你必须加班的事情,你都应该考虑使用协程。它消除了对大量布尔变量和混乱的需求。
您可以在没有布尔变量的协程函数中等待,但不能在像 Update
函数这样的空函数中等待。您已经在使用 Time.deltaTime
和 Lerp
函数,因此您知道自己在做什么。这是执行此操作的正确方法:
//2 seconds within each transition/Can change from the Editor
public float transitionTimeInSec = 2f;
private bool changingColor = false;
private Color color1;
private Color color2;
void Start()
{
StartCoroutine(beginToChangeColor());
}
IEnumerator beginToChangeColor()
{
Camera cam = Camera.main;
color1 = Random.ColorHSV(Random.value, Random.value);
color2 = Random.ColorHSV(Random.value, Random.value);
while (true)
{
//Lerp Color and wait here until that's done
yield return lerpColor(cam, color1, color2, transitionTimeInSec);
//Generate new color
color1 = cam.backgroundColor;
color2 = Random.ColorHSV(Random.value, Random.value);
}
}
IEnumerator lerpColor(Camera targetCamera, Color fromColor, Color toColor, float duration)
{
if (changingColor)
{
yield break;
}
changingColor = true;
float counter = 0;
while (counter < duration)
{
counter += Time.deltaTime;
float colorTime = counter / duration;
Debug.Log(colorTime);
//Change color
targetCamera.backgroundColor = Color.Lerp(fromColor, toColor, counter / duration);
//Wait for a frame
yield return null;
}
changingColor = false;
}
尽管@Programmer 的回答是当场的并且它工作得很好,但我设法在上面的代码中找到了问题。
发生的事情是,在我将第 29 行中的 color1 设置为新的随机颜色后,transition 的值为 1 (夹紧)。 因此,在第 25 行的下一帧中设置 transition 之前,第 21 行执行,并且由于 transition = 1,新的 color1 被返回,因此新 color1[=29= 的 "flashing" ].所以我干脆把transition重新设置为0后重新设置time 和 time2.
用于闪烁 使用这个
if (time > 5)
{
color2 = color1;
color1 = Random.ColorHSV(Random.value, Random.value);
time = 0;
time2 = 0;
}
else
{
time += Time.deltaTime;
time2 += Time.deltaTime;
transition = time2 / 5;
background.color = Color.Lerp(color2, color1, transition);
}