目标任务:
1.重新实现切换关卡页面显示并打包后没问题
2.设置trigger切换关卡到探索地图里
3.写一个Actor类用于收集物品:trigger函数,骨骼网格体组件,SphereCollision组件
4.笔试题的算法复习
1 重构后GameInstance代码
思路:通过封装LoadStreamLevel和UnLoad管理,并实现Transition面板动画的播放和实现逻辑,Load的回调绑定本类中的OnLevelLoaded(),因为是流式管理关卡,所以GetMap()返回结果一直是Manager,所以自定义了CurrentLevelName和LastLevelName管理。
#include "GameInstance/MyGameInstance.h"
#include "GameFramework/GameUserSettings.h"
#include "MediaSource.h"
#include "MediaPlayer.h"
#include "MediaTexture.h"
#include "NavigationSystem.h"
#include "NavigationSystemTypes.h"#include "Blueprint/UserWidget.h"
#include "Engine/StreamableManager.h"
#include "Kismet/GameplayStatics.h"
#include "UI/MyStartMenuUI.h"
#include "Engine/LevelStreamingDynamic.h"
#include "GameFramework/GameModeBase.h"
#include "Player/MyPlayerController.h"
#include "GameFramework/GameModeBase.h"
#include "Manager/MySaveManager.h"
#include "Player/MyPlayerData.h"
#include "UI/MyTransitionWidget.h"void UMyGameInstance::Init()
{Super::Init();UE_LOG(LogTemp,Warning,TEXT("GameInstance-->OnInit"))/*GEngine->GetGameUserSettings()->SetFullscreenMode(EWindowMode::Windowed);GEngine->GetGameUserSettings()->SetScreenResolution(FIntPoint(1600, 900));GEngine->GetGameUserSettings()->ApplySettings(true);*/CurrentLevelName=FString("Manager");LastLevelName=FString("Manager");/*UWorld* World = GetWorld();if (World){// 获取加载的流式关卡对象TArray<ULevelStreaming*> LevelStreaming = World->GetStreamingLevels();for(ULevelStreaming* Level : LevelStreaming){Level->OnLevelLoaded.AddDynamic(this, &UMyGameInstance::OnLevelLoaded);}}*/
}void UMyGameInstance::ShowStartMenu()
{UE_LOG(LogTemp,Warning,TEXT("OnShowMainMenuPersistent--Start"));if (!StartMenuWidget){StartMenuWidget = CreateWidget<UMyStartMenuUI>(UGameplayStatics::GetPlayerController(GetWorld(),0), StartMenuWidgetClass);if(StartMenuWidget&& !StartMenuWidget->IsInViewport()){StartMenuWidget->AddToViewport();UE_LOG(LogTemp,Warning,TEXT("Create a new StartMenuWidget,and Added To Viewport"));}if(StartMenuWidget){UE_LOG(LogTemp,Warning,TEXT("OnShowMainMenuPersistent,StartMenuWidget->IsInViewport()==%d"),StartMenuWidget->IsInViewport());}else{UE_LOG(LogTemp,Warning,TEXT("OnShowMainMenuPersistent,StartMenuWidget->Is not valid"));}}else{StartMenuWidget->AddToViewport();UE_LOG(LogTemp,Warning,TEXT("StartMenuWidget is Valid,Added To Viewport"));}UE_LOG(LogTemp,Warning,TEXT("OnShowMainMenuPersistent-->End"));
}void UMyGameInstance::LoadMapByMyOwnName(FString& MapName)const
{UE_LOG(LogTemp,Warning,TEXT("UMyGameInstance::LoadMapByMyOwnName"));FLatentActionInfo LatentInfo;LatentInfo.UUID = FMath::Rand(); // 随机生成一个唯一的IDLatentInfo.Linkage = 0; // 通常设置为0LatentInfo.CallbackTarget=const_cast<UMyGameInstance*>(this);LatentInfo.ExecutionFunction = TEXT("OnLevelLoaded");if(MapName.Equals(MyMainString)){UGameplayStatics::LoadStreamLevelBySoftObjectPtr(GetWorld(),MyMainLevel , true, false, LatentInfo);}else if(MapName.Equals(StartMenuString)){UGameplayStatics::LoadStreamLevelBySoftObjectPtr(GetWorld(),StartLevel , true, true, LatentInfo);}else if(MapName.Equals(Level1String)){UGameplayStatics::LoadStreamLevelBySoftObjectPtr(GetWorld(),Level1 , true, false, LatentInfo);}else{UE_LOG(LogTemp,Warning,TEXT("UMyGameInstance::LoadMapByMyOwnName-->Error!"));}
}
void UMyGameInstance::UnLoadMapByMyOwnName(FString& MapName)const
{if(MapName.Equals(MyMainString)){UGameplayStatics::UnloadStreamLevelBySoftObjectPtr(GetWorld(),MyMainLevel , FLatentActionInfo(),false);}else if(MapName.Equals(StartMenuString)){UGameplayStatics::UnloadStreamLevelBySoftObjectPtr(GetWorld(),StartLevel , FLatentActionInfo(),false);}else if(MapName.Equals(Level1String)){UGameplayStatics::UnloadStreamLevelBySoftObjectPtr(GetWorld(),Level1 , FLatentActionInfo(),false);}else if(MapName.Equals(FString("Manager"))){UE_LOG(LogTemp,Warning,TEXT("UMyGameInstance::UnLoadMapByMyOwnName-->Manager!"));}else{UE_LOG(LogTemp,Warning,TEXT("UMyGameInstance::UnLoadMapByMyOwnName-->Error!"));}
}
void UMyGameInstance::OnLevelLoaded()
{UE_LOG(LogTemp, Warning, TEXT("GameInstance->OnLevelLoaded"));UWorld* World=GetWorld();AMyPlayerController* MyPlayerController=Cast<AMyPlayerController>(UGameplayStatics::GetPlayerController(World,0));if(CurrentLevelName.Equals(StartMenuString)){ShowStartMenu();if(MyPlayerController){MyPlayerController->GetPawn()->SetActorLocation(FVector(200, 200, 200));}else{UE_LOG(LogTemp, Warning, TEXT("GameInstance->OnLevelLoaded-->MyPlayerController is not Valid"));}}else if(CurrentLevelName.Equals(MyMainString)){if(MyPlayerController){MyPlayerController->GetPawn()->SetActorLocation(FVector(-2336, 1152, 102));}else{UE_LOG(LogTemp, Warning, TEXT("GameInstance->OnLevelLoaded-->MyPlayerController is not Valid"));}StartMenuWidget->RemoveFromParent();}if(MyPlayerController){MyPlayerController->OnLevelLoaded(CurrentLevelName);}UnLoadMapByMyOwnName(LastLevelName);if(TransitionWidget){UE_LOG(LogTemp, Warning, TEXT("GameInstance->OnLevelLoaded-->TransitionWidget is InViewPort:%d"),TransitionWidget->IsInViewport());TransitionWidget->PlayTransitionOut();//数据都处理完之后播放淡出动画}
}void UMyGameInstance::ShowTransitionWidget()
{TransitionWidget = CreateWidget<UMyTransitionWidget>(GetWorld(), TransitionWidgetClass);if (TransitionWidget){// 注册回调,等进入动画播放完成后会广播,此处响应委托TransitionWidget->OnFTransitionInFinishedDelegate.AddDynamic(this, &UMyGameInstance::OnTransitionInFinished);TransitionWidget->OnFTransitionOutFinishedDelegate.AddDynamic(this, &UMyGameInstance::OnTransitionOutFinished);TransitionWidget->AddToViewport();TransitionWidget->PlayTransitionIn();//UE_LOG(LogTemp, Warning, TEXT("Show Transition Widget"));}
}void UMyGameInstance::HideTransitionWidget()
{if (TransitionWidget){TransitionWidget->RemoveFromParent();UE_LOG(LogTemp,Warning,TEXT("HideTransitionWidget"));}
}void UMyGameInstance::SwitchLevelWithTransition(const FString& LevelName)
{LastLevelName=CurrentLevelName;CurrentLevelName=LevelName;bool bIsShowTransition { !(LastLevelName.Equals(ManagerString)&&CurrentLevelName.Equals(StartMenuString)) };UE_LOG(LogTemp,Warning,TEXT("UMyGameInstance::SwitchLevelWithTransition,CurrentLevelName==%s,bIsShowTransition==%d"),*CurrentLevelName,bIsShowTransition);if(bIsShowTransition){ShowTransitionWidget();//TransitionIn动画的结束回调会加载关卡}else{LoadMapByMyOwnName(CurrentLevelName);}
}void UMyGameInstance::OnTransitionInFinished()
{LoadMapByMyOwnName(CurrentLevelName);
}void UMyGameInstance::OnTransitionOutFinished()
{HideTransitionWidget();
}void UMyGameInstance::OnStart()
{Super::OnStart();UE_LOG(LogTemp,Warning,TEXT("GameInstance-->OnStart"));//SwitchLevelWithTransition(FString("StartMenu"));//ShowStartMenu();}