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
How to Deserialize a JSON Array into an Object Using JSON.Net
How to Read an Outlook (2003/2007) Pst File in C#
ASP.NET Core 2.0 Ldap Active Directory Authentication
How to Check Whether an Object Has Certain Method/Property
App.Config for a Class Library
Entity Framework Thread Safety
How to Show the Sum of in a Datagridview Column
System.Data.Sqlclient.Sqlexception: Login Failed for User
How to Enable Cross Origin Requests in ASP.NET MVC
ASP.NET Core Metadatatype Attribute Not Working
Delegate Caching Behavior Changes in Roslyn
C# Vertical Label in a Windows Forms
Can You Have a Property Name Containing a Dash