Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Opacity over time

Discussion in 'Scripting' started by GFFG, Jan 27, 2016.

  1. GFFG

    GFFG

    Joined:
    Nov 13, 2014
    Posts:
    224
    Hi, I've been trying to have some blood spatter on the ground in my game over time with this script:
    Code (CSharp):
    1. float fadeOutTime = 8.0f;
    2.  
    3.  
    4.     void Start()
    5.     {
    6.         StartCoroutine( FadeOut( fadeOutTime, renderer.material ) );
    7.     }
    8.  
    9.  
    10.     IEnumerator FadeOut( float time, Material material )
    11.     {
    12.         float index = 0.0f;
    13.         float rate = 1.0f/time;
    14.         while( index < 1.0f )
    15.         {
    16.             index -= rate;
    17.             material.SetFloat ("_Cutoff", index);
    18.             yield return null;
    19.         }
    20.        
    21.     }
    It doesn't work however. It remains at either maximum or minimum alpha cutoff depending on + or -, can anybody please help? It's supposed to slowly become more and more visible.
     
  2. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    633
    Hi, I believe "index" stays bellow zero forever. You start off a value of 0 then remove 1/8th every frame, so unless you're using a shader that supports negative cutoff values it wont work.
     
  3. GFFG

    GFFG

    Joined:
    Nov 13, 2014
    Posts:
    224
    Okay. Thank you for the input
     
  4. The-Little-Guy

    The-Little-Guy

    Joined:
    Aug 1, 2012
    Posts:
    297
    This could be done without a Coroutine. I would do something like this:

    Code (CSharp):
    1. public class Test : MonoBehaviour {
    2.  
    3.     public float duration = 8f;
    4.  
    5.     float time;
    6.     Material material;
    7.  
    8.     void Start(){
    9.         material = GetComponent<Renderer>().material;
    10.     }
    11.  
    12.     void Update(){
    13.         float val = Mathf.Lerp(1f, 0f, time);
    14.         time += Time.deltaTime / duration;
    15.  
    16.         material.SetFloat ("_Cutoff", val);
    17.     }
    18.  
    19. }
     
    GFFG likes this.
  5. GFFG

    GFFG

    Joined:
    Nov 13, 2014
    Posts:
    224
    It works perfectly. I was sure coroutine was the way to go but time += Time.deltaTime / duration; is a new one for me. Thank you very much
     
    The-Little-Guy likes this.
  6. The-Little-Guy

    The-Little-Guy

    Joined:
    Aug 1, 2012
    Posts:
    297
    Also note, to test completion, the returned value of the Lerp will return the second parameter. So If you wanted to destroy the object upon completion, you would do this:

    Code (CSharp):
    1.     void Update(){
    2.         float val = Mathf.Lerp(1f, 0f, time);
    3.         time += Time.deltaTime / duration;
    4.  
    5.         material.SetFloat ("_Cutoff", val);
    6.  
    7.         if(val <= 0f{
    8.             Destroy(gameObject);
    9.         }
    10.     }
     
    GFFG likes this.
  7. GFFG

    GFFG

    Joined:
    Nov 13, 2014
    Posts:
    224
    Awesome! Thanks :)