Reputation: 153
I have some structs like object - 4 child object - in each child 2 more child. I want for each child object change alpha of their color.
I created IEnumarator that should change alpha but when i test this it only changes for 0.8, not to 0, and i also want to change it by time, smoothly for 2 seconds for example, but it happens quick
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 how to do that right, mb i should change color in Update for each object but i dont sure its good for clear and easy code, so what im asking for - can i use another IEnumerator for each object which would work like an Update, smth like:
foreach (Image image in imageComponents)
{
StartCourutine(changeAlpha(image));
}
Upvotes: 0
Views: 612
Reputation: 5173
The error is in passing 10 * Time.deltaTime
as the t
value for Lerp(Vector3 a, Vector3 b, float t);
If you look at the documentation for Lerp()
:
When t = 0 returns a. When t = 1 returns b. When t = 0.5 returns the point midway between a and b.
This means that in order for your alpha to have a nice fade, the t
value of Lerp()
should be a value that goes from 1 to 0 (or 0 to 1 if you want to fade in) over a certain time. Right now you are passing in 10 * Time.deltaTime
this will always be the same value, based on the framerate. (in this case that would be about 0.8).
To fix this issue you need t
to be a value that slowly increases/decreases (depending on wether you want to fade in or out) between 0 and 1 . One way of doing this is by encasing your logic in a while loop.
float speed = 0.01f;
float time = 0;
while ( time < 1)
{
time += speed;
//Rest of code
}
This will increment the time
value by speed
(in this case 0.01) every time the loop runs, which in this case is for 100 iterations (0.01 * 100 = 1).
We can now apply this time
value as the t
value in the Lerp()
method to make it a smooth transition
image.color = Color.Lerp(image.color, _color, time);
If you want your fade to take more or less time, simply increase or decrease the value in speed
.
the total implementation would look something like this (notice that I've also done some optimizations that I will cover later)
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;
}
}
The optimizations I've done:
The arrays you loop through imageComponents
and textComponents
are already of type Image
and Text
. This means that when you loop through them in a foreach()
loop Image image
and Text text
are already of their respective types, and will already hold a reference to their component. What this means is that your .GetComponent<Image>()
and .GetComponent<Text>()
calls are unnecessary.
In example:
Color _color = image.GetComponent<Image>().color;
is the same as
Color _color = image.color;
I have also removed the Transform _object
parameter that HideAllBoosters
required, as this didn't seem to be used in the method at all. It may be that you do use this value somewhere later in the function that is outside the scope of this question. If that is the case you need to include it ofcourse.
Upvotes: 1