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.
CodePudding user response:
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
.