我有一些结构,例如object-4 child object-在每个孩子中还有2个孩子。我想为每个子对象更改其颜色的alpha。
我创建了应该更改Alpha的IEnumarator,但是当我对其进行测试时,它仅更改为0.8,而不是0,并且我还想按时间更改它,例如平稳地更改2秒钟,但是它发生得很快
imageComponents = gameObject.GetComponentsInChildren<Image>();
textComponents = gameObject.GetComponentsInChildren<Text>();
IEnumerator HideAllBoosters(Transform _object)
{
foreach (Image image in imageComponents)
{
Color _color = image.GetComponent<Image>().color;
_color = new Color(_color.r, _color.g, _color.b, 0);
image.GetComponent<Image>().color = Color.Lerp(image.color, _color, 10 * Time.deltaTime);
}
foreach (Text text in textComponents)
{
Color _color = text.GetComponent<Text>().color;
_color = new Color(_color.r, _color.g, _color.b, 0);
text.GetComponent<Text>().color = Color.Lerp(text.color, _color, 10 * Time.deltaTime);
}
yield return null;
}
Idk如何正确执行操作,mb我应该在Update中为每个对象更改颜色,但是我不确定它对于清晰易懂的代码有好处,所以我要问的是-我可以为每个对象使用另一个IEnumerator来工作吗更新,例如:
foreach (Image image in imageComponents)
{
StartCourutine(changeAlpha(image));
}
答案 0 :(得分:1)
错误在于传递10 * Time.deltaTime
作为t
的{{1}}值
如果您查看Lerp(Vector3 a, Vector3 b, float t);
的{{3}}:
当t = 0时返回a。当t = 1时返回b。当t = 0.5时,返回a和b之间的中间点。
这意味着,为了使Alpha具有良好的淡入淡出效果,Lerp()
的{{1}}值应为1到0(如果要淡入淡出则为0到1)在一定时间内。目前,您要传入的t
始终是相同的值(基于帧速率)。 (在这种情况下,约为0.8)。
要解决此问题,您需要将Lerp()
设为在0到1之间缓慢增加/减少(取决于您要淡入还是淡出的值)的值。一种实现方法是将逻辑包裹在while循环中。
10 * Time.deltaTime
每次循环运行时,这将使t
的值增加float speed = 0.01f;
float time = 0;
while ( time < 1)
{
time += speed;
//Rest of code
}
(在本例中为0.01),在本例中为100次迭代(0.01 * 100 = 1)。
我们现在可以将此time
值用作speed
方法中的time
值,以使其平滑过渡
t
如果您希望淡入淡出花费更多或更少的时间,只需增加或减少Lerp()
中的值即可。
整个实现看起来像这样(请注意,我也做了一些优化,稍后将介绍)
image.color = Color.Lerp(image.color, _color, time);
我完成的优化:
您通过speed
和public float speed = 0.01f; //The speed at which the fade happens
private Image[] imageComponents;
private Text[] textComponents;
void Start()
{
imageComponents = gameObject.GetComponentsInChildren<Image>(); //Cache the images so we don't have to find them every time
textComponents = gameObject.GetComponentsInChildren<Text>(); //Cache the texts
StartCoroutine(HideAllBoosters());//Start the Coroutine
}
IEnumerator HideAllBoosters()
{
float t = 0; //Start value for our loop
while (t < 1) // 1 indicates the max value of t at which the loop stops. In this case after 100 iterations since the speed is 0.01
{
t += speed;
foreach (Image image in imageComponents)
{
Color _color = image.color;
_color = new Color(_color.r, _color.g, _color.b, 0);
image.color = Color.Lerp(image.color, _color, t); //t dictates how far in the interpolation we are.
}
foreach (Text text in textComponents)
{
Color _color = text.color;
_color = new Color(_color.r, _color.g, _color.b, 0);
text.color = Color.Lerp(text.color, _color, t);
}
yield return null;
}
}
循环的数组已经是imageComponents
和textComponents
类型。这意味着当您在Image
循环中遍历它们时,Text
和foreach()
已经属于它们各自的类型,并且已经拥有对其组成部分的引用。这意味着您的Image image
和Text text
呼叫是不必要的。
例如:
.GetComponent<Image>()
与
相同.GetComponent<Text>()
我还删除了Color _color = image.GetComponent<Image>().color;
所需的Color _color = image.color;
参数,因为该方法似乎根本没有使用该参数。可能是您稍后在此问题范围之外的函数中确实使用了该值。如果是这种情况,则需要将其包括在内。