Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 Destran · Mar 18, 2014 at 03:37 PM · color.lerp

Can you change Alpha and Blue(rbg) simultaneously?

Going largely off of aldonaletto's answer on:

http://answers.unity3d.com/questions/328891/controlling-duration-of-colorlerp-in-seconds.html

I'm attempting to fade in/out my GUIText while at the same time lerping the color from white to yellow. Using the following script:

 #pragma strict
 
 var startColor : Color;
 var endColor : Color;
 var warningText : GUIText;
 
 var duration: float = 2; // duration in seconds
 var t: float = 0; // lerp control variable
     
 function Start()
 {
     warningText.material.color.a = 0; // hides warning text
     startColor = Color.white;
     endColor = Color.yellow; //sets color of warning text
 }
 
 function Update()
 {
     if(conditions are met ex: close to detection, low health)
     {
         Fade();
         ColorSwap();
     }
     
     if(conditions are not met)
     {
         warningText.material.color.a = 0; //hide text
     }
 }
 
 function Fade()
     {
         while (warningText.material.color.a < 1) //fade in
         {    
             warningText.material.color.a += 0.005 * Time.deltaTime * 1;
             yield;    
         }  
         
         yield WaitForSeconds(1);
         
         while (warningText.material.color.a > 0) //fade out
         {
             warningText.material.color.a -= 0.005 * Time.deltaTime * 1;
             yield;
         }
     }
     
 function ColorSwap()
     {
         t += Time.deltaTime/duration;
 
         warningText.material.color = Color.Lerp(startColor, endColor, t); //goes white ->yellow
         
           yield WaitForSeconds(2.5); //pauses at yellow for .5 seconds because duration is 2 seconds
         
         warningText.material.color = Color.Lerp(endColor, startColor, t); //goes yellow ->white
         
     }

When using each function separately they work. Which leads me to believe that you can't change color/alpha at the same time. Or is there something I'm doing wrong?

Comment
Add comment
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

3 Replies

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

Answer by wibble82 · Mar 18, 2014 at 03:51 PM

Your issue is that in the ColorSwap function you are setting the colour of the material to a new value each frame. The colour encodes both rgb AND alpha, so you are effectively going:

  • in Fade(): set the alpha of my material to account for fading

  • in ColourSwap(): set the colour of my material to the new colour, AND the alpha to 1

You could do this various ways, your simplest probably being to just set the rgb part of material.color in ColorSwap() to something like:

 //save current alpha
 float current_alpha = warningText.material.color.a; 

 //overwrite colour with new one
 warningText.material.color = Color.Lerp(startColor, endColor, t); 

 //restore alpha (as we only wanted to overwrite the rgb components)
 warningText.material.color.a = current_alpha; 
 

Maybe put that code in a function and call it twice from your colour swap. So you might have a function that went:

 void SetWarningTextMaterialColor(Color new_col)
 {
     //save current alpha
     float current_alpha = warningText.material.color.a; 
 
     //overwrite colour with new one
     warningText.material.color = new_col; 
 
     //restore alpha (as we only wanted to overwrite the rgb components)
     warningText.material.color.a = current_alpha; 
 }

And then your set colour function would be:

 void ColorSwap()
 {
     t += Time.deltaTime/duration;
  
     SetWarningTextMaterialColor(Color.Lerp(startColor, endColor, t)); //goes white ->yellow
  
     yield return new WaitForSeconds(2.5); //pauses at yellow for .5 seconds because duration is 2 seconds
  
     SetWarningTextMaterialColor(Color.Lerp(endColor, startColor, t)); //goes yellow ->white
  
 }

Just realised, I replied in c# to your javascript question! sorry - it should be very easy to convert though. Hopefully the principle is clear anyhoo :)

As a side note, I'm not convinced your code does what you expect it to it looks like it'll just set the colour once, wait 2.5s, then set it again. Presumably you're after a gentle fade from one colour to another over a period of time? There's actually a lot of random yields in there - are you clear on what they mean?

Comment
Add comment · Show 2 · 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 Destran · Mar 18, 2014 at 04:01 PM 0
Share

haha sorry about the yields :(, this isn't the exact script because $$anonymous$$onodevelop is freaking out on me, so I was trying to quickly type it off the top of my head and just forgot to delete the yields (they were meant to be WaitForSeconds that I deleted after I realized they were in the wrong place). But you are correct that I'm looking for a gentle fade, and after running the script I posted above you are correct that it only switches once. I didn't know that about the RBG and alhpa so that is VERY useful to know:D . I'll try implementing what you wrote, seems very promising.

avatar image Destran · Mar 19, 2014 at 01:11 PM 0
Share

Thanks for your answer, it worked well after some tinkering.

avatar image
0

Answer by poncho · Mar 18, 2014 at 03:47 PM

Yes, they can, you are lerping colors from White to Yellow, both have Alpha as 1 and both are RGB(Red, Green, Blue) colors, not RGBA(Red, Green, Blue, Alpha), change the endColor's alpha to desired ending alpha

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 Destran · Mar 18, 2014 at 03:49 PM 0
Share

How would that look? as a quick 1-line example. I'm not very confident with my understanding of Color.Lerp

avatar image
0

Answer by robertbu · Mar 18, 2014 at 03:57 PM

In your ColorSwap(), you apparently want to fade to/from yellow over time, yet you don't put while loops in like you've done for Fade():

 function ColorSwap()
 {
     var t : float = 0.0;
     while (t < 1.0) {
          warningText.material.color = Color.Lerp(startColor, endColor, t); 
          yield;
          t += Time.deltaTime/duration;
     }
     warningText.material.color = endColor;
 
     yield WaitForSeconds(2.5); //pauses at yellow for .5 seconds because duration is 2 seconds
 
     t = 0.0;
     while (t < 1.0) {
         warningText.material.color = Color.Lerp(endColor, startColor, t); //goes yellow ->white\
         yield;
         t += Time.deltaTime/duration;
     }
     warningText.material.color = startColor;
 }

Note you have pseudo-code here:

 if(conditions are met ex: close to detection, low health)
 {
    Fade();
    ColorSwap();
 }

But you want to be very careful that once conditions are met, you only call these two functions once; It is easy given the structure of your code here to be calling them every frame. That would result in lots of coroutines all running at the same time...around 400 if you are running at 60 fps.

Comment
Add comment · Show 5 · 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 Destran · Mar 18, 2014 at 04:13 PM 0
Share

if I had a statement in Update ()like:

 if(currentHealth < 20)
 {
 Fade();
 ColorSwap();
 }

Wouldn't it only have the coroutines run while currenthealth is less than 20?

avatar image robertbu · Mar 18, 2014 at 04:41 PM 1
Share

No. no. no. This will not work...or more correctly, it will sorta-work but have serious issues. A coroutine (in Javascript any fucntion that has a yield) is created each time the function is called. That coroutine exists until it finishes. So 'ColorSwap()' takes 6.5 seconds to run. Assu$$anonymous$$g currentHealth remains below 20 for the 6.5 seconds, you will be creating a new coroutine each time ColorSwap() is called. So running at 60 fps, in 6.5 seconds you will call ColorSwap() 390 times. That means you will have 390 coroutines, all offset by one deltaTime in terms of their ti$$anonymous$$g, running at the same time, all trying to adjust the color. At the end of 6.5 seconds, the first one completes, but as long as currentHealth < 20, you will still be creating new ones...so you will continue to have 390 coroutines running until the health is again above 20.

A fix is to use a boolean variable. Something like:

 if (currentHealth < 20 && !fadeSwap) {
     Fade();
     ColorSwap();
     fadeSwap = true;
 
 }
 if (currentHealth >= 20) {
     fadeSwap = false;
 }

Even this code as a bit of a hole in that if the health goes above 20 and then again down below 20 in less than 6.5 seconds, you could end up with two ColorSwap() coroutine running at the same time.

avatar image Destran · Mar 18, 2014 at 04:54 PM 0
Share

okay I get that, and to avoid it being called twice, create a 7ish second timer and check that the timers expired before being able to call it again. This is really helpful to know, time to go fix some code.

avatar image robertbu · Mar 18, 2014 at 05:02 PM 0
Share

Rather than a 7 second timer, you could put a boolean value like 'swapping' at the top of the file and set it to true at the top of ColorSwap() and false at the bottom. That way you would know when the coroutine is running.

Or you could just have ColorSwap() clear the 'fadeSwap' flag when it finished, but if you do that and currentHealth < 20, then the Coroutine will fire again.

avatar image Destran · Mar 18, 2014 at 05:06 PM 0
Share

alright thanks :D

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

22 People are following this question.

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

Related Questions

Unable to Color.Lerp in two directions (Solved) 1 Answer

Color.Lerp doesn't work 1 Answer

Fade in text one character at a time 3 Answers

GUI.DrawTexture Fade In/Out Problem 1 Answer

Unity 2020.1 List index out of range and colors not changing smoothly 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