1. はじめに
前回の Vol.1の続き。
前回はホスティングサーバーへの接続までできたので、今度はマッチメイクの設定と認証をしていきます。
2. マッチメイクの設定
Unreal Game Servicesのダッシュボードに移動して、MatchMakerのセットアップのところまで移動します。

Integrate Matchmaker のボタンを押して、 Unreal API を押して次へ

Download API Specification のボタンを押して、別ブラウザで開かれた yaml ファイルを保存します。

次にキューの作成に進みます。
キュー名とMaxPlayerを指定します。

次にPoolの設定に進みます。
Pool名を入力して、Queueには先ほど作成したQueue、Timeoutは300秒などいれて次へ。

FleetとBuild Configurationも前回作成したものを選ぶ。

最後にルールを設定します。
ルール名を入力。RegionはAsisa、BackFillはTrueを選択しておきます。

あとは、希望のルール設定を入れる。

設定はできたので、あとは実際にマッチメイクの処理を追加していきます。
3. マッチメイク処理実装追加
UEに関しては、HTTPリクエストのそれぞれのAPIをたたく必要があるので、仕組みをいれていきます。
UE5にてHTTPリクエストできるようにするには以下などを参考に。
#UnrealEngine5 でHTTPリクエスト機能を実装してAPIコールしてみた | DevelopersIO
また、Unityのサンプルプロジェクトがあるので、こちらなど参考に。
3-1. 認証API
まずは認証のAPI。
https://services.docs.unity.com/docs/service-account-auth/index.html
クライアントからAPIをたたく際には、
- ClientAuthを使用
- ServiceAccountを使用
のどちらかの認証APIを先に叩いて、AuthTokenを取得する必要がある。
今回は手っ取り早くServiceAccountを使用します。
Service Account Authentication | Unity Services Web API docs
↑のドキュメント通りに。
まずは、サービスアカウントのキーIDとシークレットIDを作成します。
アカウントにログインして、Service Accountsの項目に移動して、以下の「Create Service Account」ボタンを押します。

サービスアカウント名と詳細を入力して、OKを押します。
サービスアカウントが作成されたので、Keysの Create Keyを押します。
すると以下のようにキーIDとシークレットIDがでてくるので、メモしておきます。

サービスアカウントの資格情報が欲しいので、以下のコマンドを実行します。(Unixでのコマンドなので、Windowsの標準コマンドプロンプトの場合は別途。。)
echo -n "{キーID}:{シークレットID}" | base64
すると、以下のようにハッシュが表示されます。(以下はサンプルの例)

これをメモっておきます。
マッチングのAPIでは ステートレストークンが必要になってきます。↓を参考。
Service Account Authentication | Unity Services Web API docs
ステートレストークンには PROJECT_ID と ENVIRONMENT_ID が必要になってくるので、サービスアカウントからメモしておきます。


これで、認証用のAPIを叩く準備ができました。
メモした
- サービスアカウントの資格情報のハッシュ(Basicをつけて)
- PROJECT_ID
- ENVIRONMENT_ID
こちらを Config.csに追加しておきます。

初期化のタイミングで以下のように HTTPリクエストを送るようにします。
void ACPP_MatchUI::BeginPlay()
{
Super::BeginPlay();
// Auth設定
MatchAuth = NewObject();
if (MatchAuth)
{
MatchAuth->Request();
}
}
void UCPP_MatchAuth::Request()
{
// URLを作成
const FString URL = TEXT("https://services.api.unity.com/auth/v1/token-exchange") + TEXT("?projectId=") + PRODUCT_ID + TEXT("&environmentId=") + ENVIROMENT_ID;
UHTTP* Request = NewObject();
Request->Request(*URL, EHttpVerbs::POST, *BASIC_TOKEN, TEXT(""), [=](const FString& Response)
{
// レスポンスをパース
TSharedPtr JsonObject;
TSharedRef> Reader = TJsonReaderFactory<>::Create(Response);
if (FJsonSerializer::Deserialize(Reader, JsonObject))
{
// AuthTokenを取得
AuthToken = JsonObject->GetStringField(TEXT("accessToken"));
}
});
}
HTTPリクエストのサンプルは以下。
void UHTTP::Request(
const FString& Url,
const EHttpVerbs Verb,
const FString& Header,
const FString& Body,
const TFunction Callback)
{
// HTTPリクエストオブジェクト作成
const FHttpRequestRef Request = FHttpModule::Get().CreateRequest();
// HTTPリクエスト完了時に実行する関数のポインタをセット
Request->OnProcessRequestComplete().BindWeakLambda(this, [=](FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool ConnectionSuccessfully)
{
if (HttpResponse)
{
// UEでログ出力(APIから受け取った文字列そのまま)
UE_LOG(LogTemp, Log, TEXT("UHTTP:Response %s"), *HttpResponse->GetContentAsString());
FColor DisplayColor = FColor::Green;
if (!ConnectionSuccessfully)
{
DisplayColor = FColor::Red;
}
// 画面上に表示
GEngine->AddOnScreenDebugMessage(-1, 3.0f, DisplayColor, FString::Printf(TEXT("HTTP Response!!! Response(%s)"), *HttpResponse->GetContentAsString()), true, FVector2D(1.0f, 1.0f));
// Callback実行
Callback(*HttpResponse->GetContentAsString());
}
});
// HTTPリクエストのURLをセット
Request->SetURL(Url);
UEnum* const Enum = FindObject(ANY_PACKAGE, TEXT("EHttpVerbs"));
const FString VerbString = Enum->GetNameStringByIndex(static_cast(Verb));
// HTTPリクエストのメソッドをセット
Request->SetVerb(VerbString);
// HTTPリクエストのヘッダーをセット
Request->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
if (!Header.IsEmpty())
{
UE_LOG(LogTemp, Log, TEXT("UHTTP:Request Authorization : %s"), *Header);
Request->SetHeader(TEXT("Authorization"), Header);
}
// HTTPリクエストのボディをセット
UE_LOG(LogTemp, Log, TEXT("UHTTP:Request Verb : %s, Url : %s, Body : %s"), *VerbString, *Url, *Body);
Request->SetContentAsString(Body);
Request->SetContentAsString(Body);
// HTTPリクエスト実行
Request->ProcessRequest();
// 画面上に表示
GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Yellow, FString::Printf(TEXT("HTTP Request!!! Url(%s)"), *Url), true, FVector2D(1.0f, 1.0f));
}
上記を追加して、ゲームをプレイします。以下のようにaccessTokenを取得できるかと思います。

これでようやくマッチメイクのAPIを叩く準備ができました。
次は実際にマッチメイクのAPIを叩いて、動作を確認していきます。