六一的部落格


关关难过关关过,前路漫漫亦灿灿。



Open Level


说明

在游戏结束窗口添加按钮, 点击则重启关卡


API导航


UserWidget

  1. 初始化时调用

    1virtual bool Initialize();
     1bool UUserWidget::Initialize()
     2{
     3    // If it's not initialized initialize it, as long as it's not the CDO, we never initialize the CDO.
     4    if (!bInitialized && !HasAnyFlags(RF_ClassDefaultObject))
     5    {
     6        // If this is a sub-widget of another UserWidget, default designer flags and player context to match those of the owning widget
     7        if (UUserWidget* OwningUserWidget = GetTypedOuter<UUserWidget>())
     8        {
     9#if WITH_EDITOR
    10            SetDesignerFlags(OwningUserWidget->GetDesignerFlags());
    11#endif
    12            SetPlayerContext(OwningUserWidget->GetPlayerContext());
    13        }
    14
    15        UWidgetBlueprintGeneratedClass* BGClass = Cast<UWidgetBlueprintGeneratedClass>(GetClass());
    16        // Only do this if this widget is of a blueprint class
    17        if (BGClass)
    18        {
    19            BGClass->InitializeWidget(this);
    20        }
    21        else
    22        {
    23            InitializeNativeClassData();
    24        }
    25
    26        if ( WidgetTree == nullptr )
    27        {
    28            WidgetTree = NewObject<UWidgetTree>(this, TEXT("WidgetTree"), RF_Transient);
    29        }
    30        else
    31        {
    32            WidgetTree->SetFlags(RF_Transient);
    33
    34            InitializeNamedSlots();
    35        }
    36
    37        if (!IsDesignTime() && PlayerContext.IsValid())
    38        {
    39            NativeOnInitialized();
    40        }
    41
    42        bInitialized = true;
    43        return true;
    44    }
    45
    46    return false;
    47}
  2. 在Initialize最后调用

    不用考虑自定义操作与调用基类Initialize的先后顺序

    1virtual void NativeOnInitialized();

GameplayStatics

  1. 重启关卡

    会重新创建对象, 重置定时器等

    被称作硬重启 Hard Reset

    1/**
    2​ * Travel to another level
    3 *
    4​ * @param	LevelName			the level to open
    5​ * @param	bAbsolute			if true options are reset, if false options are carried over from current level
    6​ * @param	Options				a string of options to use for the travel URL
    7 */
    8UFUNCTION(BlueprintCallable, meta=(WorldContext="WorldContextObject", AdvancedDisplay = "2", DisplayName = "Open Level (by Name)"), Category="Game")
    9static void OpenLevel(const UObject* WorldContextObject, FName LevelName, bool bAbsolute = true, FString Options = FString(TEXT("")));
  2. 获取当前关卡名

    1/**
    2​ * Get the name of the currently-open level.
    3 *
    4​ * @param bRemovePrefixString	remove any streaming- or editor- added prefixes from the level name.
    5 */
    6UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", AdvancedDisplay = "1"), Category = "Game")
    7static FString GetCurrentLevelName(const UObject* WorldContextObject, bool bRemovePrefixString = true);

GameModeBase

被称作软重启 Soft Reset , 默认会对场景中的所有Actor调用Reset, 同时也留有自由操作空间. 我们可以不用重新创建所有对象

1/**
2 * Overridable function called when resetting level. This is used to reset the game state while staying in the same map
3 * Default implementation calls Reset() on all actors except GameMode and Controllers
4 */
5UFUNCTION(BlueprintCallable, Category=Game)
6virtual void ResetLevel();

在STUGameOverWidget中添加重启逻辑


添加属性: 按钮

ShootThemUp: UI/STUGameOverWidget.h

1class UButton;
2
3UPROPERTY(meta = (BindWidget))
4UButton *ResetLevelButton;

添加按钮点击时回调函数

private

ShootThemUp: UI/STUGameOverWidget.h

1UFUNCTION()
2void OnResetLevel();

ShootThemUp: UI/STUGameOverWidget.cpp

1#include "Kismet/GameplayStatics.h"
2#include "Components/Button.h"
3
4void USTUGameOverWidget::OnResetLevel()
5{
6    const auto CurrentLevelName = UGameplayStatics::GetCurrentLevelName(GetWorld()); /* DefaultMap */
7
8    UGameplayStatics::OpenLevel(GetWorld(), FName(CurrentLevelName));
9}

覆写NativeOnInitialized

protected

ShootThemUp: UI/STUGameOverWidget.h

1virtual void NativeOnInitialized() override;

可以把所有Initialize替换成NativeOnInitialized, 不作演示

ShootThemUp: UI/STUGameOverWidget.cpp

1void USTUGameOverWidget::NativeOnInitialized()
2{
3    Super::NativeOnInitialized();
4
5    if (ResetLevelButton)
6    {
7        ResetLevelButton->OnClicked.AddDynamic(this, &USTUGameOverWidget::OnResetLevel);
8    }
9}

修改WBP_GameOverWidget

  1. 修改WBP_PauseWidget: 鼠标悬浮在按钮之上时的光标图形


  2. 拷贝WBP_PauseWidget中按钮所属大小盒


  3. 添加分隔符


  4. 粘贴大小盒


    这里出现了问题, 粘贴得到的是按钮

    修改文本


    修改按钮变量名



查看


鼠标悬浮在按钮上时, 可以看见手形光标

可以正常重启关卡


重启关卡


Open Level


说明

在游戏结束窗口添加按钮, 点击则重启关卡


API导航


UserWidget

  1. 初始化时调用

    1virtual bool Initialize();
     1bool UUserWidget::Initialize()
     2{
     3    // If it's not initialized initialize it, as long as it's not the CDO, we never initialize the CDO.
     4    if (!bInitialized && !HasAnyFlags(RF_ClassDefaultObject))
     5    {
     6        // If this is a sub-widget of another UserWidget, default designer flags and player context to match those of the owning widget
     7        if (UUserWidget* OwningUserWidget = GetTypedOuter<UUserWidget>())
     8        {
     9#if WITH_EDITOR
    10            SetDesignerFlags(OwningUserWidget->GetDesignerFlags());
    11#endif
    12            SetPlayerContext(OwningUserWidget->GetPlayerContext());
    13        }
    14
    15        UWidgetBlueprintGeneratedClass* BGClass = Cast<UWidgetBlueprintGeneratedClass>(GetClass());
    16        // Only do this if this widget is of a blueprint class
    17        if (BGClass)
    18        {
    19            BGClass->InitializeWidget(this);
    20        }
    21        else
    22        {
    23            InitializeNativeClassData();
    24        }
    25
    26        if ( WidgetTree == nullptr )
    27        {
    28            WidgetTree = NewObject<UWidgetTree>(this, TEXT("WidgetTree"), RF_Transient);
    29        }
    30        else
    31        {
    32            WidgetTree->SetFlags(RF_Transient);
    33
    34            InitializeNamedSlots();
    35        }
    36
    37        if (!IsDesignTime() && PlayerContext.IsValid())
    38        {
    39            NativeOnInitialized();
    40        }
    41
    42        bInitialized = true;
    43        return true;
    44    }
    45
    46    return false;
    47}
  2. 在Initialize最后调用

    不用考虑自定义操作与调用基类Initialize的先后顺序

    1virtual void NativeOnInitialized();

GameplayStatics

  1. 重启关卡

    会重新创建对象, 重置定时器等

    被称作硬重启 Hard Reset

    1/**
    2​ * Travel to another level
    3 *
    4​ * @param	LevelName			the level to open
    5​ * @param	bAbsolute			if true options are reset, if false options are carried over from current level
    6​ * @param	Options				a string of options to use for the travel URL
    7 */
    8UFUNCTION(BlueprintCallable, meta=(WorldContext="WorldContextObject", AdvancedDisplay = "2", DisplayName = "Open Level (by Name)"), Category="Game")
    9static void OpenLevel(const UObject* WorldContextObject, FName LevelName, bool bAbsolute = true, FString Options = FString(TEXT("")));
  2. 获取当前关卡名

    1/**
    2​ * Get the name of the currently-open level.
    3 *
    4​ * @param bRemovePrefixString	remove any streaming- or editor- added prefixes from the level name.
    5 */
    6UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", AdvancedDisplay = "1"), Category = "Game")
    7static FString GetCurrentLevelName(const UObject* WorldContextObject, bool bRemovePrefixString = true);

GameModeBase

被称作软重启 Soft Reset , 默认会对场景中的所有Actor调用Reset, 同时也留有自由操作空间. 我们可以不用重新创建所有对象

1/**
2 * Overridable function called when resetting level. This is used to reset the game state while staying in the same map
3 * Default implementation calls Reset() on all actors except GameMode and Controllers
4 */
5UFUNCTION(BlueprintCallable, Category=Game)
6virtual void ResetLevel();

在STUGameOverWidget中添加重启逻辑


添加属性: 按钮

ShootThemUp: UI/STUGameOverWidget.h

1class UButton;
2
3UPROPERTY(meta = (BindWidget))
4UButton *ResetLevelButton;

添加按钮点击时回调函数

private

ShootThemUp: UI/STUGameOverWidget.h

1UFUNCTION()
2void OnResetLevel();

ShootThemUp: UI/STUGameOverWidget.cpp

1#include "Kismet/GameplayStatics.h"
2#include "Components/Button.h"
3
4void USTUGameOverWidget::OnResetLevel()
5{
6    const auto CurrentLevelName = UGameplayStatics::GetCurrentLevelName(GetWorld()); /* DefaultMap */
7
8    UGameplayStatics::OpenLevel(GetWorld(), FName(CurrentLevelName));
9}

覆写NativeOnInitialized

protected

ShootThemUp: UI/STUGameOverWidget.h

1virtual void NativeOnInitialized() override;

可以把所有Initialize替换成NativeOnInitialized, 不作演示

ShootThemUp: UI/STUGameOverWidget.cpp

1void USTUGameOverWidget::NativeOnInitialized()
2{
3    Super::NativeOnInitialized();
4
5    if (ResetLevelButton)
6    {
7        ResetLevelButton->OnClicked.AddDynamic(this, &USTUGameOverWidget::OnResetLevel);
8    }
9}

修改WBP_GameOverWidget

  1. 修改WBP_PauseWidget: 鼠标悬浮在按钮之上时的光标图形


  2. 拷贝WBP_PauseWidget中按钮所属大小盒


  3. 添加分隔符


  4. 粘贴大小盒


    这里出现了问题, 粘贴得到的是按钮

    修改文本


    修改按钮变量名



查看


鼠标悬浮在按钮上时, 可以看见手形光标

可以正常重启关卡