Create a Coroutine to Fade Out Different Types of Object

Create a coroutine to fade out different types of object

It could be you're looking for

Tweeng

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.

More...

// 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 :

Just put this in a file Extns.cs:

public static class Extns
{
public static IEnumerator Tweeng( this float duration,
System.Action<float> var, float aa, float zz )
{
float sT = Time.time;
float eT = sT + duration;

while (Time.time < eT)
{
float t = (Time.time-sT)/duration;
var( Mathf.SmoothStep(aa, zz, t) );
yield return null;
}

var(zz);
}

public static IEnumerator Tweeng( this float duration,
System.Action<Vector3> var, Vector3 aa, Vector3 zz )
{
float sT = Time.time;
float eT = sT + duration;

while (Time.time < eT)
{
float t = (Time.time-sT)/duration;
var( Vector3.Lerp(aa, zz, Mathf.SmoothStep(0f, 1f, t) ) );
yield return null;
}

var(zz);
}
}

(Note that those examples include smoothing. You may need no-smoothing in some cases. In fact, in projects now we always have both "Tweeng" and "SmoothedTweeng".)

(If you're interested, you can use a generics approach - fascinating QA on that.)

Tweeng - it could save your life!

How do you fade out an object in a scene from an animation clip?

To achieve what you wanted you would need to add an AnimationEvent into your Animaton.

You can do that with the Rectangle Symbol you find over the Animation Window Properties.

You can now use that AnimationEvent to call a Function in a Script that will fade out the object.

Also make sure to pass in what amount of time you want to fade the object as a float and the current GameObject as an Object into the function.

AnimationEvent Function:

public void FadeOutEvent(float waitTime, object go) {
// Get the GameObject fromt the recieved Object.
GameObject parent = go as GameObject;

// Get all ChildGameObjects and try to get their PBR Shader
List<RPBShader> shaders = parent
.GetComponentsInChildren(typeof(RPBShader)).ToList();

// Call our FadeOut Coroutine for each Component found.
foreach (var shader in shaders) {
// If the shader is null skip that element of the List.
if (shader == null) {
continue;
}
StartCoroutine(FadeOut(waitTime, shader));
}
}

RPBShader would the Type of the Component you want to get.


To fade out the Object over time we would need to use an IEnumerator.

Fade Out Coroutine:

private IEnumerator FadeOut(float waitTime, RPBShader shader) {
// Decrease 1 at a time,
// with a delay equal to the time,
// until the Animation finished / 100.
float delay = waitTime / 100;

while (shader.alpha > 0) {
shader.alpha--;
yield return new WaitForSeconds(delay);
}
}

shader.alpha would be the current's Object PBR Shader Alpha Value that you want to decrease.



Fade out object

You don't need to fade anything. Just attach the AudioSource to the Bee GameObject that does not get destroyed then get reference to it in the Start function. Also use gameObject.CompareTag instead if gameObject.tag

AudioSource coinCollectSound;

void Start()
{
coinCollectSound = GameObject.Find("Bee").GetComponent<AudioSource>();
}

void OnCollisionEnter2D(Collision2D colisor)
{
if (colisor.gameObject.CompareTag ("Bee"))
{

coinCollectSound.Play();

score.AddScore (point);
Destroy(gameObject);
}

if (colisor.gameObject.CompareTag("floor"))
{
Destroy(gameObject, 1.5f);

}
}

EDIT:

Not mentioned in your question that you have 3 sounds.

Create GameObjects named COINSOUNDS then create 3 extra GameObjects under it. Rename them to COINSOUND1,COINSOUND2,COINSOUND3 and attach AudioSource to each of them. Don't attach AudioSource to the COINSOUNDS(parent GameOBject).

COINSOUND1,COINSOUND2,COINSOUND3 must be child of COINSOUNDS GameObject.

AudioSource[] coinCollectSound;

void Start()
{
coinCollectSound = new AudioSource[3];
coinCollectSound[0] = GameObject.Find("COINSOUNDS/COINSOUND1").GetComponent<AudioSource>();
coinCollectSound[1] = GameObject.Find("COINSOUNDS/COINSOUND2").GetComponent<AudioSource>();
coinCollectSound[2] = GameObject.Find("COINSOUNDS/COINSOUND3").GetComponent<AudioSource>();
}

void OnCollisionEnter2D(Collision2D colisor)
{
if (colisor.gameObject.CompareTag("Bee"))
{

coinCollectSound[0].Play();//Play COINSOUND1
coinCollectSound[1].Play();//Play COINSOUND2
coinCollectSound[2].Play();//Play COINSOUND3

score.AddScore (point);
Destroy(gameObject);
}

if (colisor.gameObject.CompareTag("floor"))
{
Destroy(gameObject, 1.5f);

}
}

SOLUTION 3

You can also use coroutine. Start coroutine, fade the image, play sound, wait for sound to finish playing, then destroy. This can only be done in coroutine. This looks better than my other solution.You don't have to modify anything in your current scene with the code below.

SpriteRenderer coinSpriteRenderer;
AudioSource coinCollectSound;

void Start()
{
coinCollectSound = gameObject.GetComponent<AudioSource>();
coinSpriteRenderer = gameObject.GetComponent<SpriteRenderer>();
}

void OnCollisionEnter2D(Collision2D colisor)
{
if (colisor.gameObject.CompareTag("Bee"))
{

score.AddScore (point);
StartCoroutine(fadeAndWaitForSound(1));
}

if (colisor.gameObject.CompareTag("floor"))
{
StartCoroutine(fadeAndWaitForSound(1));
}

}

IEnumerator fadeAndWaitForSound(float fadeTimeInSeconds = 1)
{

Color currentColor = coinSpriteRenderer.color;

Color invisibleColor = coinSpriteRenderer.color;
invisibleColor.a = 0; //Set Alpha to 0

float counter = 0;

//Play sound
coinCollectSound.Play();

//Wait till sound is done playing
while (coinCollectSound.isPlaying)
{
yield return null;
}

//Now Fade texture
while (counter < fadeTimeInSeconds)
{
counter += Time.deltaTime;
coinSpriteRenderer.color = Color.Lerp(currentColor, invisibleColor, counter / fadeTimeInSeconds);
yield return null;
}

//Destroy after fading
Destroy(gameObject);
}

Coroutines in F#

The equivalent F# code is the following:

member this.Fade() =
seq {
for f in 1.0 .. -0.1 .. 0.0 do
let c = renderer.material.color
c.alpha <- f
renderer.material.color <- c
yield ()
} :> IEnumerable

Note that unlike in C#, you have to yield some value, so we're using unit (()). The seq expression will have the type seq<unit>, which is an alias for IEnumerable<Unit>. To make it conform to the type Unity is expecting, we just need to upcast it by using :> IEnumerable



Related Topics



Leave a reply



Submit