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 "GameFramework/Actor.h"
|
||||||
#include "InputCoreTypes.h"
|
#include "InputCoreTypes.h"
|
||||||
|
#include "Kismet/GameplayStatics.h"
|
||||||
#include "UObject/Object.h"
|
#include "UObject/Object.h"
|
||||||
|
|
||||||
|
#include "Levels/LevelBase.h"
|
||||||
|
#include "PlayerBase.h"
|
||||||
|
|
||||||
bool UCommonFunctions::IsNonGameObject(UObject* object)
|
bool UCommonFunctions::IsNonGameObject(UObject* object)
|
||||||
{
|
{
|
||||||
@ -34,3 +37,20 @@ void UCommonFunctions::DestroyActorRecursively(AActor* actor)
|
|||||||
child->Destroy();
|
child->Destroy();
|
||||||
actor->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)
|
UFUNCTION(BlueprintCallable, Category = Actor)
|
||||||
static void DestroyActorRecursively(class AActor* 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 "InputMappingContext.h"
|
||||||
#include "Kismet/GameplayStatics.h"
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
|
||||||
|
#include "CommonFunctions.h"
|
||||||
#include "CustomGameUserSettings.h"
|
#include "CustomGameUserSettings.h"
|
||||||
#include "Interactable/Activators/InCameraInteractableActivator.h"
|
#include "Interactable/Activators/InCameraInteractableActivator.h"
|
||||||
#include "Interactable/Activators/RaycastInteractableActivator.h"
|
#include "Interactable/Activators/RaycastInteractableActivator.h"
|
||||||
#include "Interactable/Modificators/ActivateInteractableModificator.h"
|
#include "Interactable/Modificators/ActivateInteractableModificator.h"
|
||||||
#include "Interactable/Modificators/SawInteractableModificator.h"
|
#include "Interactable/Modificators/SawInteractableModificator.h"
|
||||||
|
#include "Levels/LevelBase.h"
|
||||||
|
#include "PlayerBase.h"
|
||||||
|
#include "SaveData.h"
|
||||||
|
|
||||||
|
UCustomGameInstanceBase* UCustomGameInstanceBase::instance = nullptr;
|
||||||
|
|
||||||
void UCustomGameInstanceBase::Init()
|
void UCustomGameInstanceBase::Init()
|
||||||
{
|
{
|
||||||
|
instance = this;
|
||||||
|
|
||||||
UGameInstance::Init();
|
UGameInstance::Init();
|
||||||
|
|
||||||
// IN FUTURE ASSIGN FROM CONTENT LOADER MEMBER
|
// IN FUTURE ASSIGN FROM CONTENT LOADER MEMBER
|
||||||
@ -31,6 +39,13 @@ void UCustomGameInstanceBase::Init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ApplyMouseSettings();
|
ApplyMouseSettings();
|
||||||
|
|
||||||
|
saveData = Cast<USaveData>(UGameplayStatics::CreateSaveGameObject(USaveData::StaticClass()));
|
||||||
|
}
|
||||||
|
|
||||||
|
UCustomGameInstanceBase* UCustomGameInstanceBase::GetGameInstance()
|
||||||
|
{
|
||||||
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UCustomGameInstanceBase::ApplyMouseSettings()
|
void UCustomGameInstanceBase::ApplyMouseSettings()
|
||||||
@ -82,4 +97,33 @@ 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
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "Engine/GameInstance.h"
|
#include "Engine/GameInstance.h"
|
||||||
|
|
||||||
#include "CustomGameInstanceBase.generated.h"
|
#include "CustomGameInstanceBase.generated.h"
|
||||||
@ -17,11 +16,21 @@ class UCustomGameInstanceBase : public UGameInstance
|
|||||||
public:
|
public:
|
||||||
virtual void Init() override;
|
virtual void Init() override;
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintPure)
|
||||||
|
static UCustomGameInstanceBase* GetGameInstance();
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = Settings)
|
UFUNCTION(BlueprintCallable, Category = Settings)
|
||||||
void ApplyMouseSettings();
|
void ApplyMouseSettings();
|
||||||
|
|
||||||
void AppendInteractableModificatorClass(TSubclassOf<class UInteractableModificator> modificator);
|
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;
|
FLevelBeginnedDelegate OnLevelBeginned;
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly)
|
UPROPERTY(EditDefaultsOnly)
|
||||||
@ -31,4 +40,6 @@ public:
|
|||||||
UPROPERTY(EditDefaultsOnly)
|
UPROPERTY(EditDefaultsOnly)
|
||||||
TSet<TSoftObjectPtr<class UInputMappingContext>> inputContexts;
|
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 "LevelBase.h"
|
||||||
|
|
||||||
|
#include "EngineUtils.h"
|
||||||
#include "LevelSequencePlayer.h"
|
#include "LevelSequencePlayer.h"
|
||||||
|
|
||||||
|
#include "CommonFunctions.h"
|
||||||
#include "CustomGameInstanceBase.h"
|
#include "CustomGameInstanceBase.h"
|
||||||
|
#include "Interactable/Interactable.h"
|
||||||
|
#include "Levels/Checkpoint.h"
|
||||||
|
#include "PlayerBase.h"
|
||||||
|
#include "SaveData.h"
|
||||||
|
|
||||||
void ALevelBase::BeginPlay()
|
void ALevelBase::BeginPlay()
|
||||||
{
|
{
|
||||||
ALevelScriptActor::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()))
|
if(auto GI = Cast<UCustomGameInstanceBase>(GetWorld()->GetGameInstance()))
|
||||||
GI->OnLevelBeginned.Broadcast(GetFName());
|
GI->OnLevelBeginned.Broadcast(GetFName());
|
||||||
|
}
|
||||||
|
|
||||||
//=== start level animations
|
void ALevelBase::StartLevelAnimations()
|
||||||
|
{
|
||||||
FMovieSceneSequencePlaybackSettings playbackSettings;
|
FMovieSceneSequencePlaybackSettings playbackSettings;
|
||||||
playbackSettings.bAutoPlay = true;
|
playbackSettings.bAutoPlay = true;
|
||||||
FMovieSceneSequenceLoopCount playbackLoopCount;
|
FMovieSceneSequenceLoopCount playbackLoopCount;
|
||||||
@ -27,6 +47,46 @@ void ALevelBase::BeginPlay()
|
|||||||
auto sequencePlayer = ULevelSequencePlayer::CreateLevelSequencePlayer(GetWorld(), sequence.LoadSynchronous(), playbackSettings, sequenceActor);
|
auto sequencePlayer = ULevelSequencePlayer::CreateLevelSequencePlayer(GetWorld(), sequence.LoadSynchronous(), playbackSettings, sequenceActor);
|
||||||
onBeginPlaySequencesActors.Add(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)
|
UFUNCTION(BlueprintCallable)
|
||||||
inline void CallNextState() { ++state; NextState(); }
|
inline void CallNextState() { ++state; NextState(); }
|
||||||
|
|
||||||
|
inline int32 GetState() { return state; };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void BeginPlay() override;
|
virtual void BeginPlay() override;
|
||||||
|
|
||||||
UFUNCTION(BlueprintImplementableEvent)
|
UFUNCTION(BlueprintImplementableEvent)
|
||||||
void NextState();
|
void NextState();
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable)
|
||||||
|
void IterateToState(int32 to);
|
||||||
|
|
||||||
|
void BroadcastNewLevelBeginPlay();
|
||||||
|
void StartLevelAnimations();
|
||||||
|
void ApplySaveData();
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly)
|
UPROPERTY(EditDefaultsOnly)
|
||||||
TArray<TSoftObjectPtr<class ULevelSequence>> onBeginPlaySequences;
|
TArray<TSoftObjectPtr<class ULevelSequence>> onBeginPlaySequences;
|
||||||
TArray<class ALevelSequenceActor*> onBeginPlaySequencesActors;
|
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