Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why when fading out list of materials each material fade out in another time and not all the materials fade at the same time?

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class FadeInOut : MonoBehaviour
{
    List<Material> mats = new List<Material>();

    private void Start()
    {
        foreach (Transform g in transform.GetComponentsInChildren<Transform>())
        {
            if (g.GetComponent<SkinnedMeshRenderer>() != null)
            {
                var l = g.GetComponent<SkinnedMeshRenderer>().sharedMaterials.ToList();
                foreach(Material mat in l)
                {
                    mats.Add(mat);
                }                
            }
        }  
    }

    private void Update()
    {
        if(Input.GetKeyDown(KeyCode.G))
        {
            StartCoroutine(FadeTo(mats, 0, 0.5f));
        }
    }

    IEnumerator FadeTo(List<Material> materials, float targetOpacity, float duration)
    {
        for (int i = 0; i < materials.Count; i++)
        {
            Color color = materials[i].color;
            float startOpacity = color.a;

            float t = 0;

            while (t < duration)
            {
                t += Time.deltaTime;
                float blend = Mathf.Clamp01(t / duration);

                color.a = Mathf.Lerp(startOpacity, targetOpacity, blend);

                materials[i].color = color;

                yield return null;
            }
        }
    }
}

The first material fade out after 0.5f second but then the other materials each one fade out in a bit more time the last one almost 1-2 seconds after the first one.

and i want all the materials to fade out a the same time if the time is 0.5f or 5f then fade out all the materials after 5 seconds or after 0.5f but the same time and not one after the other.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Because your outer for loop is going through materials:

for (int i = 0; i < materials.Count; i++)

and your inner while loop is running the timing on one material:

while (t < duration)
{
    t += Time.deltaTime;
    // ...
    materials[i].color = color;
}

So you get material 0, then fade it, then you get material 1, then fade it, etc.

If you want to fade all the materials together then you should swap your loops so you run a timer for everything then iterate through the materials at each time step, like:

IEnumerator FadeTo(List<Material> materials, float targetOpacity, float duration)
{
    float t = 0;
    List<float> startOpacities = new List<float>();
    foreach(var material in materials)
    {
        startOpacities.Add(material.color.a);
    }
    
    while (t < duration)
    {
        t += Time.deltaTime;
        float blend = Mathf.Clamp01(t / duration);
        
        for (int i = 0; i < materials.Count; i++)
        {
            Color color = materials[i].color;
            color.a = Mathf.Lerp(startOpacities[i], targetOpacity, blend);
            materials[i].color = color;
        }
        yield return null;
    }
}

So here I’m caching all the starting opacities, then entering the timing loop. Each timing loop we increment the t value, which is used to determine blend, then we loop through each material and alter the alpha channel. After all the materials are set, THEN we yield return null.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading