コンテンツにスキップ
Get Started

Unreal SDK セットアップ

FirstLook Unreal SDK は Unreal Engine プラグインであり、Unreal ゲームから FirstLook とのインターフェースを可能にします。このプラグインは現在、Steam ログイン、ゲーム内アンケート、セッション追跡、カスタムイベント、カスタム期間イベント、プレイヤールックアップ、PlayFab アイデンティティリンク、エンタイトルメント、プレイテストウォーターマークをサポートしています。 FirstLook SDK の主要なアクセスポイントは UFirstLookSubsystem であり、FirstLook とのインタラクションに使用されるいくつかのメソッドとデリゲートを公開しています。

このセットアップガイドでは、MyGame という名前の Unreal ゲームプロジェクトがあることを前提とします。

  1. 管理ダッシュボードから FirstLookSDK を取得してください。 Download
SDK

  2. Unreal SDK 設定ファイルを生成してください。 SDK Config
  3. FirstLook で Steam ゲームをセットアップしてください。Steam Integration を参照してください。
  4. Steam アカウントをリンクしたテストプレイヤーをプレイテストに招待してください。プレイヤーの招待を参照してください。

Unreal への FirstLookSDK プラグインのセットアップ

Section titled “Unreal への FirstLookSDK プラグインのセットアップ”

FirstLookSDK を取得し、FirstLook でゲームをセットアップしたら、Unreal プロジェクトにプラグインをインストールできます。

  1. FirstLookSDK プラグインを MyGame/Plugins/FirstLookSDK に移動してください。MyGame/Plugins ディレクトリが存在しない場合は作成してください。

  2. MyGame.uproject ファイルに FirstLookSDK プラグインを登録してください。

    "Plugins": [
    {
    "Name": "FirstLookSDK",
    "Enabled": true
    }
    ]
  3. MyGame.Build.cs ファイルに FirstLookSDK プラグインを依存関係として追加してください。

    PrivateDependencyModuleNames.AddRange(new string[] {"FirstLookSDK"});
  4. Unreal Editor で、以下のパスから FirstLookApiURL、FirstLookClientURL、FirstLookGameSlug に対する FirstLookSDK プラグイン設定を構成してください:

    Edit > ProjectSettings > Plugins > FirstLook Plugin Settings

    • あるいは、DefaultGame.ini ファイルでプラグインを設定することもできます:

      [/Script/FirstLookSDK.FirstLookSDKSettings]
      FirstLookApiURL="https://api.firstlook.gg"
      FirstLookClientURL="https://<game-slug>.firstlook.gg"
      FirstLookGameSlug="<game-slug>"

      (<game-slug> をあなたの FirstLook ゲームスラグに置き換えてください)

    クライアント URL を確認するには、FirstLook 設定でドメインを確認してください: Client URL

  5. DefaultEngine.ini ファイルに OnlineSubsystemSteam を設定してください。

    [OnlineSubsystem]
    DefaultPlatformService=Steam
    [OnlineSubsystemSteam]
    bEnabled=true
    SteamDevAppId=<steam-app-id>

    (<steam-app-id> をあなたの Steam アプリ ID に置き換えてください)

    SDK は実行中の Steam クライアントから Steam アプリ ID を読み取り、Steam が利用できない場合のみ SteamDevAppId にフォールバックします。したがって、単一のパッケージビルドを複数の Steam アプリ ID に対してリリースすることができ、プレイヤーが実際に起動したアプリを報告します。SteamDevAppId は OnlineSubsystemSteam を初期化するために必要であり、エディター内で使用される値であり続けます。

  6. Unreal CommonUI をセットアップしてください。

    • このガイドのステップ 1 に従い、デフォルトの Game Viewport Client Class を CommonGameViewportClient に設定してください。

FirstLookSDK Unreal プラグインが正しくセットアップされたので、FirstLook Steam ログインは FirstLook サブシステムの初期化時に自動的に呼び出されるため、そのまま機能します。 ローカルでインテグレーションをテストするためにいくつかの手順を踏む必要があります。

  1. Unreal Editor でスタンドアロンゲームモードのログを有効にしてください

    • Edit > Editor Preferences で以下に移動してください:

      Level Editor > Play > Play in Standalone Game > Additional Launch Parameters

    • -log を起動パラメーターとして追加してください

    • Standalone Logging

  2. スタンドアロンゲームとしてプレイしてください

  3. 出力ログに、LogFirstLookSDK ログカテゴリからログインが成功したことを示すログ行が表示されるはずです

    • 例: LogFirstLookSDK: Verbose: Login succeeded.

サブシステムは初期化時に一度だけ認証を行います: Steam チケットとアプリ ID が利用可能な場合は Steam で認証し、それ以外の場合は匿名で認証します。認証完了前に行われた呼び出しはキューに入れられません。SDK はそれらをスキップし、次の単一の警告をログに記録します:

LogFirstLookSDK: Warning: FirstLook is not authenticated yet; <url> was skipped. Wait for OnFirstLookReady before calling the SDK.

スキップされた呼び出しは通常、返答を受け取らないため、デリゲートが発火することはありません。一部の呼び出しは代わりにすぐに応答するため、呼び出す前にデリゲートをバインドしてください: エンタイトルメント呼び出しは 401 および Not authenticated で失敗デリゲートを発火し、PostEvent、GetFeedbackSurvey、GetTriggeredSurveys はアンケートが利用不可であることを報告します。

認証が失敗した場合、SDK はこのセッションですべての FirstLook API 呼び出しがスキップされることをログに記録し、OnAuthenticationFailed を発火させます。失敗したログインはゲームが再起動するまで継続します。

OnFirstLookReady と OnAuthenticationFailed はネイティブイベントのため、AddUObject または AddLambda でバインドしてください。それぞれ一度だけ発火するため、バインド前に認証が完了した場合に備えて、まず IsAuthenticated() と HasAuthenticationFailed() を確認してください。

void UMainMenu::NativeConstruct()
{
Super::NativeConstruct();
if (UFirstLookSubsystem* FirstLook = GetOwningLocalPlayer()->GetSubsystem<UFirstLookSubsystem>())
{
if (FirstLook->IsAuthenticated())
{
HandleFirstLookReady();
}
else if (FirstLook->HasAuthenticationFailed())
{
HandleFirstLookFailed();
}
else
{
FirstLook->OnFirstLookReady.AddUObject(this, &UMainMenu::HandleFirstLookReady);
FirstLook->OnAuthenticationFailed.AddUObject(this, &UMainMenu::HandleFirstLookFailed);
}
}
}

FirstLook へのログインが成功するようになったので、FirstLook サブシステムを使用してゲーム内アンケートをトリガーできます。

  1. ゲームクライアント配信を有効にしたアンケートを作成してください。アンケートの作成を参照してください。

  2. 新しく作成したアンケートのトリガーをセットアップしてください。トリガーのセットアップを参照してください。

  3. Unreal でアンケートデリゲートを登録してください:

    UFirstLookSubsystem::OnNewNativeSurveyAvailable:

    • このデリゲートが呼び出されたときに WBP_Survey_Screen ウィジェットを表示する必要があります。 このウィジェットは以下の場所にあります: MyGame/Plugins/FirstLookSDK/Content/UI_Survey/Widgets/WBP_Survey_Screen.uasset

    UFirstLookSubsystem::OnNewBrowserSurveyAvailable:

    • デフォルトで UFirstLookSubsystem::ActivateSurveyBrowserOverlay を使用して Steam ブラウザーオーバーレイを表示するようにフックされています

  4. アンケート用に作成したトリガーを使用して UFirstLookSubsystem::PostEvent を呼び出してください。 トリガー条件が満たされると、設定されたアンケート配信チャンネルに応じて、前の手順でセットアップしたデリゲートのいずれかがトリガーされます。

FirstLook SDK は、追加のコードなしにプレイヤーセッションを自動的に追跡します。セッションは UFirstLookSubsystem が初期化されたときに開始し、ゲームクライアントが正常にシャットダウンしたときに終了します。FirstLook アカウントをまだ作成していないプレイヤーも追跡されます—ダッシュボードではリンクされていないプレイヤーとして表示され、サインインしている場合は Steam アカウントが関連付けられます。

セッションが記録されると、Analytics ページの Retention タブ、および各プレイヤープロフィールでプレイヤーアクティビティとセッション期間データを確認できます。

自動セッション追跡に加えて、スタジオにとって最も重要なことをキャプチャするための独自のゲームプレイイベントを計測できます—ヒーローの選択、マッチの結果、ストアでの購入など。UFirstLookSubsystem の PostCounterEvent メソッドを使用して、整数値を持つ名前付きカウンターを送信できます:

UCLASS()
class FIRSTLOOKSDK_API UFirstLookSubsystem : public ULocalPlayerSubsystem
{
public:
// ...
UFUNCTION(BlueprintCallable, Category = FirstLook)
void PostCounterEvent(FString CounterName, int32 Count);
UFUNCTION(BlueprintCallable, Category = FirstLook)
void PostCounterEventWithParam(FString CounterName, FString Param, int32 Count);
// ...
}

以下は UCommonActivatableWidget からカウンターイベントを送信する例です。この場合、プレイヤーがロードアウト画面でヒーローを選択したことを記録しています:

void UMainMenu::HandleSendCounterEventClicked()
{
if (ULocalPlayer* OwningLocalPlayer = GetOwningLocalPlayer();
OwningLocalPlayer != nullptr)
{
if (UFirstLookSubsystem* FirstLookSubsystem =
OwningLocalPlayer->GetSubsystem<UFirstLookSubsystem>())
{
FirstLookSubsystem->PostCounterEvent("loadout.hero-a-selected", 1);
}
}
}

イベント名は <category>.<event-type> の規則に従います。このパターンを使用すると、FirstLook は関連するイベントをAnalytics ページおよびプレイヤープロフィールで自動的にグループ化し、カテゴリ別にメトリクスを参照しやすくします。

ゲーム内でイベントが発生する場所を反映したカテゴリ名前空間を選択してください—例えば、match、lobby、menu、store、in-game など。必要なだけカテゴリを自由に定義できます。

PostCounterEventWithParam を使用すると、プレイヤーが開始したレベルや購入したアイテムなど、1 つのイベントをバリアントに分割できます。新しいイベント名を定義することなく分割できます。同じ関数は Blueprint で Post Counter Event With Param ノードとして利用できます。

void UGameplayHud::HandleLevelStarted(const FString& LevelId)
{
if (ULocalPlayer* OwningLocalPlayer = GetOwningLocalPlayer();
OwningLocalPlayer != nullptr)
{
if (UFirstLookSubsystem* FirstLookSubsystem =
OwningLocalPlayer->GetSubsystem<UFirstLookSubsystem>())
{
FirstLookSubsystem->PostCounterEventWithParam("level.started", LevelId, 1);
}
}
}

FirstLook はバリアントを level.started#forest_3 として保存し、Analytics ページのベースイベント下にチャート表示し、すべてのバリアントをベース合計に集計します。パラメーターはトリムされ小文字化され、最大 64 文字で # を含んではなりません。空のパラメーターはプレーンイベントを送信し、PostCounterEvent はそのまま動作し続けます。各固有のパラメーターは独自のバリアントとして追跡されるため、値のセットは小さく保ってください。

カウンターイベントは何かが発生したことを記録しますが、どれくらいの時間 かかったかを知る必要がある場合もあります。期間イベントを使用すると、ゲーム内の2つの明示的な時点間の経過時間を計測できます—マッチ、ロード画面、メニューに費やした時間、または追跡したい他のスパンなど。

SDK は UFirstLookSubsystem に StartDurationEvent / EndDurationEvent ペアを公開しています:

UCLASS()
class FIRSTLOOKSDK_API UFirstLookSubsystem : public ULocalPlayerSubsystem
{
public:
// ...
UFUNCTION(BlueprintCallable, Category = FirstLook)
void StartDurationEvent(FString DurationName);
UFUNCTION(BlueprintCallable, Category = FirstLook)
void EndDurationEvent(FString DurationName);
// ...
}

アクティビティが開始されたときに StartDurationEvent を呼び出し、終了したときに EndDurationEvent を呼び出してください。SDK がタイミングと配信を処理します—名前を指定するだけです。

以下は、プレイヤーがマッチに費やした時間を追跡する例です。StartDurationEvent はマッチ開始時に呼び出され、EndDurationEvent はマッチ終了時に呼び出されます:

void AMyGameMode::OnMatchStart()
{
for (APlayerController* PC : GetWorld()->GetPlayerControllerIterator())
{
if (ULocalPlayer* LP = PC->GetLocalPlayer())
{
if (UFirstLookSubsystem* FirstLook = LP->GetSubsystem<UFirstLookSubsystem>())
{
FirstLook->StartDurationEvent("match.round");
}
}
}
}
void AMyGameMode::OnMatchEnd()
{
for (APlayerController* PC : GetWorld()->GetPlayerControllerIterator())
{
if (ULocalPlayer* LP = PC->GetLocalPlayer())
{
if (UFirstLookSubsystem* FirstLook = LP->GetSubsystem<UFirstLookSubsystem>())
{
FirstLook->EndDurationEvent("match.round");
}
}
}
}

期間イベント名はカウンターイベントと同じ <category>.<event-type> 規則に従います。FirstLook はAnalytics ページでカテゴリプレフィックスによって自動的にグループ化します。

セッション、カウンターイベント、期間イベントはそれぞれ build_version を記録します。FirstLook はそれを不透明なテキストとして保存するため、フォーマットは完全にスタジオの選択次第です: semver、CI ビルド番号、ブランチ+コミット文字列など。プレイヤーフィルターのビルドフィルターは完全一致で適合するため、1 つの規則を選択して安定させてください。

デフォルトでは SDK がプロジェクトバージョンを読み取るため、設定は不要です: UFirstLookSubsystem は起動時に [/Script/EngineSettings.GeneralProjectSettings] から ProjectVersion を読み取ります。これは Project Settings > Project > Description > Version で設定する値です。

代わりに独自の値を提供するには、OverrideBuildVersion(Blueprint および C++ で利用可能)を呼び出してください:

FirstLook->OverrideBuildVersion(TEXT("1.4.2"));

GetCurrentPlayer を呼び出し、OnCurrentPlayerAvailable をバインドして、認証済みプレイヤーの FirstLook レコードを読み取ってください。例えば、クレームプロンプトを表示するかどうかを決定するために使用できます。

void UMainMenu::RefreshPlayer()
{
UFirstLookSubsystem* FirstLook = GetOwningLocalPlayer()->GetSubsystem<UFirstLookSubsystem>();
FirstLook->OnCurrentPlayerAvailable.AddUniqueDynamic(this, &UMainMenu::HandleCurrentPlayer);
FirstLook->GetCurrentPlayer();
}
// AddDynamic が要求するため、UFUNCTION として宣言されています。
void UMainMenu::HandleCurrentPlayer(const FFirstLookCurrentPlayerResponse& CurrentPlayer)
{
if (CurrentPlayer.player.IsUnlinked())
{
GetOwningLocalPlayer()->GetSubsystem<UFirstLookSubsystem>()->GetPlayerClaim();
}
}

FFirstLookCurrentPlayerResponse は player(id、state)、steam(steam_id、Steam アカウントがリンクされていない場合は空)、discord(discord_id)、role(id、name)を保持しています。state はプレイヤーのステートの小文字文字列です。

OnCurrentPlayerAvailable は成功時のみ発火します。失敗は GetCurrentPlayer failed: ... としてログに記録されます。

リンクされていないプレイヤーのオンボーディング

Section titled “リンクされていないプレイヤーのオンボーディング”

SDK は新しいプレイヤーをリンクされていない状態で作成します。これらのプレイヤーにアカウントをクレームしてプロフィールを完成させるためのリンクを提供できます。これにより、メール、報酬、Discord、フレンド招待、およびロールが提供するその他のすべてがアンロックされます。

リンクされていないプレイヤーをオンボーディングするには、まずダッシュボードで From Game フローを設定してください。

  1. SDK 設定ページで Unlinked Claiming トグルを有効にしてください。
  2. From Game フローの Claim、Onboarding、Complete ステップを設定してください。
  3. オプション - ロールを設定してください。

From Game フローが設定されたら、ゲームクライアントは SDK メソッド UFirstLookSubsystem::GetPlayerClaim を呼び出し、OnPlayerClaimAndCodeAvailable デリゲートにバインドできます。デリゲートがトリガーされると、URL と Base64 エンコードされた QR コードが提供されます。このリンクまたは QR コードをプレイヤーに提示して、メール確認と From Game フローで設定されたオンボーディングステップを完了できるようにしてください。

外部アイデンティティのリンク

Section titled “外部アイデンティティのリンク”

認証が完了したら、LinkIdentity を呼び出してプロバイダー名とそのサービスでのプレイヤー ID を提供し、FirstLook が 2 つのレコードを照合できるようにします。PlayFab は現在サポートされている唯一のプロバイダーです:

FirstLook->LinkIdentity(TEXT("playfab"), PlayFabId);

LinkIdentity はログにのみ結果を報告します。リンクの失敗は Failed to link identity playfab (response code ...) と理由とともにログに記録されます: リンクがゲームで有効になっていない場合は 403(FirstLook に連絡してください)、ID が別のプレイヤーに属している場合は 409、ID が空または 64 文字を超える場合は 422。プレイヤー自身の ID の再リンクは成功するため、起動のたびに呼び出しても安全です。

エンタイトルメントは FirstLook からプレイヤーに付与するゲーム内アイテムです。SDK は FirstLook タイプのエンタイトルメントを配信します: ダッシュボードの Entitlements でエンタイトルメントを作成し、例えば Grant Entitlement 一括アクションを使用してプレイヤーに付与します。ゲームはプレイヤーの未配信エンタイトルメントを取得し、アイテムを付与して、再配信されないように各エンタイトルメントを換金します。Pragma エンタイトルメントは代わりに Pragma を通じて配信され、ここには表示されません。ダッシュボードに Entitlements が表示されない場合は、FirstLook に連絡して有効にしてください。

呼び出し成功失敗
GetEntitlements()OnEntitlementsAvailable(Entitlements)、存在しない場合は空の配列OnEntitlementsRequestFailed(StatusCode, Error)
RedeemEntitlement(EntitlementId)OnEntitlementRedeemed(EntitlementId, RedeemedAt)OnEntitlementRedeemFailed(EntitlementId, StatusCode, Error)
void UInventoryWidget::NativeConstruct()
{
Super::NativeConstruct();
if (UFirstLookSubsystem* FirstLook = GetOwningLocalPlayer()->GetSubsystem<UFirstLookSubsystem>())
{
FirstLook->OnEntitlementsAvailable.AddDynamic(this, &UInventoryWidget::HandleEntitlements);
FirstLook->GetEntitlements();
}
}
void UInventoryWidget::HandleEntitlements(const TArray<FFirstLookEntitlement>& Entitlements)
{
UFirstLookSubsystem* FirstLook = GetOwningLocalPlayer()->GetSubsystem<UFirstLookSubsystem>();
for (const FFirstLookEntitlement& Entitlement : Entitlements)
{
// Entitlement.id をキーにして付与することで、再試行しても一度だけアイテムが付与されます。
GrantItemOnce(Entitlement.id, Entitlement.sku);
FirstLook->RedeemEntitlement(Entitlement.id);
}
}

各 FFirstLookEntitlement は id、entitlement_type、name、sku、redeemable_type_id、created_at を保持しています。アイテムはダッシュボードで設定した Entitlement ID である sku で照合してください。翻訳または名前変更される可能性のある表示文字列である name では照合しないでください。

換金は一度限りです。同じエンタイトルメントを再度換金すると 400 および Entitlement already redeemed で失敗します。これは通常、以前の試みが成功したことを意味するため、完了済みとして扱ってください。

ウォーターマークオーバーレイ

Section titled “ウォーターマークオーバーレイ”

SDK はプレイテストビルドにウォーターマークを付与できます。各セッションは固有のコードを取得し、SDK はそれを画面全体に角度をつけてタイル表示し、ゆっくりとドリフトさせます。クロッピングで削除できないよう、中央は常にカバーされています。スクリーンショットやストリームが漏洩した場合、コードによってそのプレイヤーとセッションを特定できます。

  1. SDK 設定ページで Playtest Watermark の下の Enable Watermark をオンにし、Save Changes をクリックしてください。
  2. セッション開始後、SDK はセッションのコードを取得し、最初のローカルプレイヤーのビューポートに自動的にオーバーレイを描画します。
  3. 漏洩を追跡するには、Search watermark ページでコードを入力し、属するプレイヤーとセッションを見つけてください。

FirstLook はウォーターマークのオン・オフのみを制御します。外観はプロジェクト内の Edit > Project Settings > Plugins > FirstLook の Watermark セクション、または DefaultGame.ini で設定します:

[/Script/FirstLookSDK.FirstLookSDKSettings]
WatermarkOpacity=0.18
WatermarkTileDensity=5.0
WatermarkAngleDegrees=30.0
WatermarkDriftSpeed=0.5
bWatermarkIncludeCenter=True
設定デフォルト範囲効果
WatermarkColorWhiteテキストカラー
WatermarkOpacity0.180 〜 1テキストの不透明度
WatermarkTileDensity5.01 〜 12画面幅に収まるコードのおよその数
WatermarkAngleDegrees30.00 〜 90グリッドの傾き
WatermarkDriftSpeed0.50 〜 20 でグリッドを静止させる
bWatermarkIncludeCentertrue画面中央をカバーし続ける

OnWatermarkEnabled はオーバーレイが表示されたときにセッションごとに一度発火し、コードを持ち運びます。オーバーレイはそれ自体でレンダリングされるため、プレイヤーにセッションがウォーターマークされていることを伝えたい場合のみバインドしてください。Blueprint では On Watermark Enabled として利用できます。

ウォーターマークがゲームで有効になっていない場合、SDK は Watermark: watermarking is not enabled for this game. Contact FirstLook to enable it. をログに記録し、オーバーレイなしでゲームが実行されます。一時的なフェッチの失敗は再試行され、フェッチが繰り返し失敗した場合もゲームはオーバーレイなしで実行され続けます。