- Home /
Fade object in smoothly not working
Hi,
I'm using this script to fade an object in when the scene loads - but rather than fading in from transparent, for the first second it appears as fully opaque, and then disappears, after which the fade works as normal. I've been comparing it with other ones - but I just can't work out how to get rid of this split second when the game loads, and the object can be seen.
Sorry for the newbie question - but any ideas on how to get the fade in working smoothly?
using UnityEngine;
using System.Collections;
public class FadeInAndOut : MonoBehaviour
{
// publically editable speed
public float fadeDelay = 0.0f;
public float fadeTime = 0.5f;
public bool fadeInOnStart = false;
public bool fadeOutOnStart = false;
private bool logInitialFadeSequence = false;
// store colours
private Color[] colors;
// allow automatic fading on the start of the scene
IEnumerator Start ()
{
//yield return null;
yield return new WaitForSeconds (fadeDelay);
if (fadeInOnStart)
{
logInitialFadeSequence = true;
FadeIn ();
}
if (fadeOutOnStart)
{
FadeOut (fadeTime);
}
}
// check the alpha value of most opaque object
float MaxAlpha()
{
float maxAlpha = 0.0f;
Renderer[] rendererObjects = GetComponentsInChildren<Renderer>();
foreach (Renderer item in rendererObjects)
{
maxAlpha = Mathf.Max (maxAlpha, item.material.color.a);
}
return maxAlpha;
}
// fade sequence
IEnumerator FadeSequence (float fadingOutTime)
{
// log fading direction, then precalculate fading speed as a multiplier
bool fadingOut = (fadingOutTime < 0.0f);
float fadingOutSpeed = 1.0f / fadingOutTime;
// grab all child objects
Renderer[] rendererObjects = GetComponentsInChildren<Renderer>();
if (colors == null)
{
//create a cache of colors if necessary
colors = new Color[rendererObjects.Length];
// store the original colours for all child objects
for (int i = 0; i < rendererObjects.Length; i++)
{
colors[i] = rendererObjects[i].material.color;
}
}
// make all objects visible
for (int i = 0; i < rendererObjects.Length; i++)
{
rendererObjects[i].enabled = true;
}
// get current max alpha
float alphaValue = MaxAlpha();
// This is a special case for objects that are set to fade in on start.
// it will treat them as alpha 0, despite them not being so.
if (logInitialFadeSequence && !fadingOut)
{
alphaValue = 0.0f;
logInitialFadeSequence = false;
}
// iterate to change alpha value
while ( (alphaValue >= 0.0f && fadingOut) || (alphaValue <= 1.0f && !fadingOut))
{
alphaValue += Time.deltaTime * fadingOutSpeed;
for (int i = 0; i < rendererObjects.Length; i++)
{
Color newColor = (colors != null ? colors[i] : rendererObjects[i].material.color);
newColor.a = Mathf.Min ( newColor.a, alphaValue );
newColor.a = Mathf.Clamp (newColor.a, 0.0f, 1.0f);
rendererObjects[i].material.SetColor("_Color", newColor) ;
}
yield return null;
}
// turn objects off after fading out
if (fadingOut)
{
for (int i = 0; i < rendererObjects.Length; i++)
{
rendererObjects[i].enabled = false;
}
}
Debug.Log ("fade sequence end : " + fadingOut);
}
void FadeIn ()
{
FadeIn (fadeTime);
}
void FadeOut ()
{
FadeOut (fadeTime);
}
void FadeIn (float newFadeTime)
{
StopAllCoroutines();
StartCoroutine("FadeSequence", newFadeTime);
}
void FadeOut (float newFadeTime)
{
StopAllCoroutines();
StartCoroutine("FadeSequence", -newFadeTime);
}
}
All the best, Laurien
When you say the objects are visible for a second, do you mean literally a full second, or that they show up for a brief moment (1 frame) then start fading in?
If they are only showing up for a single frame then try the following:
// make all objects visible
for (int i = 0; i < rendererObjects.Length; i++)
{
rendererObjects[i].enabled = true;
}
For the above code block here ensure that your current alpha value also gets set to 0 if you are fading in. e.g. loop through your renderers to set the _Color
rendererObjects[i].material.SetColor("_Color", newColor)
Answer by DFortun81 · Jan 13, 2015 at 12:56 AM
While your solution seems a tad unorthodox, it would seem that there is a logical error present in your while loop.
newColor.a = Mathf.Min ( newColor.a, alphaValue );
Your alpha value will never go up no matter what you set it to and will immediately set itself to 0 the first time it is run when fading out the component.