Listing and reading files from Player Data Storage
You can store and retrieve per-user data in Player Data Storage using the User Cloud interface. You can't retrieve data of other players though; you can only access data of the locally signed in user.
Listing files stored in Player Data Storage
- C++
- Blueprints
To interact with Player Data Storage, first get the user cloud interface:
#include "OnlineSubsystem.h"
#include "OnlineSubsystemUtils.h"
// ...
IOnlineSubsystem* Subsystem = Online::GetSubsystem(this->GetWorld());
IOnlineUserCloudPtr UserCloud = Subsystem->GetUserCloudInterface();
Register the event handler so you know when the enumeration has completed. EnumerateUserFilesDelegateHandle
is declared as an FDelegateHandle
.
this->EnumerateUserFilesDelegateHandle =
UserCloud->AddOnEnumerateUserFilesCompleteDelegate_Handle(FOnEnumerateUserFilesComplete::FDelegate::CreateUObject(
this,
&UMyClass::HandleEnumerateUserFilesComplete));
Then call EnumerateUserFiles
using the player ID of the local user.
UserCloud->EnumerateUserFiles(*LocalUserId);
When your callback fires, you'll want to handle any errors (check bWasSuccessful
), and then deregister the event handler:
void UMyClass::HandleEnumerateUserFilesComplete(
bool bWasSuccessful,
FUniqueNetId UserId)
{
// Deregister the event handler.
IOnlineSubsystem *Subsystem = Online::GetSubsystem(this->GetWorld());
IOnlineUserCloudPtr UserCloud = Subsystem->GetUserCloudInterface();
UserCloud->ClearOnEnumerateUserFilesCompleteDelegate_Handle(this->EnumerateUserFilesDelegateHandle);
this->EnumerateUserFilesDelegateHandle.Reset();
if (!bWasSuccessful)
{
// Enumeration didn't succeed, return error.
}
else
{
// Enumeration was successful, do something.
}
}
After enumeration succeeds, you can get a list of the user's files by calling GetUserFileList
:
TArray<FCloudFileHeader> Files;
UserCloud->GetUserFileList(*LocalUserId, Files);
TArray<FString> FileNames;
FileNames.Reserve(Files.Num() - 1);
for (const auto& It : Files)
{
FileNames.Add(It.FileName);
}
Reading a file from Player Data Storage
When reading files from Player Data Storage, they might need to be transparently downloaded first, so reading files is an asynchronous operation.
- C++
- Blueprints
First, register the event handler for when the file read is complete. ReadUserFileDelegateHandle
is declared as an FDelegateHandle
.
this->ReadUserFileDelegateHandle =
UserCloud->AddOnReadUserFileCompleteDelegate_Handle(FOnReadUserFileComplete::FDelegate::CreateUObject(
this,
&UMyClass::ReadUserFileDelegateHandle));
Then call ReadUserFile
using the local player's ID and the file's name.
if (!UserCloud->ReadUserFile(*UserId, FileName))
{
// Couldn't read user file, return error.
}
When your callback fires, you'll want to handle any errors (check bWasSuccessful
), and then deregister the event handler:
void UMyClass::ReadUserFileDelegateHandle(
bool bWasSuccessful,
const FUniqueNetId &UserId,
const FString &FileName)
{
// Deregister the event handler.
IOnlineSubsystem *Subsystem = Online::GetSubsystem(this->GetWorld());
IOnlineUserCloudPtr UserCloud = Subsystem->GetUserCloudInterface();
UserCloud->ClearOnReadUserFileCompleteDelegate_Handle(this->ReadUserFileDelegateHandle);
this->ReadUserFileDelegateHandle.Reset();
if (!bWasSuccessful)
{
// Failed to read user file, return error.
}
else
{
TArray<uint8> FileContents;
if (!UserCloud->GetFileContents(UserId, FileName, FileContents))
{
// Failed to read user file, return error.
}
else
{
// The file data is in FileContents. If you wanted to read the file contents
// as a save game, you could so like this:
USaveGame *Data = UGameplayStatics::LoadGameFromMemory(FileContents);
}
}
}