> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrate the PlayFab Unreal Engine Marketplace plugin

> 既存の PlayFab Online Subsystem 統合プロジェクトに PlayFab SDK UE Marketplace プラグインを統合する方法のガイダンス。

# クイックスタート ガイド: PlayFab Online Subsystem と PlayFab Unreal Engine Marketplace プラグインの統合

このクイックスタート ガイドは、既存の PlayFab Online Subsystem (OSS) 統合プロジェクトに [PlayFab SDK Unreal Engine (UE) Marketplace プラグイン](/services/playfab/sdks/unreal) を統合するのに役立ちます。

PlayFab SDK プラグインは、プレイヤー認証、仮想アイテムおよび通貨管理、およびソーシャル機能の作成などの、PlayFab の管理、クライアント、およびサーバー操作を実行するために使用されます。PlayFab Online Subsystem と組み合わせて使用​​すると、プロジェクトは Unreal Engine プロジェクト向けの PlayFab 機能の完全なスイートにアクセスできます。

PlayFab OSS または PlayFab SDK プラグインを互いに独立して使用する場合、最初のステップはユーザーの認証です。適切なセットアップなしに両方を同じプロジェクトで使用すると、PlayFab OSS と PlayFab SDK プラグインの両方が同じユーザーに対して個別の認証呼び出しを行うことになります。

このクイックスタート ガイドは、PlayFab OSS を介して認証し、その認証を PlayFab SDK プラグインで再利用して、シームレスなユーザー認証エクスペリエンスを提供するのに役立ちます。

## 前提条件

* PlayFab OSS を `<game>.build.cs` ファイル内のプラグインとして統合するようにしてください。以下の例では、統合を許可するトグル オプションを作成し、`#ifdef` ガードを許可する定義を設定します。
  ```cs theme={null}
  // PlayFab OnlineSubsystem Plugin Settings.
  //
  // While the PlayFab OSS is integrated with the game at an engine level, we cannot directly access
  // PF OSS headers unless we integrate it as a plugin.
  //
  // `bOSSPlayFabAsPlugin` must be set to true to expose the PlayFab OSS headers directly to the game.
  bool bOSSPlayFabAsPlugin = false;
  if (bOSSPlayFabAsPlugin)
  {
      PublicDependencyModuleNames.AddRange(new string[] { "OnlineSubsystemPlayFab" });
      PublicDefinitions.Add("WITH_OSS_PLAYFAB=1");
  }
  ```

* PlayFab SDK プラグインを `<game>.build.cs` ファイルに統合するようにしてください。以下の例では、統合を許可するトグル オプションを作成し、`#ifdef` ガードを許可する定義を設定します。
  ```cs theme={null}
  // PlayFab SDK Plugin Settings.
  //
  // `bPlayFabPlugin` must be set to true to enable compilation and integration with the PlayFab
  // SDK Plugin.
  // Ensure that the PF SDK Plugin is installed via Engine plugin or as a local game plugin.
  bool bPlayFabPlugin = false;
  if (bPlayFabPlugin)
  {
      PrivateDependencyModuleNames.AddRange(new string[] { "PlayFab", "PlayFabCpp", "PlayFabCommon" });
      PublicDefinitions.Add("WITH_PLAYFAB_PLUGIN=1");
  }
  ```

* `<game.build.cs>` ファイルを更新した後 (およびその後更新するたびに)、`.uproject` ファイルを右クリックして `Generate Visual Studio Project Files` を選択し、ゲームの Visual Studio プロジェクト ファイルを再生成してください。

* PlayFab OSS は、PlayFab OSS ユーザー認証フローの完了時にトリガーされる公開 `AuthenticateUserComplete` デリゲートを提供するようになりました。このデリゲートにバインドして、PlayFab OSS 認証の詳細を取得します。
  ```cpp theme={null}
  /**
  * Delegate used on the completion of FOnlineIdentityPlayFab::AuthenticateUser().
  *
  * @param LocalUserNum the controller number of the associated user that made the request
  * @param bWasSuccessful true if authentication was successful, false if there was an error
  * @param PlatformUserIdStr user identifier returned from the service.
  * @param ErrorStr string representing the error condition
  */
  DECLARE_MULTICAST_DELEGATE_FourParams(FOnAuthenticateUserComplete, int32 /*LocalUserNum*/, bool /*bWasSuccessful*/, const FString& /*PlatformUserIdStr*/, const FString& /*ErrorStr*/);
  typedef FOnAuthenticateUserComplete::FDelegate FOnAuthenticateUserCompleteDelegate;
  ```

## 手順

[完全なコード例](#full-code-example) にジャンプすることもできます。

1. **正しいヘッダーをインクルードする**
   ```cpp theme={null}
   #ifdef WITH_OSS_PLAYFAB
   #include "OnlineSubsystemPlayFab.h"
   #endif // WITH_OSS_PLAYFAB

   #ifdef WITH_PLAYFAB_PLUGIN
   #include "PlayFab.h"
   #include "PlayFabCommon.h"
   #include "Core/PlayFabClientDataModels.h"
   #endif // WITH_PLAYFAB_PLUGIN
   ```

2. **PlayFab OSS の取得**
   ```cpp theme={null}
   FOnlineSubsystemPlayFab* PFOnlineSub = static_cast<FOnlineSubsystemPlayFab*>(IOnlineSubsystem::Get(TEXT("PLAYFAB")));
   ```

3. **`AuthenticateUserComplete` デリゲートへのバインド**

   ```cpp theme={null}
   const FOnlineIdentityPlayFabPtr PlayFabIdentityInterface = PFOnlineSub->GetIdentityInterfacePlayFab();
   PlayFabIdentityInterface->AddOnAuthenticateUserCompleteDelegate_Handle
   (
       0, // LocalUserNum
       FOnAuthenticateUserCompleteDelegate::CreateUObject(this, &UGameInstance::OnAuthenticateUserComplete)
   );
   ```

   このデリゲートにバインドする関数は、デリゲートと同じシグネチャを持つ必要があります。例:

   ```cpp theme={null}
   void UGameInstance::OnAuthenticateUserComplete(int32 localUserNum, bool bWasSuccessful, const FString& platformUserIdStr, const FString& error)
   ```

   ラムダをデリゲートにバインドすることもできます。例:

   ```cpp theme={null}
   // We don't pass the `FOnlineIdentityPlayFabPtr` pointer through the lambda capture since the original
   // local isn't guaranteed to live longer than the lambda and we want to avoid dangling references.
   //
   // You can retrieve `FOnlineIdentityPlayFabPtr` again inside the lambda.
   PlayFabIdentityInterface->AddOnAuthenticateUserCompleteDelegate_Handle
   (
       0, // LocalUserNum
       FOnAuthenticateUserCompleteDelegate::CreateLambda([this](int32 localUserNum, bool bWasSuccessful, const FString& platformUserIdStr, const FString& error)
       {
           // lambda execution
       });
   )
   ```

4. **認証結果の処理**: デリゲートにバインドされた関数で、認証結果を処理します。認証が成功した場合、デリゲート トリガーからの `platformUserIdStr` を介して認証されたローカル ユーザーを取得します。次に、PlayFab OSS の `LocalUser` から PlayFab の `LoginResult` を構築します。
   ```cpp theme={null}
   void UGameInstance::OnAuthenticateUserComplete(int32 localUserNum, bool bWasSuccessful, const FString& platformUserIdStr, const FString& error)
   {
       if (!bWasSuccessful)
       {
           UE_LOG(LogOnlineGame, Error, TEXT("OSS PlayFab AuthenticateLocalUser Failed. Error: %s"), *error);
           return;
       }

       UE_LOG(LogOnlineGame, Display, TEXT("[%s] AuthenticateLocalUser Complete"), ANSI_TO_TCHAR(__FUNCTION__));

       FOnlineSubsystemPlayFab* PFOnlineSub = static_cast<FOnlineSubsystemPlayFab*>(IOnlineSubsystem::Get(TEXT("PLAYFAB")));
       const FOnlineIdentityPlayFabPtr PlayFabIdentityInterface = PFOnlineSub->GetIdentityInterfacePlayFab();

       if (PlayFabIdentityInterface)
       {
           if (const auto LocalUser = PlayFabIdentityInterface->GetPartyLocalUserFromPlatformIdString(platformUserIdStr))
           {
               // Setting PlayFab SDK Settings for future API calls
               auto& PFCommonModule = IPlayFabCommonModuleInterface::Get();
               PFCommonModule.SetClientSessionTicket(LocalUser->GetSessionTicket());
               PFCommonModule.SetEntityToken(LocalUser->GetEntityToken());

               // Create EntityKey
               auto LocalEntityKey = MakeShared<PlayFab::ClientModels::FEntityKey>();
               LocalEntityKey->Id = LocalUser->GetEntityId();
               LocalEntityKey->Type = LocalUser->GetEntityType();

               // Create EntityToken
               auto LocalEntityToken = MakeShared<PlayFab::ClientModels::FEntityTokenResponse>();
               LocalEntityToken->Entity = LocalEntityKey;
               LocalEntityToken->EntityToken = LocalUser->GetEntityToken();

               // Create LoginResult
               PlayFab::ClientModels::FLoginResult LoginResult;
               LoginResult.EntityToken = LocalEntityToken;
               LoginResult.LastLoginTime = LocalUser->GetEntityTokenUpdateTime();
               LoginResult.PlayFabId = LocalUser->GetPlayFabId();
               LoginResult.SessionTicket = LocalUser->GetSessionTicket();

               // With `LoginResult` populated, we can now use the PlayFab SDK Plugin APIs
               // however we wish. This state is considered "authenticated".
               //
               // This delegate signature functions does not return anything. You can pass `LoginResult`
               // out of this function however you wish.
               // 
               // Example psuedocode for a non-existent function that takes `LoginResult` as a parameter:
               // void UGameInstance::OnAPILoginSuccess(PlayFab::ClientModels::FLoginResult LoginResult);
           }
       }
   }
   ```

5. **PlayFab SDK プラグイン API の使用**: `LoginResult` に情報が設定されたら、必要に応じて PlayFab SDK プラグイン API を使用できます。この状態は「認証済み」と見なされます。

## 完全なコード例

```cpp theme={null}
#ifdef WITH_OSS_PLAYFAB
#include "OnlineSubsystemPlayFab.h"
#endif // WITH_OSS_PLAYFAB

#ifdef WITH_PLAYFAB_PLUGIN
#include "PlayFab.h"
#include "PlayFabCommon.h"
#include "Core/PlayFabClientDataModels.h"
#endif // WITH_PLAYFAB_PLUGIN

...

void UGameInstance::Init()
{
    Super::Init();
    ...

    // This is an example scenario of integrating the PlayFab OnlineSubsystem with the
    // PlayFab SDK Plugin.
    //
    // In this scenario, you can authenticate via the PlayFab OSS,
    // and then re-use that authentication with the PlayFab SDK Plugin.
    // 
    // PF OSS offers a public `AuthenticateUserComplete` delegate that can be bound;
    // this delegate triggers on completion of the PF OSS user authentication flow.
    // 
    // Below is an example of a game binding to that delegate, retrieving the
    // authenticated local user via the `platformUserIdStr` from the delegate
    // trigger, and then constructing a PlayFab `LoginResult` from the PF OSS
    // `LocalUser.`
    // 
    // These definitions are defined in `<game>.build.cs`.
#if defined(WITH_OSS_PLAYFAB) && defined(WITH_PLAYFAB_PLUGIN)
    // Explicitly retrieve the PlayFab OSS - we can't assume it's the default OSS.
    FOnlineSubsystemPlayFab* PFOnlineSub = static_cast<FOnlineSubsystemPlayFab*>(IOnlineSubsystem::Get(TEXT("PLAYFAB")));

    UE_LOG(LogOnlineGame, Warning, TEXT("Retrieved PFOnlineSub"));

    if (PFOnlineSub)
    {
        const FOnlineIdentityPlayFabPtr PlayFabIdentityInterface = PFOnlineSub->GetIdentityInterfacePlayFab();

        PlayFabIdentityInterface->AddOnAuthenticateUserCompleteDelegate_Handle
        (
            0, // LocalUserNum
            FOnAuthenticateUserCompleteDelegate::CreateUObject(this, &UGameInstance::OnAuthenticateUserComplete)
        );
    }
    else
    {
        UE_LOG(LogOnlineGame, Error, TEXT("UGameInstance::Init: Unable to find OnlineSubsystemPlayFab"));
    }
#endif // WITH_OSS_PLAYFAB && WITH_PLAYFAB_PLUGIN

    ...
}

void UGameInstance::OnAuthenticateUserComplete(int32 localUserNum, bool bWasSuccessful, const FString& platformUserIdStr, const FString& error)
{
    if (!bWasSuccessful)
    {
        UE_LOG(LogOnlineGame, Error, TEXT("OSS PlayFab AuthenticateLocalUser Failed. Error: %s"), *error);
        return;
    }

    UE_LOG(LogOnlineGame, Display, TEXT("[%s] AuthenticateLocalUser Complete"), ANSI_TO_TCHAR(__FUNCTION__));

    FOnlineSubsystemPlayFab* PFOnlineSub = static_cast<FOnlineSubsystemPlayFab*>(IOnlineSubsystem::Get(TEXT("PLAYFAB")));
    const FOnlineIdentityPlayFabPtr PlayFabIdentityInterface = PFOnlineSub->GetIdentityInterfacePlayFab();

    if (PlayFabIdentityInterface)
    {
        if (const auto LocalUser = PlayFabIdentityInterface->GetPartyLocalUserFromPlatformIdString(platformUserIdStr))
        {
            // Setting PlayFab SDK Settings for future API calls
            auto& PFCommonModule = IPlayFabCommonModuleInterface::Get();
            PFCommonModule.SetClientSessionTicket(LocalUser->GetSessionTicket());
            PFCommonModule.SetEntityToken(LocalUser->GetEntityToken());

            // Create EntityKey
            auto LocalEntityKey = MakeShared<PlayFab::ClientModels::FEntityKey>();
            LocalEntityKey->Id = LocalUser->GetEntityId();
            LocalEntityKey->Type = LocalUser->GetEntityType();

            // Create EntityToken
            auto LocalEntityToken = MakeShared<PlayFab::ClientModels::FEntityTokenResponse>();
            LocalEntityToken->Entity = LocalEntityKey;
            LocalEntityToken->EntityToken = LocalUser->GetEntityToken();

            // Create LoginResult
            PlayFab::ClientModels::FLoginResult LoginResult;
            LoginResult.EntityToken = LocalEntityToken;
            LoginResult.LastLoginTime = LocalUser->GetEntityTokenUpdateTime();
            LoginResult.PlayFabId = LocalUser->GetPlayFabId();
            LoginResult.SessionTicket = LocalUser->GetSessionTicket();

            // With `LoginResult` populated, we can now use the PlayFab SDK Plugin APIs
            // however we wish. This state is considered "authenticated".
            //
            // This delegate signature functions does not return anything. You can pass `LoginResult`
            // out of this function however you wish.
            // 
            // Example psuedocode for a non-existent function that takes `LoginResult` as a parameter:
            // void UGameInstance::OnAPILoginSuccess(PlayFab::ClientModels::FLoginResult LoginResult);
        }
    }
}
```


## Related topics

- [Unreal Engine クイックスタート](/ja-jp/services/playfab/sdks/unreal/quickstart.md)
- [Unreal Engine で GDK を使用する](/ja-jp/build/gdk-and-engines/unreal/unreal.md)
- [PlayFab OnlineSubsystem for Unreal Engine リリースノート](/ja-jp/services/playfab/multiplayer/networking/unreal-release-notes.md)
- [PlayFab for Unreal Engine の概要](/ja-jp/services/playfab/sdks/unified-unreal/overview.md)
- [PlayFab リリースノート 2018](/ja-jp/services/playfab/release-notes/2018.md)
