ゲームにアチーブメントを追加する

Rajen Kishna、Epic Games テクニカル アカウント マネージャー |
2022年1月25日
前の 2 つの投稿では、Stats (統計)Leaderboards (リーダーボード) について説明しました。ここでは、「Achievements (アチーブメント) インターフェース」を追加する方法について見ていきます。アチーブメントのロックは、統計の進行状況に基づいて自動的に解除したり、API を使用して手動で解除したりできます。この記事では、次の内容を扱います。
 

Epic Online Services アチーブメント と Epic アチーブメント

Epic Online Services のアチーブメントの実装について解説する前に、2021年10月にアナウンスされた Epic Online Services (EOS) のアチーブメントと (執筆時点での早期アクセス版の) Epic のアチーブメントの関係と違いについて説明します。
Epic Online Services (EOS) アチーブメント
  • Epic Online Services (EOS) のアチーブメントは、多くの Epic Online Services の機能と同様、実装するゲームのプラットフォームに依存しません。 
  • EOS アチーブメントを使用すると、独自のゲーム内 UI で進行状況を追跡したり、アチーブメントのロックを解除したりできます。 
  • EOS アチーブメントは、便宜上「オーバーレイ」によってレンダリングされますが、必ずしも Epic Games ストアのゲームにリンクされているとは限りません。したがって、Epic Game ストアのプレイヤー プロファイルまたはゲーム ページには表示されません。
  • EOS アチーブメントには XP が関連付けられていません。プラットフォームに依存していないため、ゲームのスコアリング メカニズムを自由に実装できます。
Epic アチーブメント
  • Epic アチーブメントは、Epic Games ストアなど Epic エコシステムの EOS アチーブメントを拡張するための設定だけを備えた機能です (コードは不要です)。 
  • EOS アチーブメントがロック解除されると (または、以前にロック解除された EOS アチーブメントは)、同じユーザーのそれに対応する Epic アチーブメントもロック解除されます。 
  • Epic アチーブメントは、各アチーブメントに XP 値を追加します。XP 値の範囲は「5」から「200」です。ゲームには (現時点で)、すべてのアチーブメントで合計 1,000 XP となっている必要があります。
  • Epic アチーブメントは、割り当てられた XP 値に基づいて、次の 3 つの層に分類されます。Bronze = 5-45 XP、Silver = 50-95 XP、Gold = 100-200 XP
    • 追加の Platinum アチーブメント (250 XP) は、他のすべてのアチーブメントを完了すると自動的に付与される他、ゲームごとに合計 1,250 XP を獲得できることに留意してください。
  • Epic アチーブメントの進捗状況は、プレイヤーの Epic Games ストア ライブラリ、プレイヤープロファイル、および Epic Games ストア ゲームページ (Web および Epic Games Launcher) に自動的に表示されます。
  • Epic アチーブメントを構成したゲームでは、以前に表示されていた EOS アチーブメントではなく、Epic アチーブメントがオーバーレイ (XP を含む) に表示されます。
  • 最後に、ブログでアナウンスされたとおり、今後、Epic のアチーブメントにはアバターなどの他のソーシャル機能が追加される予定です。

現在 Epic のアチーブメントは早期アクセス版で、ゲームは Epic Games ストアで公開するように設定する必要があるため、ここでは Epic Online Services のアチーブメントのみに焦点を当てます。

クライアント ポリシーを変更する

アチーブメントを使用するには、まずクライアント ポリシーにアクションを追加する必要があります。
 
  1. デベロッパー ポータル (https://dev.epicgames.com/portal/) にログインします。
  2. 左側のメニューで [Your Product (あなたの製品)] > [Product Settings (製品の設定)] に移動し、[Product Settings] 画面にある [Clients (クライアント)] タブをクリックします。
  3. 使用するクライアント ポリシーの横にある [...] をクリックし、[Update policy (ポリシーを更新)] をクリックします。
  4. [Features (機能)] まで下にスクロールし、[Achievements (アチーブメント)] の横にあるトグル ボタンをクリックします。
  5. 次のアクションの横にあるボックスをオンにします。 
    • findAchievementDefinitions:アチーブメント定義のクエリに使用します
    • findAchievementsForLocalUser:プレイヤーのアチーブメントの状況をクエリするために使用します
    • unlockAchievementForLocalUser:ログインしたユーザーのアチーブメントのロック解除に使用します
      • 本番環境では注意して使用するようにしてください。これはリバース エンジニアリングが可能で、悪意のあるユーザーが正規の手段でアチーブメントを取得せず不正にアチーブメントのロックを解除する可能性があるためです。より堅牢な方法で実装するには、統計を介してアチーブメントのロックを解除するか、独自のバックエンド サーバーを介してアチーブメントのロックを解除するようにしてください。
  6. [Save & Exit (保存して終了)] をクリックして確定します。
デベロッパー ポータルのクライアント ポリシーのアチーブメント
アチーブメントのクライアント ポリシーで許可されている機能とアクション

デベロッパー ポータルでアチーブメントを作成する

アチーブメントはデベロッパー ポータルで作成できます。そして、統計に基づいてロック解除を行うか、手動でロック解除を行うのかを設定できます。また、ロックを解除する前にアチーブメントが何であるかをプレイヤーに対して通知するかどうかに応じて、表示するのか非表示にするのかを切り替えられます。ここでは、ポータルでいくつかのアチーブメントを設定します。
 
  1. 左側のメニューで [Your Product] > [Game Services] > [Achievements] に移動します。
  2. ここでは、製品の各デプロイメントのアチーブメントを確認できます (今のところ、「Release in Live Sandbox (ライブ サンドボックスでのリリース)」で確認できるようになる予定です)。
    • 右上には [Bulk Import / Export (一括インポート / エクスポート)] ボタンもあります。これを使用すると、アチーブメントのバックアップと作成プロセスを効率化できます。ただし、その方法についてはここでは触れません。
  3. 右上の [Create New (新規作成)] をクリックして、新しいアチーブメントを追加します。
  4. フライアウトには、2 つのステップのうちの 1 番目が表示されます。これにより、アチーブメントのロックを自動的に解除するための統計を定義できます。ドロップダウンで [SumStat] 統計を選択します。この際、統計の右側のボックスにしきい値も指定する必要があります。したがって、ここには「50」を入力します。
  5. ここでは、アチーブメントのロック解除の基礎となる最大 3 つの統計を定義できますが、今のところはこれだけを使用します。[Next(次へ)] をクリックして、2 つのステップのうちの 2 番目に進みます。
    • プレイヤー固有のデータを格納および取得する」という記事に沿って作業している場合は、すでに 4 つの統計情報が定義されているはずです。もしされていない場合は、その記事に戻って、まずは統計を設定するようにしてください。
  6. ここでは、アチーブメント設定の大部分を定義します。アチーブメント ID として「50_TOTAL_CLICKS」を入力します。
  7. テストするロケールを保持または選択します。
  8. このアチーブメントは、[Visibility (可視性)] 設定で [Shown (表示)] のままにしておきます。
  9. ロック解除およびロック状態のアチーブメントのアイコンをアップロードします。これには、1024x1024 ピクセル以下で 1.02 MB 以下の任意の画像 (JPG、PNG、BMP、またはアニメーション化されていない GIF) を使用できます。
    • アイコンのファイル名は、すべてのアチーブメントで一意のものである必要があります。そうでない場合、同じファイル名で新しいアップロードを行うと、古いファイルが上書きされてしまいます。
  10. ロック状態およびロック解除状態の名前と説明を入力します。
    • Locked Display Name:クリック、クリック、クリック…
    • Locked Description:終わるまで何クリック?
    • Unlocked Display Name:クリック チャンピオン
    • Unlocked Description:合計 50 回クリックしました。
    • オプションとしてフレーバー テキストも入力できます。これには、ゲームで使用可能な任意のローカライズされた文字列が使用できます。ここでは、スキップします。
  11. [Create (作成)] をクリックすると、このアチーブメントの作成は完了です。フライアウトが閉じた後、アチーブメントがリストに表示されます。
 
デベロッパー ポータルのアチーブメント クリックチャンピオン
「クリックチャンピオン」アチーブメントが作成されました

次は、手動でロック解除が可能な 2 つ目の隠しアチーブメントを作成します。
 
  1. [Create New (新規作成)] をクリックして、新しいアチーブメントを追加します。
  2. 2 つのステップの 1 つ目で統計を指定せずに、フライアウトで [Next (次へ)] をクリックします。
  3. このアチーブメントの詳細を指定します。
    • Achievement ID:TOP_SECRET
    • Visibility:非表示
    • Unlocked Display Name:発見
    • Unlocked Description:隠しアチーブメントのロックが解除されました。
    • 隠しアチーブメントには、ロック時の表示名や説明がないことに注意してください。

アチーブメント定義をクエリする

次は、アチーブメント定義をクエリするコードの実装を行います。
 
  1. 「Views」フォルダに新しいユーザー コントロールを「AchievementView」という名前で作成します。
  • アチーブメントの UI には 2 つの別々の ListView があります。1 つはすべての定義を表示し、もう 1 つはプレイヤーの進行状況を表示します。ここでは、UI の一部に表示されているすべての定義を行う ListView から作業を行います。
 
  1. 「AchievementsView.xaml.cs」を開いて ViewModel をアタッチし、イベント ハンドラを変更したプレースホルダの選択を維持します。
  1. 「AchievementsViewModel.cs」クラスを「ViewModels」フォルダに追加します。
  1. 「ViewModelLocator.cs」で AchievementsViewModel への参照を追加します。
  1. 「AchievementsService.cs」クラスを「Services」フォルダに追加して、定義のクエリを行えるようにします。
  • Achievements.QueryDefinitions」を呼び出して、ローカルキャッシュにすべてのアチーブメント定義を入力します。
  • 次に、返されたすべてのアチーブメントをイテレートし、「Achievements.CopyAchievementDefinitionV2ByIndex」を介してキャッシュから ObservableCollection にコピーします。
    • SDK で V2 API を使用していることに注意してください。これにより、非推奨の古い API (CopyAchievementDefinitionByIndex など) が置き換えられます。
 
  1. 「AchievementsQueryDefinitionsCommand.cs」クラスを「Commands」フォルダに追加します。
  1. 「AchievementsViewModel.cs」を開き、次のコマンドを宣言してインスタンス化します。
  1. Connect インターフェースを使用して正常にログインした後にのみアチーブメント定義のクエリを行えるように、次の行を「ViewModelLocator.cs」にある RaiseConnectCanExecuteChanged() メソッドに追加します。
  1. 最後に、「MainWindow.xaml」にある TabControl に AchievementsView を追加します。
これで、アプリを実行して Auth と Connect を介して認証すると、[Achievements (アチーブメント)] タブの [Query definitions (クエリの定義)] ボタンでアチーブメント定義をクエリできるようになりました。
 
アプリのアチーブメントのクエリ定義
クエリされたアチーブメント定義

プレイヤーのアチーブメント進行状況をクエリする

すべてのアチーブメント定義を取得する方法を説明しました。次はプレイヤーの進捗状況を取得する方法を見ていきます。
 
  1. 「AchievementsView.xaml」を開き、前の </ListView> タグのすぐ下に 2 番目の ListView と StackPanel を追加します。
  • ここでは、アチーブメントに添付されている統計情報 (存在する場合) の表示には、少し力任せな方法を使用しています。配列の最初の統計を表示しています (たとえ存在しない場合でも)。本番環境では、StatInfo プロパティで返される PlayerStatInfo の配列を使用の前に検証する必要があります。
 
  1. 「AchievementsViewModel.cs」を開き、選択したアチーブメントの下に次のコレクションを宣言してプレイヤーのアチーブメント進行状況を保持します。
  1. 「AchievementsService.cs」を開き、次のメソッドを追加して、プレイヤーのアチーブメント進行状況のクエリを行えるようにします。
 
  1. 「AchievementsQueryPlayerAchievementsCommand.cs」クラスを「Commands」フォルダに追加します。
  1. 「AchievementsViewModel.cs」を開き、次のコマンドを宣言してインスタンス化します。
  1. Connect インターフェースを使用して正常にログインした後にのみプレイヤーのアチーブメント進行状況のクエリを行えるように、次の行を「ViewModelLocator.cs」にある RaiseConnectCanExecuteChanged() メソッドに追加します。
これで、もう一度アプリを起動して [Query stats (統計情報をクエリ)] ボタンを使用すると、プレイヤーのアチーブメント進行状況を取得できるようになりました。
 
アプリのアチーブメント QueryPlayerAchievementsInitial
プレイヤーのアチーブメント進行状況をクエリする

ここでは、以下の注意事項があります。
 
  • QueryPlayerAchievements を呼び出した際に返される DisplayName プロパティは null です。したがって、Description、IconURL、および FlavorText プロパティ (ここでは UI には表示されていません) と同様です。これらのプロパティは、QueryDefinitions 呼び出しによって取得されて SDK キャッシュに格納されるため、最初に [Query definitions (クエリ定義)] ボタンをクリックして、これらのプロパティをキャッシュに追加する必要があります。
  • プレイヤーに統計値が取り込まれていない限り、StatInfo プロパティは null になります。上のスクリーンショットでは、ログインしているプレイヤーの統計がリセットされていることから、値は表示されていません。
  • プレイヤーの進行状況は、0〜100% の値を表す「0〜1」の double 値としてレポートされます。スクリーンショット内でログインしているプレイヤーの場合、統計情報が取り込まれていないため、進行状況は「0」です。

サンプル アプリの [Stats (統計)] タブに移動してクリック数を取り込んだ後に [Achievements (アチーブメント)] タブに戻ると、クエリの定義クエリの進行状況を順番に表示して、プレイヤーの進行状況を確認できます。
 
アプリのアチーブメント QueryPlayerAchievementsFinal
プレイヤーのアチーブメント進行状況をクエリする

アチーブメントのロックを解除する

アチーブメントのロック解除について、1 つは手動、もう 1 つは統計を使用して自動的に行うように設定しました。次は、手動でアチーブメントのロックを解除するコードと、アチーブメントが自動的にロック解除されたときに通知を受け取る方法を見ていきます。

前述のように、ゲームのコードでアチーブメントのロックを手動で解除する場合、悪意のあるユーザーが未獲得のアチーブメントのロック解除を行う際のヒントを与えてしまう可能性があることに注意してください。
 
  1. 「AchievementService.cs」を開き、次のメソッドを追加して、手動でアチーブメントのロック解除を行えるようにします。
  • ここでのプロセスはかなり簡単に行えます。「Achievements.UnlockAchievements」を呼び出し、AchievementID の配列を渡してアチーブメントのロックを解除します。
 
  1. 「AchievementsUnlockAchievementCommand.cs」クラスを「Commands」フォルダに追加します。
  1. 「AchievementsViewModel.cs」を開き、次のコマンドを宣言してインスタンス化します。
  1. 最後に、「AchievementsView.xaml.cs」を開き、AchievementsListView_SelectionChanged メソッドに次の行を追加します。そうすることで、アチーブメントが選択されたときにのみ [Unlock (ロック解除)] ボタンがクリックできるようになります。
アプリを実行して認証するときは、[Achievements] タブに移動し、[Query definitions] をクリックします。次に、TOP_SECRET アチーブメントをクリックし、[Unlock] ボタンをクリックします。UI に変更はありませんが、Visual Studio のデバッグ出力に「UnlockAchievements Success」メッセージが表示されます。このコードは、表示されるアチーブメントおよび隠しアチーブメントに適用されることに注意してください。

これで、[Query progress (クエリの進行状況)] をクリックすると、アチーブメントがリストに表示されるようになりました。前述の通り、隠しアチーブメントはロックが解除されるまでは QueryPlayerAchievements 呼び出しによって返されることはありません。
 
アプリのアチーブメント アチーブメントのロック解除
隠しアチーブメントを手動でロック解除

最後に、アチーブメントのロック解除通知をサブスクライブします。これにより、統計の進行によってアチーブメントのロックが解除されたときに独自のコードを実行できるようになります。
 
  1. 「AchievementsService.cs」を開いて次のメソッドを追加すると、アチーブメント通知のサブスクライブおよびサブスクライブ解除が行えます。
  • Achievements.AddNotifyAchievementsUnlockedV2」を呼び出して通知を設定し、コールバック メソッドを渡します。すると、アチーブメントに関連付けられた統計を取り込むことによってアチーブメントのロックが解除されたときに、それが呼び出されます。このメソッドは、アチーブメントのロックを手動で解除するときにも呼び出されることに注意してください。
  • AchievementsUnlockedCallback はデバッグ出力に行を書き込むだけです。しかし、ここでは UI を処理して、アチーブメントのロックを解除したことをプレイヤーに通知します。
  • AddNotifyAchievementsUnlockedV2 は notificationId を返します。これを使用すると、アチーブメントのロック解除に関する通知を停止できます。このサンプルでは実装していませんが、RemoveNotification メソッドでは行っています。
 
  1. シンプルにするために、「AchievementsService.cs」の ViewModelLocator.Main.StatusBarText = string.Empty のすぐ上にある QueryDefinitions メソッドに次の呼び出しを追加します。そうすることで、QueryDefinitions の呼び出し後に通知の受信を開始できます。
アプリをもう一度実行して認証し、[Achievements] タブに移動し、[Query definitions] ボタンをクリックします。合計 50 クリックした時に取得できるアチーブメントの進行状況を確認するには、[Query progress (進行状況のクエリ)] ボタンをクリックします。まだロックが解除されていない場合は、進行状況を確認し、[Stats (統計)] タブに移動して、ロックが解除されるまでクリック数を増やします。

Visual Studio のデバッグ出力に、アチーブメントのロックが解除されたことを示すメッセージがポップアップ表示されます。すでにアチーブメントのロックを解除している場合は、次のセクションの手順に従ってアチーブメントをリセットし、必要に応じてプレイヤーの統計もリセットします。

プレイヤーのアチーブメントの検索や修正を行う

プレイヤーのアチーブメントを手動で調整する必要がある場合は、ロックを解除するか、リセット/ロックする必要があります。この作業は、デベロッパー ポータルで行うことができます。
 
  1. デベロッパー ポータル (https://dev.epicgames.com/portal/) にログインします。
  2. 左側のメニューで [Your Product] > [Game Services] > [Achievements] に移動します。
  3. 右上の [Player Lookup (プレイヤーのルックアップ)] ボタンをクリックします。
  4. フライアウトで、プレイヤーの製品ユーザー ID (PUID) またはアカウント固有の ID (Epic アカウント ID など) を入力し、[Search (検索)] をクリックします。
  5. プレイヤーのアチーブメントのリストが、現在の進行状況とロック解除ステータスとともに表示されます。このリストにある省略記号ボタンをクリックすると、このアチーブメントのロックを解除またはリセットできます。

[Reset All (すべてリセット)] または [Unlock All (すべてロック解除)] ボタンを使用してすべてのアチーブメントをすばやく切り替えることもできます。しかし、これを本番環境で使用する際は注意が必要です。この機能は、開発中に最も役立ちます。もう 1 つの良い方法は、開発中にアチーブメントをテストするための個別のデプロイメントを作成することです。すべてのプレイヤー データは特定のデプロイメントにスコープされているためです。

デベロッパー ポータル アチーブメント プレイヤー ルックアップ
デベロッパー ポータルでアチーブメントのロックを解除またはリセットする

使用制限および要件

これまで見てきた他のサービスと同様に、アチーブメント機能には、すべてのユーザーに対して信頼性と可用性を保証するために設定された使用上の制限事項があります。この記事の作成時点では次の制限事項があります (最新情報については「こちらのドキュメント」を参照してください)。
 
  • デプロイメントごとにアチーブメントは合計最大 1000 個
  • アチーブメントは最大 3 つの統計から自動的にロックを解除可能

アチーブメントは、次の要件にも準拠する必要があります。
 
  • アチーブメント ID は最大 256 文字
  • アチーブメント ID には、次の文字を使用できません:, { ^ } % ` ] > [ ~ < # | & $ @ = ; ?\ ( )* /
  • アイコンのファイル名には、次の文字を使用できません: , { ^ } % ` ] > [ ~ < # | & $ @ = ; :+ ?!\ ( )* /
  • アチーブメントごとに最大 22 のローカライズされたテキストバリアントを使用可能
  • アチーブメント アイコンの最大ファイルサイズは 1.02MB
  • アチーブメント アイコンの最大解像度は 1024 x 1024 ピクセル
  • PNG、JPG、BMP、またはアチーブメント アイコンのみアニメーションのない GIF 形式が使用可能

また、クライアントまたはサーバー呼び出し用の API 呼び出しには、それぞれユーザーごと、またはデプロイメントごとのレート制限があります。これについては「こちらのドキュメント」を参照してください。

コードを入手する

この記事に記載しているコードは次の場所から取得できます。GitHub リポジトリ に記載されている使用方法に従って、ダウンロードしたコードを設定してください。
 
このシリーズの記事の一覧については、 「シリーズの記事リスト」を参照してください。フィードバックや質問がある場合は、コミュニティ フォーラムにアクセスして、お知らせください。

    デベロッパーみなさんの成功が、Epic の成功です

    Epic は、オープンで統合されたゲーム コミュニティを大切にしています。
    オンライン サービスをすべての人に無料で提供することにより、より多くのデベロッパーがそれぞれのプレイヤー コミュニティにサービスを提供できるようにすることが目標です。