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
  4. Dismiss Notice

Question Screen Fade In and Out

Discussion in 'UI Toolkit' started by ShokWayve, Jul 11, 2023.

  1. ShokWayve

    ShokWayve

    Joined:
    Jan 16, 2013
    Posts:
    122
    Greetings,

    What is the recommended way to do screen fade ins and out? I tried to do it using pseudo classes but I could not find a pseudo class that corresponded to when the screen is made active or inactive.

    I was going to use it doing c#, but I am trying to figure out how to access the background color of the screen - a visual element - in code, how to change it, and if that method is performant.

    Any help would be greatly appreciated.

    Thank you.
     
  2. Christopher412

    Christopher412

    Joined:
    May 26, 2023
    Posts:
    7
    I've had good success doing this with css/uss transitions.

    Have an element non visible through alpha set to 0 in uss.

    Then have a uss class with alpha set to 1, the right transisions set, and then just:

    element.AddToClassList("fade-in");
     
  3. ShokWayve

    ShokWayve

    Joined:
    Jan 16, 2013
    Posts:
    122
    What psuedo class would you use for the fade in? I tried enabled but that doesn't work.

    I am trying to change visibility of the screen's root visual element to fade in the screen and fade it out.

    Thanks also for your reply. I think your strategy might work if I can find the right pseudo class.

    If doing it through C#, is the "element" in your example on the visual element?
     
  4. JasonsFreeTime

    JasonsFreeTime

    Joined:
    May 23, 2015
    Posts:
    31
    Here's one way I'm guessing it could be done via script to transition the screen from on layout to another. Assume your top level VisualElement in the layout is called "Container" on both the layouts.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Threading.Tasks;
    3. using UnityEngine;
    4. using UnityEngine.UIElements;
    5.  
    6. public class Layout_Transition : MonoBehaviour
    7. {
    8.     public VisualTreeAsset layout2;
    9.     public bool doFade;
    10.     UIDocument doc;
    11.     VisualElement root;
    12.     VisualElement container;
    13.  
    14.     void OnEnable()
    15.     {
    16.         doc = GetComponent<UIDocument>();
    17.         root = doc.rootVisualElement;
    18.         container = root.Q("Container");
    19.     }
    20.  
    21.     void Update()
    22.     {
    23.         if (doFade)
    24.         {
    25.             doFade = false;
    26.             container.style.opacity = 1;
    27.             FadeOut();
    28.         }
    29.     }
    30.  
    31.     async void FadeOut()
    32.     {
    33.         while (container.style.opacity.value > 0)
    34.         {
    35.             float opacity = container.style.opacity.value - 0.05f;
    36.             Mathf.Clamp(opacity, 0, 1);
    37.             container.style.opacity = opacity;
    38.             await Task.Delay(100);
    39.         }
    40.         FadeIn();
    41.     }
    42.  
    43.     async void FadeIn()
    44.     {
    45.         doc.visualTreeAsset = layout2;
    46.         root = doc.rootVisualElement;
    47.         container = root.Q("Container");
    48.  
    49.         while (container.style.opacity.value < 1)
    50.         {
    51.             float opacity = container.style.opacity.value + 0.05f;
    52.             Mathf.Clamp(opacity, 0, 1);
    53.             container.style.opacity = opacity;
    54.             await Task.Delay(100);
    55.         }
    56.     }
    57. }
    58.  
    But, let me know what you come up with.
    FYI - I'm just learning this UI Toolkit now. There is a great course on Udemy from David Makowski that covers all the basics. I highly recommend it! You can find a link to it with a discount from his youtube channel called MadCat tutorials.
     
  5. ShokWayve

    ShokWayve

    Joined:
    Jan 16, 2013
    Posts:
    122
    Thanks. Your approach definitely seems like it would work. Also thanks for the reference to the Udemy course. My only question is that one of the Unity Devs said that doing it through USS and UXML is more performant and the recommended way to do it. Nonetheless, I will definitely keep this method in mind. I will also report back on any solution I find.
     
  6. Christopher412

    Christopher412

    Joined:
    May 26, 2023
    Posts:
    7
    Have an element with the uss class .container. The code just adds a class OnEnable. This is what I meant earlier. And it should be what you're referring to in regards to using UXML/USS.

    USS
    .container {
    opacity: 0;
    }
    .fade-in {
    opacity: 1;
    transition-duration: 0.5s;
    transition-property: opacity;
    }


    Pseudo code:
    public class FadeTest : MonoBehaviour
    {
    void OnEnable() {
    // Need to wait for creation before animating stuff
    doc.rootVisualElement.RegisterCallback<GeometryChangedEvent>(_ => doc.rootVisualElement.Q("container").AddToClassList("fade-in"));
    }
    }
     
  7. JasonsFreeTime

    JasonsFreeTime

    Joined:
    May 23, 2015
    Posts:
    31
    Okay, I diddn't know about transitions. That works pretty well. So if I want to toggle fade out and fade in, (and I'm not doing anything to change the layout) I'm doing this:
    Code (CSharp):
    1.  
    2.     void FadeIn()
    3.     {
    4.         container.AddToClassList("fade-in");
    5.         container.RemoveFromClassList("fade-out");
    6.     }
    7.  
    8.     void FadeOut()
    9.     {
    10.         container.AddToClassList("fade-out");
    11.         container.RemoveFromClassList("fade-in");
    12.     }
    Where the uss is like this:

    Code (CSharp):
    1.  
    2. .container {
    3.     opacity: 1;
    4. }
    5.  
    6. .fade-in {
    7.     opacity: 1;
    8.     transition-property: opacity;
    9.     transition-duration: 0.5s;
    10.     transition-timing-function: linear;
    11. }
    12.  
    13. .fade-out {
    14.     opacity: 0;
    15.     transition-property: opacity;
    16.     transition-duration: 0.5s;
    17.     transition-timing-function: linear;
    18. }
    19.  
    This works very smoothly. I'm just wondering if the RemoveFromClassList() causes any problems if the class has not been added? It doesn't seem to.
     
  8. Spikebor

    Spikebor

    Joined:
    May 30, 2019
    Posts:
    270
    Weird, I did everything @JasonsFreeTime said,

    USS code
    Code (CSharp):
    1. .fade-in {
    2.     opacity: 1;
    3.     transition-property: opacity;
    4.     transition-duration: 1s;
    5.     transition-timing-function:ease;
    6. }
    7.  
    8. .fade-out {
    9.     opacity: 0;
    10.     transition-property: opacity;
    11.     transition-duration: 1s;
    12.     transition-timing-function:ease;
    13. }
    made helper static methods for ease of use:
    Code (CSharp):
    1.         public static void FadeIn(this VisualElement v) {
    2.             v.AddToClassList("fade-in");
    3.             v.RemoveFromClassList("fade-out");
    4.         }
    5.         public static void FadeOut(this VisualElement v)
    6.         {
    7.             v.AddToClassList("fade-out");
    8.             v.RemoveFromClassList("fade-in");
    9.         }
    10.  
    In use:
    Code (CSharp):
    1.             public void ShowAlert(string m, float dur)
    2.             {
    3.                 alertLabel.text = m;
    4.                 alert.FadeIn();
    5.             }
    6.  
    7.         public void HideAlert()
    8.             {
    9.                 alert.FadeOut();
    10.             }
    But no fading happens.

    But, if I setup in code, the element can fade.
    Code (CSharp):
    1.                
    2.                 alert.style.opacity = 0;
    3.                 alert.style.transitionProperty = new List<StylePropertyName> { "opacity" };
    4.                 alert.style.transitionDuration = new List<TimeValue> { new TimeValue(1f, TimeUnit.Second) };
    5.                 alert.style.transitionTimingFunction = new List<EasingFunction> { EasingMode.Ease };
    6.  
    Then each time I want to fade in: alert.style.opacity = 1;
    fade out: alert.style.opacity = 0;
    and the transition will auto run.
     
    Last edited: Jul 17, 2023
  9. Christopher412

    Christopher412

    Joined:
    May 26, 2023
    Posts:
    7
    Make sure you don't have inline styles set on the fading element, those will override classes.
     
  10. JasonsFreeTime

    JasonsFreeTime

    Joined:
    May 23, 2015
    Posts:
    31
    That was going to be my advice as well. I wonder if having that code amounts to being inline property applied and overriding the classes? Maybe make sure to comment out that code.
    I just happened to be reviewing selector precedence in that Udemy course and these are my notes:

    Selector Precedence

    • The Type selector has lowest precedence because there will likely be many elements with the same type (such as all VisualElements or all Labels or all Buttons, ect.)

    • The Class selector has a higher precedence than the Type selector because you can of course have multiple elements with the same class.

    • The Id selector has a higher precedence than the Class selector because its unlikely that you will name many elements with the same name. (Recommended to avoid naming multiple elements with the same name)

    • Style properties applied to the element itself are called Inline style properties and will override all other properties, so it has the highest precedence.
     
  11. Spikebor

    Spikebor

    Joined:
    May 30, 2019
    Posts:
    270
    I only write the code to setup styles after I used AddToClassList and RemoveFromClassList with no result though. So that's what I'm currently use, kinda happy with it. Since the use case code is simpler: just set opacity. But this of course does not account to more complex styles.