Uri Popov Uri Popov - 1 month ago 10
C# Question

Create a coroutine to fade out different types of object

Hi I'm trying to create a coroutine in unity that will handle fading on all manner of object. So far I'm able to get the alpha values of the different types I want but I'm at a dead end as to how to set the new color after lerping it. Here is my code :

public static IEnumerator FadeTo(float aValue, float aTime,GameObject gameObj)
{
Component[] allComponents = gameObj.GetComponents(typeof(Component));
Component fadableComponent;
Type type = null;
float alpha=0;
foreach(Component c in allComponents)
{
if(c.GetType()==typeof(Image))
{
fadableComponent = c;
alpha = fadableComponent.GetComponent<Image>().color.a;
type = fadableComponent.GetType();
Debug.Log("Found a image");
break;
}
if (c.GetType() == typeof(Renderer))
{
fadableComponent = c;
alpha = fadableComponent.GetComponent<Renderer>().material.color.a;
type = fadableComponent.GetType();
break;
}
if (c.GetType() == typeof(SpriteRenderer))
{
fadableComponent = c;
alpha = fadableComponent.GetComponent<SpriteRenderer>().color.a;
type = fadableComponent.GetType();
break;
}
if(c.GetType()== typeof(CanvasGroup))
{
fadableComponent = c;
alpha = fadableComponent.GetComponent<CanvasGroup>().alpha;
type = fadableComponent.GetType();
}
Debug.Log(alpha.ToString());
}


for (float t = 0.0f; t < 1.0f; t += Time.deltaTime / aTime)
{
Color newColor = new Color(1, 1, 1, Mathf.Lerp(alpha, aValue, t));
gameObj.transform.GetComponent(type) // What now ?!
yield return null;
}
yield return null;
}
}


Now i know how to do this with lets say another set of if's or what not, but I want to avoid that. For example of solutions I want to avoid I took a look at the iTween implementation. Here is a perfect example of what I want to avoid:

if(target.GetComponent<GUITexture>()){
target.GetComponent<GUITexture>().color=colors[3];
}else if(target.GetComponent<GUIText>()){
target.GetComponent<GUIText>().material.color=colors[3];
}else if(target.GetComponent<Renderer>()){
target.GetComponent<Renderer>().material.color=colors[3];
}else if(target.GetComponent<Light>()){
target.GetComponent<Light>().color=colors[3];
}


This is a mess, moms spaghetti. Extending this will be a nightmare.

Answer

It could be you're looking for

Tweeng

"the single most amazing thing in all of Unity".

It's the crack cocaine of game programming.

The basic syntax is

 time.Tweeng( do something )

so (in pseudocode)

StartCoroutine( 2f.Tweeng( .. move the ball .. ) );
StartCoroutine( .5f.Tweeng( .. spin the spaceship .. ) );
StartCoroutine( 1f.Tweeng( .. fade the text .. ) );

Those examples are,

  • move the ball over two seconds
  • spin the spaceship in 1/2 second
  • fade the text over one second.

Using Tweeng is so euphoric, it can cause permanent psychological problems unless you have a steady head.

// tweeng z to 20 degrees in .12 seconds
StartCoroutine(.12f.Tweeng( (t)=>transform.Eulers(0f,0f,t), 0f,20f) );

// fade in alpha in .75 seconds
StartCoroutine(.75f.Tweeng( (u)=>{c.a=u;s.color=c;}, 0f,1f) );

// duck volume..
StartCoroutine(  .3f.Tweeng( x=>{current.volume=x;}, current.volume, 0f) );

// move something..
StartCoroutine(secs.Tweeng( (p)=>parked.transform.position=p,
  parked.transform.position,
  landing.transform.position) );

// twist image
yield return StartCoroutine( .3f.Tweeng(
  (u)=>polaroid.localEulerAngles = new Vector3(0f,0f,u),
  0f,9f) );

You can Tweeng anything, certainly including fades.

basic code base for Tweeng

(Actually personally I like to just have, in my Extensions file, a few different Tweengs for each type; the generics approach is cute but maybe too clever. It's important to realize that is opaque to you; in your code base you just "Tweeng" with no concern for the type, which is great. In short,

, in your extensions file, write a Tweeng for each type that is relevant to you. You can then achieve exactly the aim of your question in all your code base. Just Tween anything.

Note that you have now covered every sort of animation; not just fades as mentioned in your question but every move, spin, bounce, zoom, effect, etc etc.

Watch out for falling in to a hypnotic state! :)

Indeed, here's an extension (using Tweeng) I use in some cases for fades. It's convenient to set up variables for handy use inside the lambda (such as "c" in the example).

public static void FadeIn(this Main mb, SpriteRenderer s)
    {
    Color c = s.color;
    c.a = 0f;
    s.color = c;
    mb.StartCoroutine( 1.25f.Tweeng( (u)=>{c.a=u;s.color=c;}, 0f,1f) );
    }

Also!

Unrelated to extensions and tweeng. Don't forget the little-known crossFadeAlpha call recently added to Unity! The call is a little confusing but it can work very well.

Here's an example (presented as an extension!)

The critical fact is that canvasRenderers always have an alpha ability, in the UI system.

public static class ExtensionsMeasures
    {

    public static void FadeIn(this Graphic g)
        {
        g.GetComponent<CanvasRenderer>().SetAlpha(0f);
        g.CrossFadeAlpha(1f,.15f,false);
        }

    public static void FadeOut(this Graphic g)
        {
        g.GetComponent<CanvasRenderer>().SetAlpha(1f);
        g.CrossFadeAlpha(0f,.15f,false);
        }