# C++ インテグレーション

> Learn how to implement authentication using C++ in Unreal Engine.

以下のセクションでは、[Unreal Engine のサブシステム](https://docs.unrealengine.com/5.3/en-US/programming-subsystems-in-unreal-engine/) を使用して Authentication SDK を統合する方法を示します。Blueprint API では、この機能を公開するために Authentication サブシステムが提供されています。

## Authentication SDK を依存関係として追加する##add-the-authentication-sdk-as-a-dependency

先に進む前に、`Authentication` をモジュールのパブリック依存関係として追加し、プラグインのヘッダーファイルをクラスに加えます。

`Authentication` をモジュールの依存関係として Unreal プロジェクトのビルドファイルに追加します。

```cpp
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "Authentication" });
```

アクセスしたいプラグインのヘッダーファイルを自分のクラスに加えます。

```cpp
#include "AuthenticationSubsystem.h"
```

## Authentication サブシステム##authentication-subsystem

Authentication サブシステムには、Unity Authentication サーバーと通信し、プレイヤープロファイル情報を保持し、ローカルストレージからプレイヤー設定をロード/アンロードするためのインターフェースが含まれています。このサブシステムは、認証ライフサイクルを管理し、プロジェクトに必要な重要な認証情報を保存する役割を担います。

Authentication サブシステムにアクセスするには、[UGameInstance](https://docs.unrealengine.com/5.3/en-US/API/Runtime/Engine/Engine/UGameInstance/) からリファレンスを取得します。

```cpp
UWorld* GameWorld = GetWorld();
UGameInstance* GameInstance = GameWorld->GetGameInstance();
UAuthenticationSubsystem* AuthenticationSubsystem = GameInstance->GetSubsystem<UAuthenticationSubsystem>();
```

### SignInAnonymously##signinanonymously

[SignInAnonymously()](./sdk-api/authentication/authentication-subsystem.md#signinanonymously\(fauthenticationsigninoptions,-unity::services::core::thandlerfauthenticationresponse\)) メソッドを使用すると、[匿名で認証を行う](/authentication/use-anon-sign-in.md) ことができます。これは、ユーザー情報を必要とせず、外部プロバイダーとのインタラクションも不要な簡単な認証方法です。成功すると、Unity Authentication サーバーから返される認証情報で現在のプレイヤープロファイルが更新されます。

[SignInAnonymously()](./sdk-api/authentication/authentication-subsystem.md#signinanonymously\(fauthenticationsigninoptions,-unity::services::core::thandlerfauthenticationresponse\)) は、サインインの実行方法を変更するパラメーターとして [`FAuthenticationSignInOptions`](./sdk-api/authentication/models/authentication-sign-in-options.md) 構造体を受け取ります。これらのパラメーターの詳細については、[Unity API サービスのドキュメントページ](https://services.docs.unity.com/player-auth/v1/index.html) を参照してください。

SDK からの応答は応答ハンドラーで処理できます。その際、[`FAuthenticationResponse`](./sdk-api/authentication/models/authentication-response.md) を出力ピンとして受け取る必要があります。

```cpp
// Create sign-in options body
FAuthenticationSignInOptions SignInOptions;
SignInOptions.bCreateAccount = true;
SignInOptions.Nonce = TEXT("abc123");

AuthenticationSubsystem->SignInAnonymously(SignInOptions, THandler<FAuthenticationResponse>::CreateLambda([this](FAuthenticationResponse Response)
{
	// Your response logic here
}));
```

### GetUserInfo##getuserinfo

[GetUserInfo()](./sdk-api/authentication/authentication-subsystem.md#getuserinfo\(unity::services::core::thandlerfauthenticationuserresponse\)) メソッドを使用すると、現在認証されているユーザーに関する情報を取得できます。これには、ユーザー ID、認証タイムスタンプ、およびそのセッションにリンクされている外部 ID プロバイダーが含まれます。

SDK からの応答は応答ハンドラーで処理できます。その際、[`FAuthenticationUserResponse`](./sdk-api/authentication/models/authentication-user-response.md) を出力ピンとして受け取る必要があります。

```cpp
AuthenticationSubsystem->GetUserInfo(
THandler<FAuthenticationUserResponse>::CreateLambda([this](FAuthenticationUserResponse Response)
{
	// Your response logic here
}));
```

### DeleteUser##deleteuser

[DeleteUser()](./sdk-api/authentication/authentication-subsystem.md#deleteuser\(unity::services::core::thandlerbool\)) メソッドを使用すると、現在認証されているプレイヤーに関連するすべての情報を削除できます。このメソッドは、プレイヤーをサインアウトし、プレイヤーの設定やプロファイルもすべて削除します。

> **Note:**
>
> **ノート**: デフォルトプロファイルを使用しているときに [DeleteUser()](./sdk-api/authentication/authentication-subsystem.md#deleteuser\(unity::services::core::thandlerbool\)) が呼び出されると、プロファイル情報が消去されますが、プロファイル自体は保持されます。

SDK からの応答は応答ハンドラーで処理できます。その際、`bool` を出力ピンとして受け取る必要があります。削除が成功した場合は `true`、それ以外の場合は `false` が返されます。

```cpp
AuthenticationSubsystem->DeleteUser(
THandler<bool>::CreateLambda([this](bool bResponse)
{
	// Your response logic here
}));
```

### RegisterStateChangedCallback##registerstatechangedcallback

[RegisterStateChangedCallback()](./sdk-api/authentication/authentication-subsystem.md#registerstatechangedcallback\(unity::services::core::thandlerfauthenticationstatechangedresponse\)) メソッドを使用すると、[サブシステムの状態](./authentication-lifecycle.md) が変化した際に呼び出されるコールバック関数を割り当てることができます。例えば、プレイヤーが認証に成功してサブシステムの状態が `Authorized` に変化した際に、割り当てた関数が実行されます。

SDK からの応答は応答ハンドラーで処理できます。その際、[`AuthenticationStateChangedResponse`](./sdk-api/authentication/models/authentication-state-changed-response.md) を出力ピンとして受け取る必要があります。

```cpp
AuthenticationSubsystem->RegisterStateChangedCallback(
THandler<AuthenticationStateChangedResponse>::CreateLambda([this](AuthenticationStateChangedResponse Response)
{
	// Your response logic here
}));
```

### SignOut##signout

[SignOut()](./sdk-api/authentication/authentication-subsystem.md#signout\(bool\)) メソッドを使用すると、現在認証されているプレイヤープロファイルからサインアウトできます。これにより、現在のプレイヤープロファイルが削除され、デフォルトのプロファイルに切り替わります。このメソッドには、プレイヤーに関連付けられた保存済みの認証情報を削除する、オプションのパラメーターもあります。

> **Note:**
>
> **ノート**: デフォルトプロファイルを使用しているときに [SignOut()](./sdk-api/authentication/authentication-subsystem.md#signout\(bool\)) が呼び出されると、プロファイル情報が消去されますが、プロファイル自体は保持されます。

```cpp
AuthenticationSubsystem->SignOut(true); // Clear player credentials
```

### SwitchProfile##switchprofile

[SwitchProfile()](./sdk-api/authentication/authentication-subsystem.md#switchprofile\(const-fstring&\)) メソッドを使用すると、プレイヤープロファイルを切り替えたり、新しいプロファイルを作成したりできます。

> **Note:**
>
> **ノート**: [SwitchProfile()](./sdk-api/authentication/authentication-subsystem.md#switchprofile\(const-fstring&\)) は、サインアウト状態のときにのみ呼び出すことができます。認証された状態のときにプロファイルの切り替えが試みられた場合は、警告が記録され、何も実行されません。

```cpp
FString NewProfileName = FString(TEXT("new_profile_123"));
AuthenticationSubsystem->SwitchProfile(NewProfileName);
```

### ProfileExists##profileexists

[ProfileExists()](./sdk-api/authentication/authentication-subsystem.md#profileexists\(const-fstring&\)) メソッドを使用すると、指定したプロファイルが現在のセッションに存在するかどうかを確認できます。

> **Note:**
>
> **ノート**: 前のセッションで作成され、現在のセッションでは再作成されていないプロファイルがある場合、[ProfileExists()](./sdk-api/authentication/authentication-subsystem.md#profileexists\(const-fstring&\)) でそれらを検出することはできません。

```cpp
FString ProfileToCheckFor = FString(TEXT("new_profile_123"));
bool bExists = AuthenticationSubsystem->ProfileExists(ProfileToCheckFor);
```

### GetCurrentProfileName##getcurrentprofilename

[GetCurrentProfileName()](./sdk-api/authentication/authentication-subsystem.md#getcurrentprofilename\(\)) メソッドを使用すると、現在のプレイヤープロファイルの名前を取得できます。

```cpp
FString ProfileName = AuthenticationSubsystem->GetCurrentProfileName();
```

### GetProfileNames##getprofilenames

[GetCurrentProfileName()](./sdk-api/authentication/authentication-subsystem.md#getcurrentprofilename\(\)) メソッドを使用すると、現在のセッションで使用されているすべてのプレイヤープロファイル名のリストを取得できます。

```cpp
TArray<FString> ProfileNames = AuthenticationSubsystem->GetProfileNames();
```

### RegisterProfileChangedCallback##registerprofilechangedcallback

[RegisterProfileChangedCallback()](./sdk-api/authentication/authentication-subsystem.md#registerprofilechangedcallback\(unity::services::core::thandlerfauthenticationplayerprofilechangedresponse\)) メソッドを使用すると、プレイヤープロファイルが変更された際に呼び出されるコールバック関数を割り当てることができます。例えば、[SwitchProfile](./cpp-integration.md#switchprofile) が正常に実行されたときに、割り当てた関数が実行されます。

SDK からの応答は応答ハンドラーで処理できます。その際、[AuthenticationPlayerProfileChangedResponse](./sdk-api/authentication/models/authentication-player-profile-changed-response.md) を出力ピンとして受け取る必要があります。

```cpp
AuthenticationSubsystem->RegisterPlayerProfileChangedCallback(
THandler<AuthenticationPlayerProfileChangedResponse>::CreateLambda([this](AuthenticationPlayerProfileChangedResponse Response)
{
	// Your response logic here
}));
```

### RegisterProfileDeletedCallback##registerprofiledeletedcallback

[RegisterProfileChangedCallback()](./sdk-api/authentication/authentication-subsystem.md#registerprofilechangedcallback\(unity::services::core::thandlerfauthenticationplayerprofilechangedresponse\)) メソッドを使用すると、プレイヤープロファイルが現在のセッションから削除された際に呼び出されるコールバック関数を割り当てることができます。例えば、[SignOut](./cpp-integration.md#signout) が正常に実行されたときに、割り当てた関数が実行されます。

SDK からの応答は応答ハンドラーで処理できます。その際、[AuthenticationPlayerProfileChangedResponse](./sdk-api/authentication/models/authentication-player-profile-changed-response.md) を出力ピンとして受け取る必要があります。

```cpp
AuthenticationSubsystem->RegisterPlayerProfileChangedCallback(
THandler<AuthenticationPlayerProfileChangedResponse>::CreateLambda([this](AuthenticationPlayerProfileChangedResponse Response)
{
	// Your response logic here
}));
```

### IsSignedIn##issignedin

[IsSignedIn()](./sdk-api/authentication/authentication-subsystem.md#issignedin\(\)) メソッドを使用すると、現在のプレイヤープロファイルがサインインしているかどうかを確認できます。"サインインしている" とは、Authorized (認証済み) または Expired (有効期限切れ) のいずれかの状態であることを意味します。

```cpp
bool bSignedIn = AuthenticationSubsystem->IsSignedIn();
```

### IsAnonymous##isanonymous

[IsAnonymous()](./sdk-api/authentication/authentication-subsystem.md#isauthorized\(\)) メソッドを使用すると、現在のプレイヤープロファイルが匿名でサインインしているかどうかを確認できます。[SignInAnonymously](./cpp-integration.md#signinanonymously) が正常に実行されると、true が返されます。

```cpp
bool bAnonymous = AuthenticationSubsystem->IsAnonymous();
```

### IsAuthorized##isauthorized

[IsAuthorized()](./sdk-api/authentication/authentication-subsystem.md#isauthorized\(\)) メソッドを使用すると、現在のプレイヤープロファイルがサインインしており、現在も認証されているかどうかを確認できます。サインインメソッドが正常に実行され、有効期限がまだ切れていなければ、true が返されます。

```cpp
bool bAuthorized = AuthenticationSubsystem->IsAuthorized();
```

### IsExpired##isexpired

[IsExpired()](./sdk-api/authentication/authentication-subsystem.md#isexpired\(\)) メソッドを使用すると、現在のプレイヤープロファイルのセッションが有効期限切れかどうかを確認できます。サインイン成功時の応答で返された有効期限を過ぎている場合は、true が返されます。

```cpp
bool bExpired = AuthenticationSubsystem->IsExpired();
```

### SessionTokenExists##sessiontokenexists

[SessionTokenExists()](./sdk-api/authentication/authentication-subsystem.md#sessiontokenexists\(\)) メソッドを使用すると、現在のプレイヤープロファイルのプレイヤー設定にセッショントークンが存在するかどうかを確認できます。

```cpp
bool bTokenExists = AuthenticationSubsystem->SessionTokenExists();
```

### GetUnityProjectId##getunityprojectid

[GetUnityProjectId()](./sdk-api/authentication/authentication-subsystem.md#getunityprojectid\(\)) メソッドを使用すると、現在の認証セッションに関連付けられている Unity プロジェクト ID を取得できます。

```cpp
FGuid ProjectId = AuthenticationSubsystem->GetUnityProjectId();
```

### GetUnityEnvironmentName##getunityenvironmentname

[GetUnityEnvironmentName()](./sdk-api/authentication/authentication-subsystem.md#getunityenvironmentname\(\)) メソッドを使用すると、現在の認証セッションに関連付けられている Unity 環境 ID を取得できます。

```cpp
FString EnvironmentId = AuthenticationSubsystem->GetUnityEnvironmentName();
```

### GetAccessToken##getaccesstoken

[GetAccessToken()](./sdk-api/authentication/authentication-subsystem.md#getaccesstoken\(\)) メソッドを使用すると、現在のセッションのアクセストークンを取得できます。当該の文字列が存在しない場合は、空の文字列が返されます。

```cpp
FString AccessToken = AuthenticationSubsystem->GetAccessToken();
```

### GetSessionToken##getsessiontoken

[GetSessionToken()](./sdk-api/authentication/authentication-subsystem.md#getsessiontoken\(\)) メソッドを使用すると、現在のセッションのセッショントークンを取得できます。当該の文字列が存在しない場合は、空の文字列が返されます。

```cpp
FString SessionToken = AuthenticationSubsystem->GetSessionToken();
```

### GetUserId##getuserid

[GetUserId()](./sdk-api/authentication/authentication-subsystem.md#getuserid\(\)) メソッドを使用すると、現在のセッションのユーザー ID を取得できます。当該の文字列が存在しない場合は、空の文字列が返されます。

> **Note:**
>
> **ノート**: これは [プレイヤープロファイル名](./cpp-integration.md#getcurrentprofilename) とは異なります。ユーザー ID は、Unity Authentication System から返される一意のユーザー識別子です。

```cpp
FString UserId = AuthenticationSubsystem->GetUserId();
```

### GetState##getstate

[GetState()](./sdk-api/authentication/authentication-subsystem.md#getstate\(\)) メソッドを使用すると、認証セッションの現在の状態を取得できます。

```cpp
EAuthenticationState UserId = AuthenticationSubsystem->GetUserId();
```

### SetUnityProjectId##setunityprojectid

[SetUnityProjectId()](./sdk-api/authentication/authentication-subsystem.md#setunityprojectid\(fguid\)) メソッドを使用すると、現在の認証セッションに対して Unity プロジェクト ID を設定できます。これが実行されると、プロジェクト設定で設定された Unity プロジェクト ID がオーバーライドされます。

```cpp
FGuid NewProjectId = FGuid(TEXT("00000000-1234-1234-000000000000"));
AuthenticationSubsystem->SetUnityProjectId(NewProjectId);
```

### SetUnityEnvironmentName##setunityenvironmentname

[SetUnityEnvironmentName()](./sdk-api/authentication/authentication-subsystem.md#setunityenvironmentname\(fstring\)) メソッドを使用すると、現在の認証セッションに対して Unity 環境名を設定できます。これが実行されると、プロジェクト設定で設定された Unity 環境名がオーバーライドされます。

```cpp
FString NewEnvironmentName = FString(TEXT("testenv2"));
AuthenticationSubsystem->SetUnityEnvironmentName(NewEnvironmentName );
```
