すべてを統合する - クラウドセーブ - (Unreal Engine モジュール)
注釈:本資料はAI技術を用いて翻訳されています。
クラウドセーブへの保存とロードのためのUIの接続
このセクションでは、AccelByte Gaming Services (AGS) クラウドセーブを使用してゲームのサウンドオプションを保存およびロードするために、オプションメニューを接続する方法を学びます。
-
保存およびロードするレコードのキーを定義します。Byte Wars プロジェクトでは、これらのレコードキーは
/Source/AccelByteWars/TutorialModules/Storage/CloudSaveEssentials/CloudSaveModels.hヘッダーで定義されています。確認して次のステップに進んでください。#define GAME_OPTIONS_KEY FString(TEXT("GameOptions"))
#define SOUND_OPTIONS_KEY FString(TEXT("Sound"))
#define SOUND_OPTIONS_MUSIC_KEY FString(TEXT("musicvolume"))
#define SOUND_OPTIONS_SFX_KEY FString(TEXT("sfxvolume")) -
クラウドセーブレコードは、文字列キーとJSONオブジェクト値のペアとして保存されます。JSONオブジェクト値は、キーと値のペアのコレクションです。Byte Wars では、キーとして
category-subcategory形式を使用し、カテゴリはGAME_OPTIONS_KEY、サブカテゴリはSOUND_OPTIONS_KEYです。音楽と効果音 (SFX) のボリュームをクラウドセーブレコードに保存し、レコードのJSONフィールドでSOUND_OPTIONS_MUSIC_KEYとSOUND_OPTIONS_SFX_KEYとして表現されます。基本的な階層は以下のコードのようになります。このステップでは何もする必要はありませんので、確認して進んでください。{
GameOptions-Sound:
"musicvolume": <value>,
"sfxvolume": <value>
} -
これらのレコードキーを使用して、クラウドセーブからゲームのサウンドオプションをロードします。
CloudSaveSubsystem_StarterクラスのCPPファイルを開き、OnLoadGameSoundOptions()関数に移動して、以下のコードを追加します。これにより、ローディング画面が表示され、クラウドセーブからゲームオプションを取得するリクエストが送信されます。リクエストが完了すると、ローディング画面が非表示になり、クラウドセーブからのレスポンスに基づいてゲームオプションが更新されます。void UCloudSaveSubsystem_Starter::OnLoadGameSoundOptions(const APlayerController* PlayerController, TDelegate<void()> OnComplete)
{
if (!PlayerController)
{
UE_LOG_CLOUDSAVE_ESSENTIALS(Warning, TEXT("Cannot get game options from Cloud Save. Player Controller is null."));
return;
}
UAccelByteWarsGameInstance* GameInstance = Cast<UAccelByteWarsGameInstance>(GetGameInstance());
ensure(GameInstance);
UPromptSubsystem* PromptSubsystem = GameInstance->GetSubsystem<UPromptSubsystem>();
ensure(PromptSubsystem);
PromptSubsystem->ShowLoading();
// Get game options from Cloud Save.
GetPlayerRecord(
PlayerController,
FString::Printf(TEXT("%s-%s"), *GAME_OPTIONS_KEY, *SOUND_OPTIONS_KEY),
FOnGetCloudSaveRecordComplete::CreateWeakLambda(this, [this, GameInstance, PromptSubsystem, OnComplete, PlayerController](bool bWasSuccessful, FJsonObject& Result)
{
UE_LOG_CLOUDSAVE_ESSENTIALS(Warning, TEXT("Get game options from Cloud Save was successful: %s"), bWasSuccessful ? TEXT("True") : TEXT("False"));
PromptSubsystem->HideLoading();
// Update the local game options based on the Cloud Save record.
double MusicVolume = 0.0f, SFXVolume = 0.0f;
if (Result.TryGetNumberField(SOUND_OPTIONS_MUSIC_KEY, MusicVolume))
{
GameInstance->SetMusicVolume(MusicVolume);
}
if (Result.TryGetNumberField(SOUND_OPTIONS_SFX_KEY, SFXVolume))
{
GameInstance->SetSFXVolume(SFXVolume);
}
GameInstance->SaveGameSettings(GetLocalUserIndex(PlayerController));
OnComplete.ExecuteIfBound();
})
);
} -
サウンドオプションをクラウドセーブに保存します。クラスのCPPファイルで
OnSaveGameSoundOptionsメソッドの定義に移動し、以下のコードを追加します。これにより、ローディング画面が表示され、クラウドセーブレコードにゲームオプションを設定するリクエストが送信されます。リクエストが完了すると、ローディング画面が非表示になります。void UCloudSaveSubsystem_Starter::OnSaveGameSoundOptions(const APlayerController* PlayerController, TDelegate<void()> OnComplete)
{
if (!PlayerController)
{
UE_LOG_CLOUDSAVE_ESSENTIALS(Warning, TEXT("Cannot set game options from Cloud Save. Player Controller is null."));
return;
}
UAccelByteWarsGameInstance* GameInstance = Cast<UAccelByteWarsGameInstance>(GetGameInstance());
ensure(GameInstance);
UPromptSubsystem* PromptSubsystem = GameInstance->GetSubsystem<UPromptSubsystem>();
ensure(PromptSubsystem);
PromptSubsystem->ShowLoading(LOCTEXT("Saving", "Saving"));
// Construct game options to save.
FJsonObject GameOptionsData;
GameOptionsData.SetNumberField(SOUND_OPTIONS_MUSIC_KEY, GameInstance->GetMusicVolume());
GameOptionsData.SetNumberField(SOUND_OPTIONS_SFX_KEY, GameInstance->GetSFXVolume());
// Save the game options to Cloud Save.
SetPlayerRecord(
PlayerController,
FString::Printf(TEXT("%s-%s"), *GAME_OPTIONS_KEY, *SOUND_OPTIONS_KEY),
GameOptionsData,
FOnSetCloudSaveRecordComplete::CreateWeakLambda(this, [this, PromptSubsystem, OnComplete](bool bWasSuccessful)
{
UE_LOG_CLOUDSAVE_ESSENTIALS(Warning, TEXT("Set game options from Cloud Save was successful: %s"), bWasSuccessful ? TEXT("True") : TEXT("False"));
PromptSubsystem->HideLoading();
OnComplete.ExecuteIfBound();
}
));
} -
OnLoadGameSoundOptionsとOnSaveGameSoundOptionsメソッドを、それぞれオプションメニューが開いたときと閉じたときにバインドします。これを行うには、オプションウィジェットのOnOptionsWidgetActivatedとOnOptionsWidgetDeactivatedデリゲートにバインドします。CloudSaveSubsystem_StarterクラスのCPPファイルのBindDelegatesメソッドに以下のコードを追加することで実現できます。void UCloudSaveSubsystem_Starter::BindDelegates()
{
UAuthEssentialsModels::OnLoginSuccessDelegate.AddUObject(this, &ThisClass::OnLoadGameSoundOptions, TDelegate<void()>());
// ...
UOptionsWidget::OnOptionsWidgetActivated.AddUObject(this, &ThisClass::OnLoadGameSoundOptions);
UOptionsWidget::OnOptionsWidgetDeactivated.AddUObject(this, &ThisClass::OnSaveGameSoundOptions);
// ...
} -
クラウドセーブサブシステムが破棄されるときに、上記のデリゲートをアンバインドします。これは、
CloudSaveSubsystem_StarterクラスのCPPファイルのUnbindDelegatesメソッドに以下のコードを追加することで実現できます。void UCloudSaveSubsystem_Starter::UnbindDelegates()
{
UAuthEssentialsModels::OnLoginSuccessDelegate.RemoveAll(this);
UOptionsWidget::OnOptionsWidgetActivated.RemoveAll(this);
UOptionsWidget::OnOptionsWidgetDeactivated.RemoveAll(this);
// ...
}
リソース
- このチュートリアルセクションで使用されているファイルは、Unreal Byte Wars GitHubリポジトリで入手できます。
- AccelByteWars/Source/AccelByteWars/TutorialModules/Storage/CloudSaveEssentials/CloudSaveModels.h
- AccelByteWars/Source/AccelByteWars/TutorialModules/Storage/CloudSaveEssentials/CloudSaveSubsystem_Starter.h
- AccelByteWars/Source/AccelByteWars/TutorialModules/Storage/CloudSaveEssentials/CloudSaveSubsystem_Starter.cpp