ue4

Widgetと画面遷移


フェードの実装

Widgetでフェードの実装をします。

Widgetの作成

フェード用のWidget(WBP_Fade)を作成します。BPは使用しません。
フェード用のイメージは分かりやすいように少し小さめです。
vatico

Widgetアクター (AWgFade.h)

C++からFadeを制御するためのクラスです。

WgFade.h

//=======================================================================
///  @file WgFade.h
///  @brief AWgFadeクラス
///  @author     inuvatico
///  @date        2021/04/02
///  @version     1.0
///  @copyright   2020 inuvatico
///  Released under the MIT license.
///    see https://opensource.org/licenses/MIT
///  @par (new/Add/Change : 2020/10/17) 
//=======================================================================

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "UI/WidgetBase.h"
#include "WgFade.generated.h"

UCLASS(Blueprintable, BlueprintType)
class AWgFade : public AWidgetBase
{
    GENERATED_BODY()

public: 
    AWgFade();
    static AWgFade* Create(UObject* Obj);

protected:
    virtual void BeginPlay() override;
    virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

public: 
    virtual void Tick(float DeltaTime) override;
    virtual bool OnAction(FString Action, int32 Param0, int32 Param1) override {
        UE_LOG(LogTemp, Log, TEXT("AWgFade:%s"), *Action);
        GEngine->AddOnScreenDebugMessage(-1, 5, FColor::Orange, FString::Printf(TEXT("ATestMenu:%s"), *Action));
        return true;
    }

    void SetColor(FLinearColor col);
    void StartFade(float TrgAlp = 0.0f,float Time = 2.5f);
    void SetCallBack(TFunction<void(void)> CallBackFunc);
private :
    UPROPERTY()
    UUserWidget* UserWidget;    
    float Timer;
    float MaxTime;
    float StartAlp;
    float EndAlp;

    TFunction<void(void)> CallBackFunc;
};

Widgetアクター (WgFade.cpp)

CreateとTickについて

Create

Createはウィジェットを作成します。
imageを取得して黒を設定しています。

Tick

Tickでフェードを処理します。
終了時にコールバックを処理します。

WgFade.cpp

//=======================================================================
///  @file WgFade.cpp
///  @brief フェードウィジェット
///  @author     inuvatico
///  @date        2021/04/02
///  @version     1.0
///  @copyright   2020 inuvatico
///  Released under the MIT license.
///    see https://opensource.org/licenses/MIT
///  @par (new/Add/Change : 2020/10/17) 
//=======================================================================
#include "WgFade.h"
#include "Res/ResDef.h"
#include "Components/Image.h"
#include "GameInstance/sub/GInstSubInstanceMng.h"
#include "UI/UIDef.h"

#pragma optimize("", off) 

//===============================================
// ウィジェットパーツの名前定義
//===============================================
#define WGFADE_IMAGE "ImageFabe"

//=====================================================
//! フェードウィジェットの作成
//=====================================================
AWgFade* AWgFade::Create(UObject* Obj)
{

    AWgFade* Wg = Cast<AWgFade>(UGInstSubInstanceMng::Get()->GetWidget(UIE_FADE, false));
    if (!Wg) {
        //ウィジェットアクターの登録
        Wg = Obj->GetWorld()->SpawnActor<AWgFade>(AWgFade::StaticClass());
        UGInstSubInstanceMng::Get()->SetWidget(UIE_FADE, Wg);
        // ウィジェットの読み込みと作成
        {
            FString path = UIR_FADE;
            TSubclassOf<class UUserWidget> WidgetClass;
            WidgetClass = TSoftClassPtr<UUserWidget>(FSoftObjectPath(*path)).LoadSynchronous();
            Wg->UserWidget = CreateWidget<UUserWidget>(Obj->GetWorld(), WidgetClass);
            Wg->UserWidget->AddToViewport(ZO_TOPFADE);
            //表示(ヒット通知を透過させない)
            Wg->UserWidget->SetVisibility(ESlateVisibility::Visible);

            FLinearColor col(1.f, 1.f, 1.f, 1.f);
            Wg->UserWidget->SetColorAndOpacity(col);
            {
                UImage* Image = Cast<UImage>(Wg->UserWidget->GetWidgetFromName(WGFADE_IMAGE));
                if (Image) {
                    FLinearColor col2(0.f, 0.f, 0.f, 1.f);
                    Image->SetColorAndOpacity(col2);
                }
            }
        }
    }
    return Wg;
}

//=====================================================
//! コンストラクタ
//=====================================================
AWgFade::AWgFade()
{
    PrimaryActorTick.bCanEverTick = true;
}

//=====================================================
//! BeginPlay
//=====================================================
void AWgFade::BeginPlay()
{
    Super::BeginPlay();
    PrimaryActorTick.bCanEverTick = true;

}

//=====================================================
//! EndPlay
//=====================================================
void AWgFade::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
    Super::EndPlay(EndPlayReason);
}

//=====================================================
//! 色設定
//=====================================================
void AWgFade::SetColor(FLinearColor col) {
    UserWidget->SetColorAndOpacity(col);
}

//=====================================================
//! フェード開始
//=====================================================
void AWgFade::StartFade(float TrgAlp, float Time) {
    Timer = Time;
    MaxTime = Time;

    UImage* Image = Cast<UImage>(UserWidget->GetWidgetFromName(WGFADE_IMAGE));
    StartAlp = Image->ColorAndOpacity.A;
    EndAlp = TrgAlp;

    SetActorTickEnabled(true);
    UserWidget->SetVisibility(ESlateVisibility::Visible);
}

//=====================================================
//! コールバックの設定
//=====================================================
void AWgFade::SetCallBack(TFunction<void(void)> Func) {
    CallBackFunc = Func;
}

//=====================================================
//! Tick
//=====================================================
void AWgFade::Tick(float DeltaTime)
{
    TFunction<void(void)> Func = nullptr;
    bool bEnd = false;

    Super::Tick(DeltaTime);

    Timer -= DeltaTime;
    if (Timer <= 0) {
        bEnd = true;
        Timer = 0;
        SetActorTickEnabled(false);
    }
    float Rate = Timer / MaxTime;
    UImage* Image = Cast<UImage>(UserWidget->GetWidgetFromName(WGFADE_IMAGE));
    Image->ColorAndOpacity.A = StartAlp + (EndAlp - StartAlp) * (1.0f - Rate);
    Image->SetColorAndOpacity(Image->ColorAndOpacity);
    //GEngine->AddOnScreenDebugMessage(-1, -1, FColor::Orange, FString::Printf(TEXT("AWgFade:%f"), Rate));

    if (bEnd) {
        if (Image->ColorAndOpacity.A <= 0) {
            UserWidget->SetVisibility(ESlateVisibility::Hidden); //非表示          
        }else {
            UserWidget->SetVisibility(ESlateVisibility::Visible); //表示          
        }
        Func = CallBackFunc;
        CallBackFunc = nullptr;
        if (Func) {
            Func();
        }
    }
}

ResDef.h

//=========================================================
// UIリソースと登録名の定義
//========================================================= 
#define UIR_TEST_MENU "/Game/00PRJ/UI/Test/WBP_TestMenu.WBP_TestMenu_C" //!< テスト用のボタン
#define UIE_TEST_MENU "TestMenu" //登録名
#define UIR_FADE "/Game/00PRJ/UI/Fade/WBP_Fade.WBP_Fade_C"//!< フェード用ウィジェット
#define UIE_FADE "Fade"//登録名

UiDef.h

//---------------------------------------------------
///ウィジェットの描画順番 
/// 値が大きい程、後に描画される
//---------------------------------------------------
enum {
    ZO_TOPFADE = 101,
    ZO_MENU = 100
};
prev/next







digitalize
  始めました。