0 votes

The question is actually asked in Stackoverflow but migrated it here since this seems the main QA platform for Godot.

It's actually a simple issue but it's driving me crazy because of its simplicity. I just want to fade in when I load a scene and then fade out whenever I click a button. As to how I do that, this is the video about it.

To sum up, I load another scene called "Fader" which contains a ColorRect with a black color and AnimationPlayer to change ColorRect's alpha value.

The code is below with extra comments on relevant parts:

using Godot;
using System;

public class TitleScreen : Control
{
    private Button[] buttons;
    private Control fader;  // the scene that I inject

    public override void _Ready()  // when title screen gets ready
    {
        GD.Print("Preparing TitleScreen...");
        InitButtons();
        InitFader();  // initialize fader
        FadeIn();  // do fade in animation
    }

    private void InitFader()  // initializing fader
    {
        GD.Print("Initializing fader...");
        var faderScene = (PackedScene)ResourceLoader.Load("res://components/Fader.tscn");  // load external fader scene
        fader = (Control)faderScene.Instance();  // instantiate the scene
        fader.SetSize(OS.WindowSize);  // set the size of fader scene to the game window, just in case
        var rect = (ColorRect)fader.GetNode("rect");  // get "rect" child from fader scene
        rect.SetSize(OS.WindowSize);  // set "rect" size to the game window as well, just in case
        fader.Visible = false;  // set the visibility to false
        AddChild(fader);  // add initialized fader scene as a child of title screen
    }

    private void InitButtons()
    {
        GD.Print("Initializing buttons...");
        buttons = new Button[3]{
            (Button)GetNode("menu_container/leftmenu_container/menu/start_button"),
            (Button)GetNode("menu_container/leftmenu_container/menu/continue_button"),
            (Button)GetNode("menu_container/leftmenu_container/menu/exit_button"),
        };

        GD.Print("Adding events to buttons...");
        buttons[0].Connect("pressed", this, "_StartGame");
        buttons[2].Connect("pressed", this, "_QuitGame");
    }

    private void FadeIn()
    {
        GD.Print("Fading in...");
        fader.Visible = true;  // set visibility of fader to true
        var player = (AnimationPlayer)fader.GetNode("player");  // get animation player
        player.Play("FadeIn");  // play FadeIn animation
        fader.Visible = false;  // set visibility of fader to false
    }

    private void FadeOut()
    {
        // similar to FadeIn
        GD.Print("Fading out...");
        fader.Visible = true;
        var player = (AnimationPlayer)fader.GetNode("player");
        player.Play("FadeOut");
        fader.Visible = false;
    }

    public void _StartGame()  // whenever I click start game button
    {
        FadeOut();  // fade out
        GetTree().ChangeScene("res://stages/Demo01.tscn");
    }

    public void _QuitGame()  // whenever I click quit game button
    {
        FadeOut();  // fade out
        GetTree().Quit();
    }
}

Seems like I can't see something. Why does it not fade in and out?


Environment

  • Manjaro 19.0.2
  • Mono JIT Compiler 6.4.0 (if it is relevant)
  • Godot 3.2
in Engine by (18 points)

1 Answer

+2 votes

Why does it not fade in and out?

It does. You just can't see it. ;) Your code makes the fader visible, starts the animation and then makes the fader invisible directly after. It does not wait for the animation to finish. You could connect to the animation_finished-signal. Or you simply include the change in visibility in the animation itself, as a separate property track.

by (10,329 points)

Oh, so animation runs async huh? Wow man, I didn't know that, let me try that.

First, thank you, I created a C# script for Fader which sets visibility on animation_started and animation_finished signals. This, very well, works while fading in. However, it does not do that while it fades out. I guess the reason is AnimationPlayer plays the animations async (?), does not wait for it to play and changes the scene immediately. It solved half the problem though, so thank you. All is left to me to solve the other half myself now that I understand what's really going on.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.