すべてをまとめる - ゲーム内ストアディスプレイ - (Unreal Engine モジュール)
注釈:本資料はAI技術を用いて翻訳されています。
UIを接続してストアディスプレイを表示する
-
SectionedShopWidget_StarterCPPファイルを開き、OnParentRefreshButtonClicked()関数に移動して、既存の実装を以下のコードに置き換えます。これは、OnQueryOrGetDisplaysCompleted()を完了デリゲートとして使用してQueryOrGetDisplays()関数を呼び出します。bRefreshingフラグをtrueに設定することで、サブシステムにバックエンドへのクエリを強制し、取得されたディスプレイ、セクション、オファーが最新であることを保証します。void USectionedShopWidget_Starter::OnParentRefreshButtonClicked()
{
if (bRefreshing)
{
return;
}
bRefreshing = true;
Ws_Root->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Loading);
InGameStoreDisplaysSubsystem->QueryOrGetDisplays(
GetOwningPlayer(),
FOnQueryOrGetDisplaysComplete::CreateUObject(this, &ThisClass::OnQueryOrGetDisplaysCompleted),
bRefreshing);
} -
OnQueryOrGetDisplaysCompleted()関数を見つけて、その実装を以下のコードに置き換えます。これは、TargetDisplayName変数に一致するディスプレイが見つかった場合、OnQueryOrGetSectionsCompleted()を完了デリゲートとして使用してQueryOrGetSectionsForDisplay()関数をトリガーします。void USectionedShopWidget_Starter::OnQueryOrGetDisplaysCompleted(
TArray<TSharedRef<FAccelByteModelsViewInfo>>& Displays,
const FOnlineError& Error)
{
if (Error.bSucceeded)
{
for (const TSharedRef<FAccelByteModelsViewInfo>& Display : Displays)
{
/**
* Trigger query sections for target display only
* Use Name to find the Display Name set on Admin Portal
* Use Title to retrieve the localized name set on Admin Portal
*/
if (Display->Name.Equals(TargetDisplayName))
{
InGameStoreDisplaysSubsystem->QueryOrGetSectionsForDisplay(
GetOwningPlayer(),
Display->ViewId,
FOnQueryOrGetSectionsInDisplayComplete::CreateUObject(this, &ThisClass::OnQueryOrGetSectionsCompleted),
bRefreshing);
return;
}
}
Ws_Root->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Empty);
}
else
{
Ws_Root->ErrorMessage = Error.ErrorMessage;
Ws_Root->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Error);
bRefreshing = false;
}
} -
OnQueryOrGetSectionsCompleted()関数に移動して、その実装を以下のコードに置き換えます。これは、取得された各セクションに対してQueryOrGetOffersInSection()をトリガーし、OnQueryOrGetOffersInSectionCompleted()を完了デリゲートとして使用します。void USectionedShopWidget_Starter::OnQueryOrGetSectionsCompleted(
TArray<TSharedRef<FAccelByteModelsSectionInfo>>& Sections,
const FOnlineError& Error)
{
if (Error.bSucceeded)
{
if (Sections.IsEmpty())
{
Ws_Root->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Empty);
return;
}
SectionDatas.Empty();
QueryOrGetOffersInSectionCount = Sections.Num();
for (int i = 0; i < Sections.Num(); ++i)
{
USectionDataObject* Data = NewObject<USectionDataObject>();
Data->SectionInfo = Sections[i].Get();
Data->SectionColor = GetSectionPresetColor(i);
SectionDatas.Add(Data);
InGameStoreDisplaysSubsystem->QueryOrGetOffersInSection(
GetOwningPlayer(),
Sections[i]->SectionId,
FOnQueryOrGetOffersInSectionComplete::CreateUObject(
this, &ThisClass::OnQueryOrGetOffersInSectionCompleted, Sections[i]->SectionId),
bRefreshing);
}
}
else
{
Ws_Root->ErrorMessage = Error.ErrorMessage;
Ws_Root->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Error);
bRefreshing = false;
}
} -
NativeOnActivated()関数に移動して、その実装を以下のコードに置き換えます。これは、ウィジェットが開かれるとすぐにQueryOrGetDisplays()を呼び出し、bRefreshingの現在の値を保持します。つまり、プレイヤーが以前にメニューを開いたことがある場合、再度バックエンドクエリをトリガーしません。void USectionedShopWidget_Starter::NativeOnActivated()
{
Super::NativeOnActivated();
InGameStoreDisplaysSubsystem = GetGameInstance()->GetSubsystem<UInGameStoreDisplaysSubsystem_Starter>();
ensure(InGameStoreDisplaysSubsystem);
Ws_Root->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Loading);
InGameStoreDisplaysSubsystem->QueryOrGetDisplays(
GetOwningPlayer(),
FOnQueryOrGetDisplaysComplete::CreateUObject(this, &ThisClass::OnQueryOrGetDisplaysCompleted),
bRefreshing);
// Bind parent's (store essentials) refresh function with this refresh function
if (UShopWidget* ShopWidget = GetFirstOccurenceOuter<UShopWidget>())
{
ShopWidget->OnRefreshButtonClickedDelegates.AddUObject(this, &ThisClass::OnParentRefreshButtonClicked);
}
else if (UShopWidget_Starter* ShopWidget_Starter = GetFirstOccurenceOuter<UShopWidget_Starter>())
{
ShopWidget_Starter->OnRefreshButtonClickedDelegates.AddUObject(this, &ThisClass::OnParentRefreshButtonClicked);
}
}