- Home /
Triggering timed dissolve in shader graph via a C# coroutine
Hi, I've created a dissolve shader in shader graph (see https://youtu.be/taMp1g1pBeE). I'm trying to trigger the dissolve on a list of materials simultaneously using a C# coroutine. I want to control the duration of the dissolve and I want the dissolve to occur smoothly. Currently the transition is jagged and I'm having difficulty finding the right method to control the time.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ShaderTrigger : MonoBehaviour {
public GameObject dissolveModel;
public List<Material> dissolveMaterials;
public float duration = 2f;
void Start ()
{
//Access materials on the model to dissolve via their renderer
Renderer[] rends = dissolveModel.GetComponentsInChildren<Renderer>();
foreach (Renderer rend in rends)
{
dissolveMaterials.Add(rend.material);
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("Space pressed");
StartCoroutine(Dissolve());
}
}
IEnumerator Dissolve ()
{
float dissolveValue = 0f;
Debug.Log("Dissolve coroutine started");
while (dissolveValue < 1f)
{
foreach (Material mat in dissolveMaterials)
{
dissolveValue += duration * (0.02f / Time.deltaTime);
dissolveValue = Mathf.Clamp01(dissolveValue);
mat.SetFloat("Vector1_66CEB364", dissolveValue);
yield return null;
}
yield return null;
}
}
}
Any advice is appreciated.
Answer by DCordoba · Feb 07, 2019 at 01:20 AM
you need to learn about Waitforseconds and some wait constructors on IEnumerator, also you need to see your design, there is some (I believe) mistakes:
return null just set null a variable if you store the coroutine on it at the startCoroutine, dont stop the time, like I think that you was trying.
you want to disolve all objects on the list at the same time, so set disolveValue inside the while, but only apply inside the for, otherwise you will increment disolve value by each object modified, not by time.
Time.DeltaTime is the time that take to render the previous frame, is commonly used on update to simulate some proportional space of time when use fixed values, since we will use wait for seconds, that not apply here
IEnumerator Dissolve () { float dissolveValue = 0f; Debug.Log("Dissolve coroutine started"); while (dissolveValue < 1f) { dissolveValue += 0.02f; dissolveValue = Mathf.Clamp01(dissolveValue); foreach (Material mat in dissolveMaterials) { mat.SetFloat("Vector1_66CEB364", dissolveValue); } //sum 0.02 each time takes 50 times to reach 1, so we have 50 iterations yield return new WaitForSeconds(duration/50f); } }
you can also set a bool to check if you already started a coroutine, or check if are coroutines active to not reset the disolve effect each time you press space.
@DCordoba $$anonymous$$any thanks! Setting dissolve value was the right move. I also intend to implement the bool. The waitForSeconds seemed to cause juddering though and prevented a smooth transition. I'm still going over it.
shame, but the smoothness of the transitions on waitforseconds, depends the time wait between transition, on this case it is duration/50f, we can modify it changing the number of iterations, by example duplicating it (from 50 iterations to 100)
dissolveValue += 0.01f;
...
yield return new WaitForSeconds(duration/100f);
Answer by Bunny83 · Feb 07, 2019 at 11:54 AM
What you probably want is this:
IEnumerator Dissolve ()
{
float dissolveValue = 0f;
Debug.Log("Dissolve coroutine started");
while (dissolveValue < 1f)
{
dissolveValue += Time.deltaTime / duration;
dissolveValue = Mathf.Clamp01(dissolveValue);
foreach (Material mat in dissolveMaterials)
{
mat.SetFloat("Vector1_66CEB364", dissolveValue);
}
yield return null;
}
}
@Bunny83 Thanks for the reply. Time.deltaTime / duration gave me the smooth transition I was looking for which was spot on. I was intending for duration to control the length of the dissolve in seconds though so that increasing the duration slows the dissolve down.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
StopCourutine not working as expectedd 2 Answers
Is it possible to modify a material/shader in code? 1 Answer