実装事例紹介:Firebase Analyticsでカスタムイベントログ収集

はじめに

こんにちは、アプリボット ゲームプログラマの220Rnです。

iOS/Android用リズムゲーム『グリメロ~グリモワールメロディプロジェクト~』
(以下、グリメロ)をリリースするにあたり、
Firebase 向け Googleアナリティクス(以下、Firebase Analytics)を導入しました。
採用理由と使用方法について共有します。

 

(2018年1月時点の情報になります)

『グリメロ~グリモワールメロディプロジェクト~』
グリメロ.png

【iOS版】
https://itunes.apple.com/jp/app/id1327285628
【Android版】
https://play.google.com/store/apps/details?id=jp.co.applibot.grimelo

背景

グリメロは主にプロモーション目的のアプリであり、課金要素は一切なく、完全無料で遊べます。
また、サーバーもなくクライアントだけで動作するアプリとなっているのですが、
ユーザのプレイ動向などは収集したい(できるだけコストをかけずに)…という要望がでてきます。
そんなときにこそ、Firebase Analyticsの出番です。

Firebase Analyticsとは

公式ページより引用すると以下の通りです。

Firebase 向け Googleアナリティクス
Firebase 向け Google アナリティクスは、アプリの使用状況とユーザー
エンゲージメントについて分析することができる、無料のアプリ測定ソリューションです。
https://firebase.google.com/docs/analytics/?hl=ja

まず、無料で扱えるという点で本プロジェクトには非常にマッチしています。
Unityプロジェクトにも対応しており、

Unity 用 Firebase 向け Google アナリティクスを使ってみる
https://firebase.google.com/docs/analytics/unity/start?hl=ja

こちらの手順に従ってスムーズな導入が可能です。

SDKの導入をするとデフォルトで起動ログなどの収集が開始され、
アクティブユーザー数などは個別に対応することなく取得できます。

自動的に収集されるイベント
https://support.google.com/firebase/answer/6317485?hl=ja

さらに、イベントログを自由に仕込むことが可能です。
例えば「リズムゲームのリザルト情報」を次のような
カスタムログイベントとして送ることができます。

// クロックワークラブロマンス
Firebase.Analytics.FirebaseAnalytics.LogEvent(
  "play_result",
  new Firebase.Analytics.Parameter[] {
      new Firebase.Analytics.Parameter(
        "difficulty", 0),
      new Firebase.Analytics.Parameter(
        "music", "クロックワークラブロマンス"),
      new Firebase.Analytics.Parameter(
        "rank", "S"),
      new Firebase.Analytics.Parameter(
        "score", "95000"),
  }
);

上記例のように自由に項目を追加していくことが可能なので、
欲しいデータを設計して送信していけばよさそうです。
500種類までという制限はありますが、これでイベントを追加していけば
あらゆるデータが取り放題です。

・・・しかしそう簡単には行きません。

問題点

実はFirebase Analyticsだけでは、カスタムデータの詳細を見ることができません。

イベントをロギングする
https://firebase.google.com/docs/analytics/unity/events?hl=ja#log_events
カスタム パラメータ: カスタム パラメータはアナリティクス レポートには記載されませんが、ユーザーリストの定義の際にフィルタとして使用できます。定義したユーザーリストはあらゆるレポートに適用できます。アプリが BigQuery プロジェクトとリンクされている場合、カスタム パラメータは BigQuery にエクスポートされるデータにも含まれます。

あくまでFirebase Analyticsでは統計処理されたデータを参照するツールなので個々を
見ることはできません。BigQueryと連携することで初めて生データを
取得することができます。しかしながらBigQueryとの連携には従量課金の
コストが生じ、できるだけコストをかけずにやりたいという点に反してしまいます。

また、カスタムイベントの統計値はイベント数の「合計のみ」という作りになっています。
(サブパラメータを沢山追加しても集計はされず、イベント発行数のみの合計値になってしまいます)

上記例でいうと、play_resultのイベント送信数しか分からず、
各楽曲のプレイ回数やクリアランクまでは分かりません。

しかしながら工夫して使えば無料範囲に収められるのではないかと考え、
いろいろと試行錯誤をしてみました。

今回収集したいデータ

グリメロはシンプルなリズムアクションゲームで、課金もないため
独自で欲しい収集データも数も多くはありません。

◆各楽曲のプレイ回数
例)クロックワークラブロマンスのプレイ回数

◆どの難易度を選択していたか
例)難易度ハードのプレイ回数

◆どの程度のリザルトだったか(クリアランク)
例)Reason of LifeのハードはどれくらいAランククリアされているか

◆ゲームの進行(達成)状況
例)各楽曲のライブラリ情報はどれくらい解禁されているか
  難易度EXPERTはどれくらい解禁されているか
  ミスティックモードはどれくらい解禁されているか、など

推奨イベントをうまく利用する

Firebase Analyticsでは推奨イベントが用意されています。

Firebase.Analytics.FirebaseAnalytics
https://firebase.google.com/docs/reference/unity/class/firebase/analytics/firebase-analytics?hl=ja#eventaddpaymentinfo

こちらが公式で提供されている推奨イベントです。これらを使用すると、
イベントによってはある程度の内包するデータまで参照できるようになります。
こちらを上手に利用するのが本稿の肝となります。
すべてのイベントは検証できていませんので、今回使用したものについてピックアップして説明します。

イベント: ゲーム
https://support.google.com/firebase/answer/6317494?hl=ja&ref_topic=6317484

こちらのゲーム用に用意されたイベントから、以下の2つをピックアップしました。
このページに記載されているイベントは集計値の詳細が見られるものと思われます。

EventSelectContent

イベント名: select_content
タイミング:ユーザーがアプリ内でコンテンツを選択したとき。
パラメータ:content_type、item_id

本来はモードの選択などをイベントとして記録するものになります。
以下、架空の格闘ゲームで想定されるモード選択&キャラ選択における使用例です。

イベント content_type item_id
1Pモードを「シマウマ」で開始 mode_1player シマウマ
2Pモードを「キリン」で開始 mode_2player キリン
エンドレスモードを「トラ」で開始 mode_endless トラ

今回はこれを楽曲&難易度選択およびリザルト取得に流用します。

イベント content_type item_id value
楽曲コード「music1」を難易度「1」でランク「S」クリア music1_1 S 100000
楽曲コード「music2」を難易度「1」でランク「A」クリア music2_1 A 91000
楽曲コード「music3」を難易度「2」でランク「C」クリア music3_2 C 50000

ポイントとしては、「楽曲コード_難易度」というフォーマットにしており、
content_typeに二つの意味を内包させたところです。

また、valueにはスコアを入れていますが、こちらは全イベントの累積値のみしか参照できません。
運用で「全ユーザの全リザルトのスコア合計が100億点を超えたら限定壁紙プレゼントキャンペーン」などを
実施することになったら使用できるレベルのものです。(現状使用していません)

実装は以下のような感じになります。
(便宜上”music1_1″など固定値になっている箇所は実際は変数)

Result.cs
Firebase.Analytics.FirebaseAnalytics.LogEvent 
    (Firebase.Analytics.FirebaseAnalytics.EventSelectContent, 
        new Firebase.Analytics.Parameter[]{
            new Firebase.Analytics.Parameter (
                Firebase.Analytics.FirebaseAnalytics.ParameterContentType, "music1_1",
            new Firebase.Analytics.Parameter (
                Firebase.Analytics.FirebaseAnalytics.ParameterItemId, "S"),
            new Firebase.Analytics.Parameter (
                Firebase.Analytics.FirebaseAnalytics.ParameterValue, 100000),
        }
    );

グリメロで使用したものは、コンソール上で次のように確認することができます。
(掲載内容は開発中のものです)

<全楽曲+難易度別の一覧表示>

content_select.png

<楽曲のリザルト一覧表示>

result_rank.png

これで各楽曲×難易度の選曲数と大まかなリザルト情報を取得することが出来ました。
某曲某難易度のゲームデータがどれくらい難しかったかなどを統計的に見ることが出来ます。

EventSpendVirtualCurrency

イベント名:spend_virtual_currency
タイミング:ユーザーがアプリ内で仮想通貨(コイン、宝石、トークンなど)を使ったとき。
パラメータ:item_name、virtual_currency_name、value

本来はコインなどのゲーム内通貨を使用した際に発行するイベントです。

イベント item_name virtual_currency_name value
「攻撃アップカード」をコイン100枚で購入した 攻撃アップカード コイン 100
「防御アップカード」をコイン200枚で購入した 防御アップカード コイン 200

上記のような購入イベントを集計して、全ユーザでどのアイテムに何を消費したかなどを
一覧することができます。上記例では、攻撃アップカードが何回100コインで購入されたかを
参照することができます。

どのアイテムがいくら売れたかを一覧できる機能を備えているので、
今回はこれをミッションの達成状況の記録に流用します。

イベント item_name virtual_currency_name value
ミッションID「101」を達成 101 101 1
ミッションID「201」を達成 201 201 1

※valueは購入金額ですが、ミッションの達成数に置き換えるため「1」固定としました。

実装は以下のような感じになります。
(”101″と固定値になっている箇所は実際はミッションIDの変数)

UserInfoSystem.cs
Firebase.Analytics.FirebaseAnalytics.LogEvent 
    (Firebase.Analytics.FirebaseAnalytics.EventSpendVirtualCurrency, 
        new Firebase.Analytics.Parameter[]{ 
            new Firebase.Analytics.Parameter(Firebase.Analytics.FirebaseAnalytics.ParameterItemName, "101"),
            new Firebase.Analytics.Parameter(Firebase.Analytics.FirebaseAnalytics.ParameterVirtualCurrencyName, "101"),
            new Firebase.Analytics.Parameter(Firebase.Analytics.FirebaseAnalytics.ParameterValue, 1),
        }
    );

以上の実装でイベントログを送信すると次のように確認することが出来ます。
各ミッションがどれくらいの人数に達成されているかを確認可能です。

FirebaseEvent_03.png

これでミッションの達成状況を取得することが出来ました。
あとはゲームの進行状況をミッションIDで管理するようにすれば対応完了です。
(グリメロでは、難易度解禁やモードの解放などをミッションクリア情報として送っています)

表記上は「商品アイテム名」になっていますが、「ミッションID」と読み替えて利用します。
そのため、あとで混乱しないようにドキュメントを記載しておく必要があります。

終わりに

グリメロでは、Firebase Analyticsを利用することで運用コストゼロを実現しました。

Firebase Analyticsの無料という強みを活かして、極力コストを削減したい小規模開発への
利用もある程度までであれば十分出来ると思います。また、運用コストを掛けられないような
個人のアプリ開発などにも利用できそうです。収集したい統計値に合わせてカスタマイズしてください。

また、公式が想定している使い方とは異なる方法になるため、
ドキュメントなどを詳細に記しておく必要がある点、特に記載項目と異なる内容で
運用することになる点についてはご注意ください。