Search Unity

Fading groups of objects

Discussion in 'UGUI & TextMesh Pro' started by highlyinteractive, Dec 13, 2014.

  1. highlyinteractive

    highlyinteractive

    Joined:
    Sep 6, 2012
    Posts:
    116
    This might be outside the scope of Unity UI, but here's my problem:

    Imagine I have a UI element with two child Image objects.
    The images are just solid colours. The back one is red & the front one is white. They're both the same size, so it just looks like a single white square.
    The parent object has a CanvasGroup so that I can fade the alpha of everything at once.

    When I fade the parent out, the white square becomes translucent pink before it's fully transparent.

    Is there any way to keep it white without hiding/changing the red Image?

    (obviously this is a simple example, but in my more complex scenario it's incredibly difficult for me to alter the red square before fading the group)
     
    Tymianek likes this.
  2. FamerJoe

    FamerJoe

    Joined:
    Dec 21, 2013
    Posts:
    193
    If you were to "keep it white", you wouldn't be fading it out at all. The reason it turns pink is because as soon as the alpha of the image is < 1, you can begin to see the red through it, which is also < 1 alpha.
     
  3. highlyinteractive

    highlyinteractive

    Joined:
    Sep 6, 2012
    Posts:
    116
    Yeah, I get that, but I'd like to somehow flatten/rasterise it or treat it like a single layer.

    For example, Flash used to have a blendMode that would achieve this. I wondered if anyone knows of a similar trick I could use in this situation.
     
  4. FamerJoe

    FamerJoe

    Joined:
    Dec 21, 2013
    Posts:
    193
    I'm not sure about that one.. I'm sure there is a way, but it's a pretty strange thing you want to do there overall :) I'm more interested in why you say you can't just hide the red square when the fade begins!
     
    Last edited: Dec 15, 2014
  5. highlyinteractive

    highlyinteractive

    Joined:
    Sep 6, 2012
    Posts:
    116
    Maybe the way I'm explaining it is strange :p

    Imagine you've got a playing card in your UI. One side is the face, and one side is the back. If you have the card face down and try to fade it out, you'll get a glimpse of the face value.

    Obviously the solution there is to hide the face completely. But my UI object is a lot more complex.

    Anything with lots of layers looks really odd when you try to fade it out, which is why I'm after a simple way to 'flatten' my UI object when it fades in/out.
     
  6. FamerJoe

    FamerJoe

    Joined:
    Dec 21, 2013
    Posts:
    193
    Makes a lot more sense now, but I still don't know how it could be so complex to the point you couldn't get a reference to the back of the card and just hide it. I would have to see the project to assess further, which I'd be happy to do.
     
  7. highlyinteractive

    highlyinteractive

    Joined:
    Sep 6, 2012
    Posts:
    116
    Haha - you'll have to take my word for it! Although here's another simple use case:

    You have a white square containing four small images loaded from Amazon.com. Two of the images are objects on a white background. Two are objects on a transparent background.

    If you fade the whole thing, it looks really ugly.
     
  8. brendan-vance

    brendan-vance

    Joined:
    Jan 16, 2014
    Posts:
    36
    Hrrm. I had actually assumed that CanvasGroup would do this for you; disappointing that it does not (although I can appreciate how difficult the problem is in 3D graphics land).

    Unity devs: Any plans to get this into a future release?
     
    highlyinteractive likes this.
  9. FamerJoe

    FamerJoe

    Joined:
    Dec 21, 2013
    Posts:
    193
    Yeah I get the application - but like I said, it seems unlikely that you just can't access what you need to access when you want to access it. Unity is all about doing just that!
     
  10. highlyinteractive

    highlyinteractive

    Joined:
    Sep 6, 2012
    Posts:
    116
    Oh sorry, my point with that example was that you wouldn't want to hide the images because they're part of the UI.

    I guess what I would need to do is draw the UI group to a buffer texture, then hide the original UI & fade the buffer.

    Side note: Is CanvasGroup part of the open source UI repo? I can't find it anywhere.
     
  11. FamerJoe

    FamerJoe

    Joined:
    Dec 21, 2013
    Posts:
    193
    Yup I understood the point, but in your situation, you actually could hide the image as a work around, but you said because your UI is complex you can't. I have some pretty complex UIs as well, and don't have any trouble accessing what I need to, so I just don't get it I guess.
     
  12. highlyinteractive

    highlyinteractive

    Joined:
    Sep 6, 2012
    Posts:
    116
    Right, well in that example, you have a white box with four images. When you fade it using CanvasGroup it looks weird because two of the images have alpha channels & two don't. So you either make a two-step animation where you fade out the images first, then fade out the white background, or you're stuck with a janky looking transition.

    Point is, it's not an issue of accessing the correct elements, it's having an intricate layout that you want to fade out all in one go, but doing so looks rubbish.
     
  13. Raimis

    Raimis

    Joined:
    Aug 27, 2014
    Posts:
    160
    OffTopic - Can you please tell me what blend mode did you use in flash to achieve that?
    OnTopic - I believe you can achieve that with rendertexture if you have pro (that what i used to do in flash - capture bitmap before alpha fading it)
     
    highlyinteractive likes this.
  14. highlyinteractive

    highlyinteractive

    Joined:
    Sep 6, 2012
    Posts:
    116
    Code (csharp):
    1. this.blendMode = BlendMode.LAYER;
    Annoyingly, it had been in Flash for *years* - I kicked myself when I found out about it!

    Yes, I think that's the simplest way. Any idea how to render a Canvas or UI element into a renderTexture?

    Edit: A quick search seems to suggest the Unity team were unable to get rendertexture's working with uGUI for 4.6.0. Not sure if this has been solved now, but I'll give it a go when I've got a bit more time.
     
    Last edited: Dec 15, 2014
  15. FamerJoe

    FamerJoe

    Joined:
    Dec 21, 2013
    Posts:
    193
    Yeah, at this point, I don't even know what your exact problem is -- I know what the solution that you desire is, but it doesn't appear if that available :) What about if you just fade IN an image over the top to cover whatever you are trying to fade for the same effect? Again, I'm not sure exactly what your trying to accomplish in your case, so it might not apply.
     
  16. highlyinteractive

    highlyinteractive

    Joined:
    Sep 6, 2012
    Posts:
    116


    My problem is that middle duck! I want that duck on the end :D

    Seriously, thanks for contributing, it's really helped me to think through the problem. The only reason I'm posting simple examples is to focus on solving the problem rather than working around it. I'll post again if I get any further with a solution.
     
    Tymianek and noio like this.
  17. FamerJoe

    FamerJoe

    Joined:
    Dec 21, 2013
    Posts:
    193
    Sometimes working around a problem IS solving it ;D
     
  18. BMayne

    BMayne

    Joined:
    Aug 4, 2014
    Posts:
    186
    Hey there,

    The good news is that this can be done. The bad news (or it could be) is that it would be done in a shader. A shader is what decides how your textures will blend.

    http://docs.unity3d.com/Manual/SL-Blend.html

    As you can see there is a lot of ways you can blend. Shaders can become very complicated and are hard to debug but they will give you the results you want.

    I would suggest taking a look at Unity's built in shader and molding it to your liking.

    Regards
     
  19. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    517
    Currently, the two elements are rendered separately with separate geometry. If one is semi-transparent, behind another is semi-transparent they will blend in some sort of blend operation (as mentioned by BMayne). To get them to blend as if they are one element, you need 1 layer of information. If it is truly as simple as the duck problem above, you could also try to use a sliced sprite to get the border to be the color you want.
     

    Attached Files:

  20. Darkcoder

    Darkcoder

    Joined:
    Apr 13, 2011
    Posts:
    3,414
    This issue is caused by drawing two transparent things on top of each other. Let's say you have a black background and draw a white box with 50% opacity, it will then draw a box with RGB 128,128,128. If you draw the same thing again then it will add 50% to the existing 50%, giving you RGB 191,191,191. This is because the shader blending is mixing the current pixel color with the new pixel color you want to add/blend, and has no knowledge of how many 'layers' you've drawn previously, or what colors they were.

    To get what you want, you either need to use one layer as Ferazel suggests, or you need to somehow store this layer information, e.g. a render texture.
     
  21. brendan-vance

    brendan-vance

    Joined:
    Jan 16, 2014
    Posts:
    36
    It may be possible to write a Unity GUI component that handles the caching of its children to one texture automatically. Indeed, CanvasGroup appears to be a native component whose code is not included in the Unity GUI source (perhaps because it does render-ish things on its backend...)

    It's also worth noting that if the Mask component were extended to use per-pixel alpha blending rather than a stencil, fading a group of graphics could be conveniently done that way.
     
    highlyinteractive likes this.
  22. Raimis

    Raimis

    Joined:
    Aug 27, 2014
    Posts:
    160
    You can indeed capture canvas into rendertexture, however you need a screenspace-camera or worldspace canvas for that. Furthermore, we were facing some additional problems with capturing it... we did a "background" capture - meaning the content that is not visible on screen, and we had to skip two frames after creation of the content for it to be properly captured. Hope this helps

    P.s. thanks for the tip on flash blend mode :) Not sure if I get to use it anymore, but i might :)
     
  23. Tymianek

    Tymianek

    Joined:
    May 16, 2015
    Posts:
    97
    Did you find the solution?
     
  24. highlyinteractive

    highlyinteractive

    Joined:
    Sep 6, 2012
    Posts:
    116
    I think I ended up with a convoluted system that dynamically swapped the UI with a captured render texture. It's really the only way to "flatten" layers