サブシステムの実装 - ストアアイテム購入 - (Unreal Engine モジュール)
注釈:本資料はAI技術を用いて翻訳されています。
サブシステムの概要
Byte Wars は、AccelByte Gaming Services (AGS) Online Subsystem (OSS) をラップするために StoreItemPurchaseSubsystem という Game Instance Subsystem を使用しています。このサブシステムは、Unreal Engine の IOnlinePurchase インターフェースの AccelByte 実装である FOnlinePurchaseAccelByte を使用します。このチュートリアルでは、サブシステムのスターター版を使用して、必要な関数をゼロから実装します。
スターターパックの内容
このチュートリアルに従うために、StoreItemPurchaseSubsystem_Starter という名前のスターターサブシステムクラスが用意されています。リソースセクションで確認できます。以下のファイルが含まれています:
- ヘッダーファイル:
Source/AccelByteWars/TutorialModules/Monetization/StoreItemPurchase/StoreItemPurchaseSubsystem_Starter.h - CPP ファイル:
Source/AccelByteWars/TutorialModules/Monetization/StoreItemPurchase/StoreItemPurchaseSubsystem_Starter.cpp
StoreItemPurchaseSubsystem_Starter クラスには、いくつかの便利なコンポーネントが含まれています:
- AGS Software Development Kit (SDK) 機能へのアクセスを提供する AGS OSS
FOnlinePurchaseAccelByteインターフェースの宣言と初期化。
private:
FOnlinePurchaseAccelBytePtr PurchaseInterface;
void UStoreItemPurchaseSubsystem_Starter::Initialize(FSubsystemCollectionBase& Collection)
{
// ...
const IOnlinePurchasePtr PurchasePtr = Online::GetSubsystem(GetWorld())->GetPurchaseInterface();
ensure(PurchasePtr);
PurchaseInterface = StaticCastSharedPtr<FOnlinePurchaseAccelByte>(PurchasePtr);
ensure(PurchaseInterface);
// ...
}
- Player Controller から一意の Net ID を取得するヘルパー関数。これは、このサブシステムの主要なユーザーであるウィジェットがプレイヤーを参照するために Player Controller を使用する一方で、OSS インターフェースがユーザーを識別するために一意の Net ID を必要とするため必要です。
private:
// ...
FUniqueNetIdPtr GetLocalPlayerUniqueNetId(const APlayerController* PlayerController) const;
さらに、Source/AccelByteWars/TutorialModules/Monetization/StoreItemPurchase/StoreItemPurchaseModel.h にあるモデルファイルには、バックエンドレスポンスを処理するために使用されるデリゲートが定義されています。
DECLARE_MULTICAST_DELEGATE_OneParam(FOnOrderComplete, const FOnlineError& /*Error*/)
アイテム購入の実装
-
StoreItemPurchaseSubsystem_Starterヘッダーファイルを開き、アイテム購入リクエストを送信する以下の関数を宣言します。public:
void CreateNewOrder(
const APlayerController* OwningPlayer,
const TWeakObjectPtr<UStoreItemDataObject> StoreItemData,
const int32 SelectedPriceIndex,
const int32 Quantity = 1) const; -
バックエンドからのレスポンスを処理するために、以下のデリゲートと関数を宣言します。
public:
// ...
FOnOrderComplete OnCheckoutCompleteDelegates;private:
// ...
void OnCreateNewOrderComplete(
bool bWasSuccessful,
const FAccelByteModelsOrderInfo& OrderInfo,
const FOnlineErrorAccelByte& OnlineError) const; -
StoreItemPurchaseSubsystem_StarterCPP ファイルを開き、CreateNewOrder()関数を実装します。この関数は、アイテム購入リクエストをバックエンドに送信します。void UStoreItemPurchaseSubsystem_Starter::CreateNewOrder(
const APlayerController* OwningPlayer,
const TWeakObjectPtr<UStoreItemDataObject> StoreItemData,
const int32 SelectedPriceIndex,
const int32 Quantity) const
{
const UStoreItemPriceDataObject* SelectedPrice = StoreItemData->GetPrices()[SelectedPriceIndex];
const FAccelByteModelsOrderCreate Order{
StoreItemData->GetStoreItemId(),
Quantity,
static_cast<int32>(SelectedPrice->GetRegularPrice()) * Quantity,
static_cast<int32>(SelectedPrice->GetFinalPrice()) * Quantity,
FPreConfigCurrency::GetCodeFromType(SelectedPrice->GetCurrencyType())
};
PurchaseInterface->CreateNewOrder(
*GetLocalPlayerUniqueNetId(OwningPlayer).Get(),
Order);
} -
OnCreateNewOrderComplete()関数を実装します。この関数は、バックエンドから返されたデータを使用してOnCheckoutCompleteDelegatesデリゲートをトリガーします。void UStoreItemPurchaseSubsystem_Starter::OnCreateNewOrderComplete(
bool bWasSuccessful,
const FAccelByteModelsOrderInfo& OrderInfo,
const FOnlineErrorAccelByte& OnlineError) const
{
if (OnCheckoutCompleteDelegates.IsBound())
{
OnCheckoutCompleteDelegates.Broadcast(OnlineError);
}
} -
CPP ファイル内で、
Initialize()関数を見つけて、既存の実装を以下のコードに置き換えます。このコードは、OnCreateNewOrderComplete()関数をFOnlinePurchaseAccelByteインターフェースの対応するデリゲートにバインドします。void UStoreItemPurchaseSubsystem_Starter::Initialize(FSubsystemCollectionBase& Collection)
{
Super::Initialize(Collection);
const IOnlinePurchasePtr PurchasePtr = Online::GetSubsystem(GetWorld())->GetPurchaseInterface();
ensure(PurchasePtr);
PurchaseInterface = StaticCastSharedPtr<FOnlinePurchaseAccelByte>(PurchasePtr);
ensure(PurchaseInterface);
PurchaseInterface->OnCreateNewOrderCompleteDelegates.AddUObject(this, &ThisClass::OnCreateNewOrderComplete);
} -
Deinitialize()関数に移動し、既存の実装を以下のコードに置き換えます。このコードは、OnCreateNewOrderComplete()関数のバインドを解除します。void UStoreItemPurchaseSubsystem_Starter::Deinitialize()
{
Super::Deinitialize();
PurchaseInterface->ClearOnCreateNewOrderCompleteDelegates(this);
}