Unreal Engine 用 AGS OSS
注釈:本資料はAI技術を用いて翻訳されています。
LocalUserNum
AGS OSS は、プレイヤーのコントローラーインデックスを識別することにより、同じゲームインスタンスをプレイする複数のローカルユーザーを処理できます。同じコントローラーインデックスは、ほとんどのOSSインターフェースで LocalUserNum として定義されています。AGS OSS は、LocalUserNum をキーとして使用してユーザーのオンライン情報を保存します。
UniqueNetId
UniqueNetId は、オンラインサービスにおけるユーザープロファイルの抽象化です。AGS OSS では、AGS Composite UniqueNetId として派生し、AGS userId、発信元プラットフォーム、および発信元プラットフォーム userId データフィールドで構成されます。
インターフェース
AGS OSS は、UE の OSS の事前定義されたインターフェースを拡張し、開発者が AGS オンラインサービスをゲームにさらに拡張および統合できるようにします。これらのインターフェースは、API を非同期呼び出しでラップするため、ゲームは通常どおり実行できます。
オンラインアイデンティティインターフェース
オンラインアイデンティティインターフェースは、プレイヤーの認証とプロファイルに使用されます。
ログイン
AGS OSS は、ネイティブプラットフォームに基づいて、または FOnlineAccelByteAccountCredentials クラスでタイプと認証情報を提供することにより、他のプラットフォームでいくつかの異なるログインタイプを提供します。OSS で利用できるログインタイプはいくつかあります。これらのログインタイプは、EAccelByteLoginType の列挙型で分類されます。タイプには次のものが含まれます。
- DeviceId
- AccelByte
- Xbox
- PS4
- PS5
- Launcher
- Steam
- RefreshToken
const UWorld* World = GameEngine->GetGameWorld();
const IOnlineSubsystem* Subsystem = Online::GetSubsystem(World, ACCELBYTE_SUBSYSTEM);
FOnlineIdentityAccelBytePtr IdentityInterface = StaticCastSharedPtr<FOnlineIdentityAccelByte>(Subsystem->GetIdentityInterface());
if (IdentityInterface.IsValid())
{
FOnlineAccelByteAccountCredentials Credentials{ EAccelByteLoginType::AccelByte
, Username, Password };
// Login
IdentityInterface->AddOnLoginCompleteDelegate_Handle(LocalUserNum
, FOnLoginCompleteDelegate::CreateLambda([](int32 LocalUserNum, bool bLoginWasSuccessful, const FUniqueNetId& UserId, const FString& LoginError)
{
if (bLoginWasSuccessful)
{
// Do something when player successfully logged in
}
else
{
// Do something when player failed to log in
}
})
);
IdentityInterface->Login(LocalUserNum, Credentials);
}
ログインに成功した後、プレイヤーは、Friends、Party、Presence などのソーシャル関連インターフェースを使用できるようにするために、Lobby サービスに接続する必要があります。ConnectAccelByteLobby を呼び出すことで手動で接続するか、DefaultEngine.ini ファイルで bAutoLobbyConnectAfterLoginSuccess を true に設定することで接続できます。
const UWorld* World = GameEngine->GetGameWorld();
const IOnlineSubsystem* Subsystem = Online::GetSubsystem(World, ACCELBYTE_SUBSYSTEM);
FOnlineIdentityAccelBytePtr IdentityInterface = StaticCastSharedPtr<FOnlineIdentityAccelByte>(Subsystem->GetIdentityInterface());
if (IdentityInterface.IsValid())
{
// Connect to AccelByte Lobby Websocket, can be automatically called after
// successful login by configuring bAutoLobbyConnectAfterLoginSuccess to true
// in DefaultEngine.ini
IdentityInterface->ConnectAccelByteLobby(LocalUserNum);
}
ログアウト
プレイヤーがプレイを終了したら、次のコードを使用してログアウトします。
const UWorld* World = GameEngine->GetGameWorld();
const IOnlineSubsystem* Subsystem = Online::GetSubsystem(World, ACCELBYTE_SUBSYSTEM);
FOnlineIdentityAccelBytePtr IdentityInterface = StaticCastSharedPtr<FOnlineIdentityAccelByte>(Subsystem->GetIdentityInterface());
if (IdentityInterface.IsValid())
{
// Logout
IdentityInterface->AddOnLogoutCompleteDelegate_Handle(LocalUserNum
, FOnLogoutCompleteDelegate::CreateLambda([](int32 LocalUserNum, bool bLogoutWasSuccessful)
{
if (bLogoutWasSuccessful)
{
// Do something when player successfully logged out
}
else
{
// Do something when player failed to log out
}
})
);
IdentityInterface->Logout(LocalUserNum);
}
オンライン同意インターフェース
オンライン同意インターフェースは、プレイヤーの法的同意ポリシーをクエリまたは受諾するために使用されます。
ユーザーが準拠していない
プレイヤーが正常にログインした後、オンライン同意インターフェースは、プレイヤーが必要なすべての法的ポリシーに準拠しているかどうかを確認します。プレイヤーが準拠している場合、OnLoginCompleteDelegates がトリガーされ、プレイヤーのログインフローが完了します。ただし、プレイヤーが必要な法的ポリシーのいずれかに準拠していない場合、OnUserNotCompliedDelegates がトリガーされ、プレイヤーはサービスを使用できなくなります。
const UWorld* World = GameEngine->GetGameWorld();
const IOnlineSubsystem* Subsystem = Online::GetSubsystem(World, ACCELBYTE_SUBSYSTEM);
const FOnlineSubsystemAccelByte* ABSubsystem = static_cast<const FOnlineSubsystemAccelByte*>(Subsystem);
FOnlineAgreementAccelBytePtr AgreementInterface = ABSubsystem->GetAgreementInterface();
if (AgreementInterface.IsValid())
{
AgreementInterface->AddOnUserNotCompliedDelegate_Handle(LocalUserNum
, FOnUserNotCompliedDelegate::CreateLambda([]()
{
// Do something when player doesn't comply with the legal agreements
})
);
}
対象となる同意事項のクエリ
OnUserNotCompliedDelegates を受け取った後、プレイヤーは対象となる同意ポリシーのリストを受け取ります。プレイヤーは、QueryEligibleAgreements 関数を使用して対象となるポリシーの完全なリストを取得するか、まだ受諾されていない同意ポリシーのみを表示するようにフィルタリングできます。デフォルトでは、この関数は、存在する場合はキャッシュからリストを取得しようとし、キャッシュされたリストで見つからない場合にのみサービスに要求します。ただし、プレイヤーは、キャッシュされたリストを見ずに常にサービスに要求するように強制することもできます。完了すると、関数は OnQueryEligibilitiesCompletedDelegates をトリガーします。
const UWorld* World = GameEngine->GetGameWorld();
const IOnlineSubsystem* Subsystem = Online::GetSubsystem(World, ACCELBYTE_SUBSYSTEM);
const FOnlineSubsystemAccelByte* ABSubsystem = static_cast<const FOnlineSubsystemAccelByte*>(Subsystem);
FOnlineAgreementAccelBytePtr AgreementInterface = ABSubsystem->GetAgreementInterface();
if (AgreementInterface.IsValid())
{
AgreementInterface->AddOnQueryEligibilitiesCompletedDelegate_Handle(LocalUserNum
, FOnQueryEligibilitiesCompletedDelegate::CreateLambda([](int32 LocalUserNum, bool bWasSuccessful, const TArray<FAccelByteModelsRetrieveUserEligibilitiesResponse>& Response, const FString& ErrMessage)
{
UE_LOG(LogTemp, Log, TEXT("List of mandatory policies that need to accepted by user."));
for (auto Policy : Response)
{
if (Policy.IsMandatory && !Policy.IsAccepted)
{
UE_LOG(LogTemp, Log, TEXT("%s\n"), *Policy.PolicyId);
}
}
})
);
// To get only the not yet accepted policies
bool bNotAcceptedOnly = true;
// To always request it to service instead of get it from cached list
bool bAlwaysRequestToService = true;
AgreementInterface->QueryEligibleAgreements(LocalUserNum
, bNotAcceptedOnly
, bAlwaysRequestToService);
}
ローカライズされたポリシーコンテンツの取得
必要なポリシーのリストを取得した後、プレイヤーはポリシーコンテンツを読めるようにする必要があります。ポリシー ID とそのロケールコードを使用して GetLocalizedPolicyContent を使用して、ローカライズされたポリシーコンテンツを取得します。他のクエリと同様に、GetLocalizedPolicyContent は、デフォルトでキャッシュされたコンテンツを最初にチェックし、まだ存在しない場合はサービスに要求します。完了すると、関数は OnGetLocalizedPolicyContentCompletedDelegates をトリガーします。
const UWorld* World = GameEngine->GetGameWorld();
const IOnlineSubsystem* Subsystem = Online::GetSubsystem(World, ACCELBYTE_SUBSYSTEM);
const FOnlineSubsystemAccelByte* ABSubsystem = static_cast<const FOnlineSubsystemAccelByte*>(Subsystem);
FOnlineAgreementAccelBytePtr AgreementInterface = ABSubsystem->GetAgreementInterface();
if (AgreementInterface.IsValid())
{
AgreementInterface->AddOnGetLocalizedPolicyContentCompletedDelegate_Handle(LocalUserNum
, FOnGetLocalizedPolicyContentCompletedDelegate::CreateLambda([](int32 LocalUserNum, bool bWasSuccessful, const FString& Response, const FString& Error)
{
if (bWasSuccessful)
{
UE_LOG(LogTemp, Log, TEXT("Document: %s"), *Response);
}
})
);
// To always request it to service instead of get it from cached documents
bool bAlwaysRequestToService = true;
FString LocaleCode = "en";
// You should be able to get the policy id from the eligible agreement list
FString PolicyId = "";
AgreementInterface->GetLocalizedPolicyContent(LocalUserNum
, PolicyId
, LocaleCode
, bAlwaysRequestToService);
}
同意ポリシーの受諾
プレイヤーがポリシーコンテンツを読んだ後、まだ受諾されていない場合はポリシーを受諾できます。ポリシー ID とロケールコードでリストを入力することにより、ポリシーを一括で受諾します。完了すると、関数は OnAcceptAgreementPoliciesCompletedDelegates をトリガーします。リストに必須のドキュメントがある場合は、ログインもトリガーし、ユーザートークンを更新するため、プレイヤーはポリシーを受諾した直後にサービスを使用できるようになります。
const UWorld* World = GameEngine->GetGameWorld();
const IOnlineSubsystem* Subsystem = Online::GetSubsystem(World, ACCELBYTE_SUBSYSTEM);
const FOnlineSubsystemAccelByte* ABSubsystem = static_cast<const FOnlineSubsystemAccelByte*>(Subsystem);
FOnlineAgreementAccelBytePtr AgreementInterface = ABSubsystem->GetAgreementInterface();
if (AgreementInterface.IsValid())
{
AgreementInterface->AddOnAcceptAgreementPoliciesCompletedDelegate_Handle(LocalUserNum
, FOnAcceptAgreementPoliciesCompletedDelegate::CreateLambda([](int32 LocalUserNum, bool bWasSuccessful, const FString& Error)
{
if (!bWasSuccessful)
{
UE_LOG(LogTemp, Log, TEXT("Error: %s"), *Error);
}
})
);
TArray<FOnlineAgreementAccelByte::FABAcceptAgreementPoliciesRequest> DocumentToAccept;
FString LocaleCode = "en";
// You should be able to get the policy id from the eligible agreement list
FString PolicyId = "";
DocumentToAccept.Add({ PolicyId, LocaleCode });
AgreementInterface->AcceptAgreementPolicies(LocalUserNum, DocumentToAccept);
}