DekanTrue
(DekanTrue)
December 11, 2014, 8:53am
1
I was wondering if there is a way to get all savegames in the savegame directory, without having to have a savegame with the list of your savegames?
So far I have only seen it done in C++.
What I would like, is to be able to copy/paste savegames to the folder, and then dynamically load them.
A direct solution. WINDOWS ONLY. In my static helper blueprint class…
---- .h -----
UFUNCTION(BlueprintCallable, Category = TDLHelpers)
static TArray<FString> GetAllSaveGameSlotNames();
---- .cpp -----
#include "PlatformFeatures.h"
#include "GameFramework/SaveGame.h"
...
TArray<FString> UtdlBlueprintHelpers::GetAllSaveGameSlotNames()
{
TArray<FString> ret;
ISaveGameSystem* SaveSystem = IPlatformFeaturesModule::Get().GetSaveGameSystem();
// If we have a save system and a valid name..
if (SaveSystem)
{
// From SaveGameSystem.h in the Unreal source code base.
FString saveGamePath = FString::Printf(TEXT("%s/SaveGames/*"), *FPaths::GameSavedDir());
UE_LOG(TDLLog, Log, TEXT("Search path %s"), *saveGamePath);
WIN32_FIND_DATA fd;
HANDLE hFind = ::FindFirstFile(*saveGamePath, &fd);
if (hFind != INVALID_HANDLE_VALUE) {
do {
UE_LOG(TDLLog, Log, TEXT(" test name: %s"), fd.cFileName);
// Disallow empty names and . and .. and don't get all tied up in WCHAR issues.
if (fd.cFileName[0] == '\0'||
fd.cFileName[0] == '.' && fd.cFileName[1] == '\0' ||
fd.cFileName[0] == '.' && fd.cFileName[1] == '.' && fd.cFileName[2] == '\0')
{ }
else if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 && fd.cFileName[0] != '.') {
ret.Add(FString(fd.cFileName));
}
} while (::FindNextFile(hFind, &fd));
::FindClose(hFind);
}
}
return ret;
}
Why not use a known name save file as master save file which contains names of all other save files?
Create a save file “MASTER”
Save your game with any name e.g “Savegame1”
Add Savegame1 in “MASTER”'s file list
to load
1.Load Save file MASTER
2.Get the name of all save files from step 2 above
3.Load the save file you want from the list.
1 Like
The issue with this method is that if something happens to that master save, the user will lose the reference to all their other saves and most likely think all their save data has been lost. BPs really need a way to list all save games properly.
Reactant
(Reactant)
July 23, 2017, 4:03pm
5
I’m not very good at C++, could someone explain why when i try and compile the above code i get an error saying USnakesBlueprintFunctionLibrary is not a class, If anyone could point me in the right direction id appreciate it
Ixiguis
(Ixiguis)
June 25, 2017, 8:04pm
6
This code should work for any platform.
.h
/** returns a list of all save games in /Saved/SaveGames folder, without the .sav extension (filename only) */
UFUNCTION(BlueprintPure, Category = Game)
static TArray<FString> GetAllSaveGameSlotNames();
.cpp
#include "Paths.h"
#include "PlatformFile.h"
#include "PlatformFilemanager.h"
TArray<FString> USnakesBlueprintFunctionLibrary::GetAllSaveGameSlotNames()
{
//////////////////////////////////////////////////////////////////////////////
class FFindSavesVisitor : public IPlatformFile::FDirectoryVisitor
{
public:
FFindSavesVisitor() {}
virtual bool Visit(const TCHAR* FilenameOrDirectory, bool bIsDirectory)
{
if (!bIsDirectory)
{
FString FullFilePath(FilenameOrDirectory);
if (FPaths::GetExtension(FullFilePath) == TEXT("sav"))
{
FString CleanFilename = FPaths::GetBaseFilename(FullFilePath);
CleanFilename = CleanFilename.Replace(TEXT(".sav"), TEXT(""));
SavesFound.Add(CleanFilename);
}
}
return true;
}
TArray<FString> SavesFound;
};
//////////////////////////////////////////////////////////////////////////////
TArray<FString> Saves;
const FString SavesFolder = FPaths::GameSavedDir() + TEXT("SaveGames");
if (!SavesFolder.IsEmpty())
{
FFindSavesVisitor Visitor;
FPlatformFileManager::Get().GetPlatformFile().IterateDirectory(*SavesFolder, Visitor);
Saves = Visitor.SavesFound;
}
return Saves;
}
If you don’t know what to do with this, look up in the wiki: “C++ blueprint function library tutorial”.
2 Likes
Reactant
(Reactant)
July 24, 2017, 3:14pm
8
i have looked that up but all i find is ramas tutorial and he doesnt explain much of anything
LatFoued
(LatFoued)
November 5, 2017, 1:35pm
9
Thanks!
This works perfectly.
dollon
(dollon)
August 8, 2019, 11:14am
10
You my sir are a life Saver.
Mewbits
(Mewbits)
November 8, 2019, 2:10am
11
You need to use your own class name instead. For instance mine is called something like UNewGameInstance because it’s in my game instance cpp file, which handles all my saving and loading.
If you use Visual Studio’s Create Definition helper (by right clicking the header file function) it will create this part for you.
I think you can do it like this in blueprint
15 Likes
Ixiguis
(Ixiguis)
May 8, 2021, 7:21pm
13
I don’t have this “Find Files” node, I think that’s from some plugin that you have.
3 Likes
Yes it is a plugin but this is a build-in plugin called Blueprint File Utilities
4 Likes
Awesome thanks mate, very helpful.
Helps me a lot. Thank you very much!!!
lord_sombo
(lord_sombo)
January 9, 2023, 7:18pm
19
Just came across this now and it’d be nice to note that you need to activate the Blueprint File Utilities plugin
2 Likes
Ad04a
(Ad04a)
February 18, 2023, 7:32am
20
Will this work in packaged for production game?