新建空場景
設置爲默認的GameMode
新建三個C++類
-
繼承:SaveGame
命名:SaveGame_Main -
繼承:UserWidget
命名:UserWidget_OpenCount
新建藍圖Widget,繼承UserWidget,添加"Text"組件 -
繼承:Actor
命名:Actor_GameController
拖進兩個場景中,設置參數
SaveGame_Main.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/SaveGame.h"
#include "SaveGame_Main.generated.h"
/**
*
*/
UCLASS()
class MAP_CLIENT_API USaveGame_Main : public USaveGame
{
GENERATED_BODY()
public:
UPROPERTY() // 必須加UPROPERTY()
int OpenCount;
};
UserWidget_OpenCount.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "TextBlock.h"
#include "UserWidget_OpenCount.generated.h"
/**
*
*/
UCLASS()
class MAP_SERVER_API UUserWidget_OpenCount : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(Meta = (BindWidget))
UTextBlock* Text_OpenCount;
};
Actor_GameController.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Actor_GameController.generated.h"
class UUserWidget_OpenCount;
class USaveGame_Main;
UCLASS()
class MAP_CLIENT_API AActor_GameController : public AActor
{
GENERATED_BODY()
private:
UPROPERTY(EditAnywhere, Category = "Actor_GameController")
FName EmptyLevelName = TEXT("EmptyMap");
UPROPERTY(EditAnywhere, Category = "Actor_GameController|Count(Exclusive)")
int MaxOpenCount = 20;
UPROPERTY(EditAnywhere, Category = "Actor_GameController|Time (Exclusive)")
int32 MaxYear = 2020;
UPROPERTY(EditAnywhere, Category = "Actor_GameController|Time (Exclusive)")
int8 MaxMonth = 5;
UPROPERTY(EditAnywhere, Category = "Actor_GameController|Time (Exclusive)")
int8 MaxDay = 9;
UUserWidget_OpenCount* WB_OpenCount;
USaveGame_Main* SaveGame_Main;
public:
AActor_GameController();
protected:
virtual void BeginPlay() override;
virtual void Tick(float DeltaSeconds) override;
};
Actor_GameController.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Actor_GameController.h"
#include "Kismet/GameplayStatics.h"
#include "SaveGame_Main.h"
#include "Helper.h"
#include "UserWidget_OpenCount.h"
#include "Paths.h"
#include "PlatformFilemanager.h"
#include "GenericPlatform/GenericPlatformFile.h"
#include "AllowWindowsPlatformTypes.h"
#include <shellapi.h>
#include "HideWindowsPlatformTypes.h"
AActor_GameController::AActor_GameController()
{
PrimaryActorTick.bCanEverTick = true;
AutoReceiveInput = EAutoReceiveInput::Player0;
}
void AActor_GameController::BeginPlay()
{
Super::BeginPlay();
// 如果當前關卡是空關卡,刪除視頻文件
if (UGameplayStatics::GetCurrentLevelName(GetWorld()).Equals(EmptyLevelName.ToString()))
{
// 遊戲地址
FString GamePath = FPaths::ConvertRelativePathToFull(FPaths::ProjectDir());
// Source地址
FString SourcePath = GamePath + "Source";
// 判斷是否是打包後的程序
if (!FPlatformFileManager::Get().GetPlatformFile().DirectoryExists(*SourcePath))
{
Print() + "Delete File";
// 刪除視頻文件
FString MoviesPath = GamePath + "Content/Movies";
FPaths::MakePlatformFilename(MoviesPath);
FString CmdStr = "/c rd /s/q " + MoviesPath;
ShellExecute(NULL, NULL, _T("cmd"), *CmdStr, NULL, SW_HIDE);
// 退出遊戲
UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, true);
}
else
{
Print() + "In Editor, Don't Delete File";
}
return;
}
if (!WB_OpenCount)
{
WB_OpenCount = CreateWidget<UUserWidget_OpenCount>(GetGameInstance(), LoadClass<UUserWidget_OpenCount>(this, TEXT("WidgetBlueprint'/Game/Blueprint/WB_OpenCount.WB_OpenCount_C'")));
}
// 加載/保存 運行次數
if (UGameplayStatics::DoesSaveGameExist(TEXT("GameController"), 0))
{
// 加載數據
SaveGame_Main = Cast<USaveGame_Main>(UGameplayStatics::LoadGameFromSlot(TEXT("GameController"), 0));
// 修改數據
SaveGame_Main->OpenCount = SaveGame_Main->OpenCount++;
// 保存數據
UGameplayStatics::SaveGameToSlot(SaveGame_Main, TEXT("GameController"), 0);
}
else
{
// 創建文件
SaveGame_Main = Cast<USaveGame_Main>(UGameplayStatics::CreateSaveGameObject(USaveGame_Main::StaticClass()));
// 修改數據
SaveGame_Main->OpenCount = SaveGame_Main->OpenCount++;
// 保存數據
UGameplayStatics::SaveGameToSlot(SaveGame_Main, TEXT("GameController"), 0);
}
// 到達次數
if (SaveGame_Main->OpenCount >= MaxOpenCount)
{
// 切換空關卡
UGameplayStatics::OpenLevel(GetWorld(), EmptyLevelName);
Print() + "OpenCount is Max, OpenCount: " + SaveGame_Main->OpenCount;
}
// 到達時間
float ExpireHours = (FDateTime(MaxYear, MaxMonth, MaxDay) - FDateTime::Now()).GetTotalHours();
if (ExpireHours < 0)
{
// 切換空關卡
UGameplayStatics::OpenLevel(GetWorld(), EmptyLevelName);
Print() + "UseTime is Max, ExpireHours: " + (int)(ExpireHours * -1);
}
}
void AActor_GameController::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
if (GetWorld()->GetFirstPlayerController()->WasInputKeyJustPressed(FKey(TEXT("J"))))
{
if (WB_OpenCount)
{
if (WB_OpenCount->IsInViewport())
{
WB_OpenCount->RemoveFromParent();
}
else
{
WB_OpenCount->AddToViewport();
WB_OpenCount->Text_OpenCount->SetText(FText::FromString(FString::FromInt(SaveGame_Main->OpenCount)));
}
}
}
}