Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by MaddoScientisto · Oct 09, 2015 at 10:00 AM · fading

My coroutine fader is not fading

I made a script to fade a scene to black starting from some examples, I tried to do it with coroutines rather than just doing it in update, with the hope that the fader would actually stop the calling object until it's done with the fading animation.

I also tried to dynamically generate the texture rather than making a big black texture manually.

In my controller, just before loading the new scene, I call

 var fader = GameObject.FindObjectOfType<SceneFadeInOut>();
             fader.StartFade();

here's the fader class

 public class SceneFadeInOut : MonoBehaviour
     {
         private Texture2D _blackTexture;
 
         public float FadeSpeed = 1.5f;
         private bool _doFade = false;
         private GUITexture _GUITexture;
 
         public Color FadeTo; 
         public Color FadeFrom;
             
 
 
 
         private void Awake()
         {
             _blackTexture = new Texture2D(1,1);
             _blackTexture.SetPixel(0,0,Color.black);
             

             _GUITexture = GetComponent<GUITexture>();
             _GUITexture.texture = _blackTexture;
             _GUITexture.pixelInset = new Rect(0,0,Screen.width,Screen.height);
 
 
         }
 
         public void StartFade()
         {
             StartCoroutine(Fade(_GUITexture, FadeSpeed, FadeFrom, FadeTo));
         }
 
         IEnumerator Fade(GUITexture mat, float duration, Color startColor, Color endColor)
         {  // remember the start
             float start = Time.time;
             float elapsed = 0;
             do
             {  // calculate how far through we are
                 elapsed = Time.time - start;
                 float normalisedTime = Mathf.Clamp(elapsed / duration, 0, 1);
                 mat.color = Color.Lerp(startColor, endColor, normalisedTime);
                 // wait for the next frame
                 yield return null;
             }
             while (elapsed > duration);
         }
 
     }


When I do the transition the coroutine code seems to run but nothing really happens and then the new scene loads as normal

What could I be doing wrong?

Comment
Add comment · Show 6
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Oct 09, 2015 at 10:13 AM 0
Share

Well, you said that you load a new level. When do you load it? Immediately after calling "StartFade"? Do you have a DontDestroyOnLoad somewhere on the script that does the fading? if not the gameobject will be destroyed when the new scene is loaded.

Or is that script in the new scene? If so, from where do you start your coroutine?

avatar image MaddoScientisto Bunny83 · Oct 09, 2015 at 01:08 PM 0
Share

I'm calling that from another object when the new scene loads actually, I didn't get around to do the scene-end one yet

avatar image Bunny83 MaddoScientisto · Oct 10, 2015 at 11:00 AM 0
Share

Wait, so you call "StartFade" before you call LoadLevel? That has several problems. First, as i asked already do you have a DontDestroyOnLoad call in your class somewhere? If not the gameobject will be destroyed when the new scene loads.

Second, Since you start the coroutine before you load the scene (now guessing the object will survive the level load) you will skip some of the time. That's because you grab the current time before the level load. If the level load takes 2 seconds for example then the time would jump 2 seconds ahead after the level load. Since you only use 1.5 second duration you probably won't see anything.

Have you seen this question:

http://answers.unity3d.com/questions/119918/transitions-between-changing-scenes.html

Show more comments
avatar image JoshuaMcKenzie · Oct 09, 2015 at 01:50 PM 0
Share

The code here seems correct. its likely either the things you're inputting into the class or the state of the ancestor gameobjects that this class is attached to that is the source of the issue. check the texture and colors your setting for the class, check if the gameobject is active in the hierarchy when the coroutine is called (also keep an eye open for canvasgroups). you could be running the coroutine while the gameobject is hidden due to a parent object being disabled or a canvas group setting the alpha to 0.

avatar image MaddoScientisto JoshuaMcKenzie · Oct 09, 2015 at 02:03 PM 0
Share

The texture is set in the awake event of the scene fade object and I'm 100% sure the caller object exists.

I could be setting the wrong texture colors on that event though, I don't know

3 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by MaddoScientisto · Oct 10, 2015 at 04:01 PM

I finally managed to find the solution so here's what I did:

First I scrapped the GUITexture and instead I made a RawImage and put it inside a canvas, then I attached the script to it. The RawImage doesn't need to have a texture set, just the color (to black).

Then the script is as follows:

 public class SceneFadeInOut : MonoBehaviour
     {   
         private RawImage _image; 
 
         private void Awake()
         {

             _image = GetComponent<RawImage>();  
         }
    
         public IEnumerator FadeIn(float speed)
         {
             yield return StartCoroutine(Fade(_image, speed, Color.black, Color.clear));
         }
 
         public IEnumerator FadeOut(float speed)
         {
             yield return StartCoroutine(Fade(_image, speed, Color.clear, Color.black));
         }
 
         IEnumerator Fade(RawImage mat, float duration, Color startColor, Color endColor)
         {  
             float start = Time.time;
             float elapsed = 0;
              while (elapsed < duration) { 
               // calculate how far through we are
                 elapsed = Time.time - start;
                 float normalisedTime = Mathf.Clamp(elapsed / duration, 0, 1);
                 mat.color = Color.Lerp(startColor, endColor, normalisedTime);
                 // wait for the next frame
                 yield return null; 
             }              
         }  
     }

And that's it, it just works, just call startcoroutine with fadein or fadeout and everything works neatly!

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Pharan · Oct 10, 2015 at 06:37 PM 1
Share

@dudester gave wrong info. If you're just waiting for the next frame, all you need is yield return null.

Technically, WaitForEndOfFrame is at the end of the current frame. Not the next frame.

yield return null also has the benefit of not allocating a new object every frame.

avatar image MaddoScientisto Pharan · Oct 12, 2015 at 01:01 PM 0
Share

Corrected with your suggestion

avatar image Ziplock9000 · Sep 27, 2017 at 11:59 AM 0
Share

When are you calling FadeIn and FadeOut, that's the actual complicated part as you might get strange things like seeing the fade in only starting after all objects are loaded and displayed or the fade out never happening or fading out when the next level is loading.

avatar image Ziplock9000 · Sep 27, 2017 at 12:13 PM 0
Share

When are you calling FadeOut, making sure the level stays loaded while doing so and only loads the next when the fade is done? Thats's the tricky part.

avatar image
1

Answer by GameDev_Chuck · May 25, 2016 at 07:04 PM

A little late to the party, but here's my contribution. I use a ui Panel instead of a 2D Texture

 using UnityEngine;
 using System.Collections;
 
 public class FadePanel : MonoBehaviour
 {
     // Add a fade panel to your UI Canvas
     // Make the panel black (On image component, 
     // set image to none, make color black)
     // Add a Canvas Group component to the panel
     // Set the Alpha of the canvas group to 0
     // Add this script to the panel 
 
     public CanvasGroup canvasGroup;     // Drop the panel with the canvas 
                                         // group on this field in the inspector
                                         // or make it private and use GetComponent 
                                         // in Awake()
     public float fadeSpeed = 1f;
 
     void Start()                // If you want the panel to fade in when the scene loads
     {
         StartCoroutine("Fade");
     }
 
     public void FadePanelIn()    // If you want to fade to black at some other time
     {
         StartCoroutine("Fade");
     }
 
     IEnumerator Fade()
     {
         while (canvasGroup.alpha != 1)
         {
             canvasGroup.alpha = Mathf.MoveTowards(canvasGroup.alpha, 1, fadeSpeed * Time.deltaTime);
             yield return null;
         }
     }
 }



Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Ziplock9000 · Sep 27, 2017 at 12:12 PM 0
Share

So when are you calling fade to black then, I notice you didn't flesh that bit out.

avatar image
-2

Answer by dudester · Oct 09, 2015 at 01:08 PM

this in incorrect , the script does not run continuously due to the while being in the wrong place it should be like so

   IEnumerator Fade(GUITexture mat, float duration, Color startColor, Color endColor)
                  {while (elapsed > duration){
          // remember the start
                      float start = Time.time;
                      float elapsed = 0;
        
                      
 // calculate how far through we are
                          elapsed = Time.time - start;
                          float normalisedTime = Mathf.Clamp(elapsed / duration, 0, 1);
                          mat.color = Color.Lerp(startColor, endColor, normalisedTime);
                          // wait for the next frame
                        //  yield return null; incorrect will stop coroutine
                       yield return new WaitForEndOfFrame();
                      }
                      
                  }
         


Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image MaddoScientisto · Oct 09, 2015 at 06:14 PM 0
Share

I tried your code but the while up there seems to be marked wrong (did you mix up the while and do while syntax?) and WaitForUpdate doesn't exist, WaitForFixedUpdate exists though so I'm trying with that.

With this code I can see that it's actually doing the cycle correctly but the texture doesn't display, so I have a problem there too I guess

 IEnumerator Fade(GUITexture mat, float duration, Color startColor, Color endColor)
         {  // remember the start
             float start = Time.time;
             float elapsed = 0;
              while (elapsed < duration) { 
               // calculate how far through we are
                 elapsed = Time.time - start;
                 float normalisedTime = $$anonymous$$athf.Clamp(elapsed / duration, 0, 1);
                 mat.color = Color.Lerp(startColor, endColor, normalisedTime);
                 // wait for the next frame
                 yield return new WaitForFixedUpdate(); 
             }
            
         }



avatar image dudester · Oct 09, 2015 at 07:13 PM 0
Share

appologys yes i had them mixed up i forgot to remove that from it , ill edit my answer to reflect that , also sorry i was thinking of the wrong thing its WaitForEndOfFrame(); not WaitForUpdate(); damn i really need to double check these things before hand , its better to use WaitForEndOfFrame(); cause it means your texture will fade correctly , also as to your problem are you just fading the alpha value? cause if not you need to do that .

avatar image Bunny83 · Oct 10, 2015 at 10:50 AM 0
Share

Actually the original code of the OP is much more correct than yours. You put the declaration and initialization of the start variable inside the while which will make the while loop to never end.

I admit that the "do while" loop is usually rarely used, but it's still correct.

 do
 {
     
 }
 while(condition);

In this case here it doesn't matter if you put the condition athte beginning or at the end. However there are other cases where it does matter. A do while loop will always run through the loop body at least once, even when the condition is false:

 do
 {
     Debug.Log("You'll see that")
 }
 while(false);
 
 while(false)
 {
     Debug.Log("You'll NOT see that")
 }

avatar image Pharan · Oct 10, 2015 at 06:39 PM 0
Share

I think you're mistaken.

yield return null doesn't stop the coroutine. It waits for the next update.

yield break breaks out of the coroutine.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

9 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Fading In and Out the GUI 1 Answer

How do I fade a light point? 3 Answers

My image does not get transparent all the way! 1 Answer

Fade Out over length of object on Material? 0 Answers

Fading Not Working 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges