This question was
closed Dec 23, 2015 at 07:40 PM by
KnightRiderGuy for the following reason:
The question is answered, right answer was accepted
Question by
KnightRiderGuy · Dec 22, 2015 at 08:34 PM ·
c#gameobjectscene-switchingfadeoutfade out
Fade Object Out On Scene Change
I have this script that I can't seem to get to work for fading out a rotating game object logo just before the scene changes.
Note: Updated code. I notice a very strange thing happening, the code seems to create a duplicate material in the inspector on the fade out operation, and only fades out the outer ring of my 3D logo even though it is part of the same mesh object. And yet if I manually adjust the alpha of the game object material it fades out perfectly so I have no clue what is going on there.??
using UnityEngine;
using System.Collections;
public class ObjectFader : 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);
}
// These are for testing only.
// void Update()
// {
// if (Input.GetKeyDown (KeyCode.Alpha0) )
// {
// FadeIn();
// }
// if (Input.GetKeyDown (KeyCode.Alpha9) )
// {
// FadeOut();
// }
// }
}
Comment
Best Answer
Answer by KnightRiderGuy · Dec 23, 2015 at 07:09 PM
This one works but it just needs a delay setting added too it that I can set in the inspector.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
[RequireComponent(typeof(MeshRenderer))]
public class ColorChange : MonoBehaviour {
[SerializeField]
float duration;
float t = 0f;
Color color1 = Color.red, color2 = new Color(1f, 1f, 1f, 0f);
MeshRenderer meshRenderer;
void Start(){
meshRenderer = GetComponent<MeshRenderer>();
}
void Update() {
Color color = Color.Lerp(color1, color2, t);
t += Time.deltaTime / duration;
foreach (Material material in meshRenderer.materials) {
material.color = color;
}
}
}
This works:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
[RequireComponent(typeof($$anonymous$$eshRenderer))]
public class ColorChange : $$anonymous$$onoBehaviour {
[SerializeField]
float duration;
float t = 0f;
Color color1 = Color.red, color2 = new Color(1f, 1f, 1f, 0f);
$$anonymous$$eshRenderer meshRenderer;
void Start(){
meshRenderer = GetComponent<$$anonymous$$eshRenderer>();
}
void Update() {
StartCoroutine(FadeLogo());
}
IEnumerator FadeLogo(){
yield return new WaitForSeconds(18.7f); // wait time
Color color = Color.Lerp(color1, color2, t);
t += Time.deltaTime / duration;
foreach ($$anonymous$$aterial material in meshRenderer.materials) {
material.color = color;
}
}
}