重启关卡
2023年11月24日 2024年1月11日
Open Level
说明
在游戏结束窗口添加按钮, 点击则重启关卡
API导航
UserWidget
-
初始化时调用
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}
-
在Initialize最后调用
不用考虑自定义操作与调用基类Initialize的先后顺序1virtual void NativeOnInitialized();
GameplayStatics
-
重启关卡
会重新创建对象, 重置定时器等被称作硬重启
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("")));
-
获取当前关卡名
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
-
修改WBP_PauseWidget: 鼠标悬浮在按钮之上时的光标图形
-
拷贝WBP_PauseWidget中按钮所属大小盒
-
添加分隔符
-
粘贴大小盒
这里出现了问题, 粘贴得到的是按钮
修改文本
修改按钮变量名
查看
鼠标悬浮在按钮上时, 可以看见手形光标
可以正常重启关卡