Save system
This commit is contained in:
parent
a432dcbbf7
commit
f7b9942b5a
BIN
Content/Blueprints/BP_Checkpoint.uasset
Normal file
BIN
Content/Blueprints/BP_Checkpoint.uasset
Normal file
Binary file not shown.
BIN
Content/Levels/Test/Actors/SaveTest/BP_Test_Load.uasset
Normal file
BIN
Content/Levels/Test/Actors/SaveTest/BP_Test_Load.uasset
Normal file
Binary file not shown.
Binary file not shown.
@ -4,8 +4,11 @@
|
||||
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
#include "UObject/Object.h"
|
||||
|
||||
#include "Levels/LevelBase.h"
|
||||
#include "PlayerBase.h"
|
||||
|
||||
bool UCommonFunctions::IsNonGameObject(UObject* object)
|
||||
{
|
||||
@ -34,3 +37,20 @@ void UCommonFunctions::DestroyActorRecursively(AActor* actor)
|
||||
child->Destroy();
|
||||
actor->Destroy();
|
||||
}
|
||||
|
||||
ALevelBase* UCommonFunctions::GetCurrentLevelScript(UObject* obj)
|
||||
{
|
||||
if(auto world = obj->GetWorld())
|
||||
if(auto level = world->GetCurrentLevel())
|
||||
if(auto script = level->GetLevelScriptActor())
|
||||
return Cast<ALevelBase>(script);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
APlayerBase* UCommonFunctions::GetPlayer(UObject* obj)
|
||||
{
|
||||
if(auto pc = UGameplayStatics::GetPlayerController(obj->GetWorld(), 0))
|
||||
if(auto pawn = pc->GetPawn())
|
||||
return Cast<APlayerBase>(pawn);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -17,4 +17,10 @@ public:
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = Actor)
|
||||
static void DestroyActorRecursively(class AActor* actor);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = Level)
|
||||
static class ALevelBase* GetCurrentLevelScript(class UObject* obj);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = Player)
|
||||
static class APlayerBase* GetPlayer(class UObject* obj);
|
||||
};
|
||||
|
@ -8,14 +8,22 @@
|
||||
#include "InputMappingContext.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
#include "CommonFunctions.h"
|
||||
#include "CustomGameUserSettings.h"
|
||||
#include "Interactable/Activators/InCameraInteractableActivator.h"
|
||||
#include "Interactable/Activators/RaycastInteractableActivator.h"
|
||||
#include "Interactable/Modificators/ActivateInteractableModificator.h"
|
||||
#include "Interactable/Modificators/SawInteractableModificator.h"
|
||||
#include "Levels/LevelBase.h"
|
||||
#include "PlayerBase.h"
|
||||
#include "SaveData.h"
|
||||
|
||||
UCustomGameInstanceBase* UCustomGameInstanceBase::instance = nullptr;
|
||||
|
||||
void UCustomGameInstanceBase::Init()
|
||||
{
|
||||
instance = this;
|
||||
|
||||
UGameInstance::Init();
|
||||
|
||||
// IN FUTURE ASSIGN FROM CONTENT LOADER MEMBER
|
||||
@ -31,6 +39,13 @@ void UCustomGameInstanceBase::Init()
|
||||
}
|
||||
|
||||
ApplyMouseSettings();
|
||||
|
||||
saveData = Cast<USaveData>(UGameplayStatics::CreateSaveGameObject(USaveData::StaticClass()));
|
||||
}
|
||||
|
||||
UCustomGameInstanceBase* UCustomGameInstanceBase::GetGameInstance()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
void UCustomGameInstanceBase::ApplyMouseSettings()
|
||||
@ -83,3 +98,32 @@ void UCustomGameInstanceBase::AppendInteractableModificatorClass(TSubclassOf<cla
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UCustomGameInstanceBase::SaveGame(FName checkpointName)
|
||||
{
|
||||
auto levelScript = UCommonFunctions::GetCurrentLevelScript(this);
|
||||
if(!levelScript)
|
||||
return;
|
||||
|
||||
auto player = UCommonFunctions::GetPlayer(this);
|
||||
if(!player)
|
||||
return;
|
||||
saveData->level = GetWorld()->GetFName();
|
||||
saveData->state = levelScript->GetState();
|
||||
saveData->checkpoint = checkpointName;
|
||||
if(player->leftPocketItem)
|
||||
saveData->playerLeftPocketItem = player->leftPocketItem->GetFName();
|
||||
if(player->rightPocketItem)
|
||||
saveData->playerRightPocketItem = player->rightPocketItem->GetFName();
|
||||
|
||||
UGameplayStatics::SaveGameToSlot(saveData, TEXT("Save"), 0);
|
||||
}
|
||||
|
||||
void UCustomGameInstanceBase::LoadGame()
|
||||
{
|
||||
saveData = Cast<USaveData>(UGameplayStatics::LoadGameFromSlot(TEXT("Save"), 0));
|
||||
if(!saveData)
|
||||
return;
|
||||
|
||||
UGameplayStatics::OpenLevel(this, saveData->level);
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/GameInstance.h"
|
||||
|
||||
#include "CustomGameInstanceBase.generated.h"
|
||||
@ -17,11 +16,21 @@ class UCustomGameInstanceBase : public UGameInstance
|
||||
public:
|
||||
virtual void Init() override;
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
static UCustomGameInstanceBase* GetGameInstance();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = Settings)
|
||||
void ApplyMouseSettings();
|
||||
|
||||
void AppendInteractableModificatorClass(TSubclassOf<class UInteractableModificator> modificator);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = Save)
|
||||
void SaveGame(FName checkpointName);
|
||||
UFUNCTION(BlueprintCallable, Category = Save)
|
||||
void LoadGame();
|
||||
|
||||
static UCustomGameInstanceBase* instance;
|
||||
|
||||
FLevelBeginnedDelegate OnLevelBeginned;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
@ -31,4 +40,6 @@ public:
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
TSet<TSoftObjectPtr<class UInputMappingContext>> inputContexts;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
class USaveData* saveData = nullptr;
|
||||
};
|
||||
|
12
Source/Lost_Edge/Private/Levels/Checkpoint.cpp
Normal file
12
Source/Lost_Edge/Private/Levels/Checkpoint.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "Checkpoint.h"
|
||||
|
||||
#include "CustomGameInstanceBase.h"
|
||||
|
||||
void ACheckpoint::SaveGame()
|
||||
{
|
||||
if(auto GI = Cast<UCustomGameInstanceBase>(GetWorld()->GetGameInstance()))
|
||||
GI->SaveGame(GetFName());
|
||||
}
|
18
Source/Lost_Edge/Private/Levels/Checkpoint.h
Normal file
18
Source/Lost_Edge/Private/Levels/Checkpoint.h
Normal file
@ -0,0 +1,18 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GameFramework/Actor.h"
|
||||
|
||||
#include "Checkpoint.generated.h"
|
||||
|
||||
UCLASS(Blueprintable, BlueprintType, MinimalAPI)
|
||||
class ACheckpoint : public AActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SaveGame();
|
||||
};
|
||||
|
@ -3,19 +3,39 @@
|
||||
|
||||
#include "LevelBase.h"
|
||||
|
||||
#include "EngineUtils.h"
|
||||
#include "LevelSequencePlayer.h"
|
||||
|
||||
#include "CommonFunctions.h"
|
||||
#include "CustomGameInstanceBase.h"
|
||||
#include "Interactable/Interactable.h"
|
||||
#include "Levels/Checkpoint.h"
|
||||
#include "PlayerBase.h"
|
||||
#include "SaveData.h"
|
||||
|
||||
void ALevelBase::BeginPlay()
|
||||
{
|
||||
ALevelScriptActor::BeginPlay();
|
||||
|
||||
//=== broadcast new level begin play
|
||||
BroadcastNewLevelBeginPlay();
|
||||
StartLevelAnimations();
|
||||
ApplySaveData();
|
||||
}
|
||||
|
||||
void ALevelBase::IterateToState(int32 to)
|
||||
{
|
||||
while(state < to)
|
||||
CallNextState();
|
||||
}
|
||||
|
||||
void ALevelBase::BroadcastNewLevelBeginPlay()
|
||||
{
|
||||
if(auto GI = Cast<UCustomGameInstanceBase>(GetWorld()->GetGameInstance()))
|
||||
GI->OnLevelBeginned.Broadcast(GetFName());
|
||||
}
|
||||
|
||||
//=== start level animations
|
||||
void ALevelBase::StartLevelAnimations()
|
||||
{
|
||||
FMovieSceneSequencePlaybackSettings playbackSettings;
|
||||
playbackSettings.bAutoPlay = true;
|
||||
FMovieSceneSequenceLoopCount playbackLoopCount;
|
||||
@ -27,6 +47,46 @@ void ALevelBase::BeginPlay()
|
||||
auto sequencePlayer = ULevelSequencePlayer::CreateLevelSequencePlayer(GetWorld(), sequence.LoadSynchronous(), playbackSettings, sequenceActor);
|
||||
onBeginPlaySequencesActors.Add(sequenceActor);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ALevelBase::ApplySaveData()
|
||||
{
|
||||
auto GI = UCustomGameInstanceBase::GetGameInstance();
|
||||
if(!GI || !GI->saveData || GI->saveData->level != GetWorld()->GetFName())
|
||||
return;
|
||||
|
||||
IterateToState(GI->saveData->state);
|
||||
|
||||
auto player = UCommonFunctions::GetPlayer(this);
|
||||
if(!player)
|
||||
return;
|
||||
|
||||
for(TActorIterator<ACheckpoint> it(GetWorld()); it; ++it)
|
||||
{
|
||||
if(it->GetFName() == GI->saveData->checkpoint)
|
||||
{
|
||||
player->SetActorLocation(it->GetActorLocation(), false, nullptr, ETeleportType::ResetPhysics);
|
||||
player->Controller->SetControlRotation(it->GetActorRotation());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int pocketItems = 0;
|
||||
for(TActorIterator<AInteractable> it(GetWorld()); it; ++it)
|
||||
{
|
||||
if(it->GetFName() == GI->saveData->playerLeftPocketItem)
|
||||
{
|
||||
++pocketItems;
|
||||
player->TakeItemToLeftHand(*it);
|
||||
}
|
||||
else if(it->GetFName() == GI->saveData->playerRightPocketItem)
|
||||
{
|
||||
++pocketItems;
|
||||
player->TakeItemToRightHand(*it);
|
||||
}
|
||||
if(pocketItems > 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,12 +15,21 @@ public:
|
||||
UFUNCTION(BlueprintCallable)
|
||||
inline void CallNextState() { ++state; NextState(); }
|
||||
|
||||
inline int32 GetState() { return state; };
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void NextState();
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void IterateToState(int32 to);
|
||||
|
||||
void BroadcastNewLevelBeginPlay();
|
||||
void StartLevelAnimations();
|
||||
void ApplySaveData();
|
||||
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
TArray<TSoftObjectPtr<class ULevelSequence>> onBeginPlaySequences;
|
||||
TArray<class ALevelSequenceActor*> onBeginPlaySequencesActors;
|
||||
|
29
Source/Lost_Edge/Private/SaveData.h
Normal file
29
Source/Lost_Edge/Private/SaveData.h
Normal file
@ -0,0 +1,29 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GameFramework/SaveGame.h"
|
||||
|
||||
#include "SaveData.generated.h"
|
||||
|
||||
UCLASS(BlueprintType)
|
||||
class USaveData : public USaveGame
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
FName level;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
int32 state;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
FName checkpoint;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
FName playerLeftPocketItem;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
FName playerRightPocketItem;
|
||||
};
|
@ -1,6 +0,0 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "SaveManager.h"
|
||||
|
||||
|
@ -1,19 +0,0 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "UObject/Object.h"
|
||||
|
||||
#include "SaveManager.generated.h"
|
||||
|
||||
UCLASS(BlueprintType)
|
||||
class USaveManager : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
|
||||
private:
|
||||
|
||||
};
|
Loading…
Reference in New Issue
Block a user