56.7K Views
April 27, 18
スライド概要
2018年3月30日に行われた「GAME CREATORS CONFERENCE '18」で登壇した際に使用した資料です。
http://www.gc-conf.com/
hash比較ですが現在のUE4ですと以下のようにコードを変更する必要があります。
/修正前
if (InstalledVersion != RemoteVersion && bInstallIsPatch == bRemoteIsPatch)
{
//修正後
bool isHashMatch = true;
TSet<FString> Tags;
auto DonwloadSize = (double)RemoteManifest->GetDeltaDownloadSize(Tags, InstalledManifest.ToSharedRef());
isHashMatch = DonwloadSize == 0;
if (!isHashMatch || (InstalledVersion != RemoteVersion && bInstallIsPatch == bRemoteIsPatch))
{
Unreal Engineを開発・提供しているエピック ゲームズ ジャパンによる公式アカウントです。 勉強会や配信などで行った講演資料を公開しています。 公式サイトはこちら https://www.unrealengine.com/ja/
徹底解説!UE4を使ったモバイルゲーム開発における コンテンツアップデートの極意! GAME CREATORS CONFERENCE '18 Epic Games Japan 岡田和也 #gcconf2018
自己紹介 Epic Games Japan サポートエンジニア 岡田和也(おかず @pafuhana1213) 最近のお仕事 EGJのモバイル担当したり コソコソ色々してます #gcconf2018
本日のお品書き • 本日のお題を選んだ理由 • UE4のコンテンツアップデート用機能の紹介 • Battle Breakersにおける運用例 #gcconf2018
Unreal Engine 4 モバイル対応に力を入れてます! #gcconf2018
Epic Games製モバイルタイトル Battle Breakers • 約1年前に、iOS / Android版をリリース • 数百体のキャラクタが登場するRPG Fortnite Battle Royale • iOS版をリリース済。数カ月後にAndroid版も • PC, コンソール版と同じゲーム内容で クロスプラットフォームプレイが可能 #gcconf2018
数多くのモバイル向けの機能・最適化が 日々追加されてます! #gcconf2018
参考:4.20で入るモバイル向けの最適化 Optimizing UE4 for Fortnite: Battle Royale - Part 2 | GDC 2017 | Unreal Engine #gcconf2018
その中からコンテンツアップデートを 選んだのは何故? #gcconf2018
モバイル開発において コンテンツアップデートは 重要かつ難易度が高いから! #gcconf2018
コンテンツアップデートの重要性 タイトルの寿命とユーザーの満足度に直結する部分! • 検証・設計が不十分な状態で作業を進めると 最後まで負債として抱えることに・・・ #gcconf2018
コンテンツアップデートの難しさ プロジェクトによって最適解が異なる! • • • • • • • • ゲームの仕様 開発規模 用意可能な設備 スケジュール 予算 予算 予算 などなどなどなどなどなど #gcconf2018
本講演の目的 コンテンツアップデートの検証・設計作業のお手伝い • UE4のコンテンツアップデートに関する機能の紹介 • 当時最新のUE4.19.0 準拠 • Battle Breakersにおける運用事例の紹介 • Battle Breakersを選んだ理由は後述 #gcconf2018
本日のお品書き • 本日のお題を選んだ理由 • UE4のコンテンツアップデート用機能の紹介 • Battle Breakersにおける運用例 #gcconf2018
コンテンツアップデート用機能の紹介 • Chunk機能によるコンテンツ分割 • Chunk用パッケージの作成 • Chunkデータのダウンロード • Chunkからのアセット取得 #gcconf2018
Chunkの日本語訳 • 大きいかたまり • 厚切れ • かなりの量 • たんまり • どっさり • (ずんぐりして)がっちりした人 https://ejje.weblio.jp/content/chunk #gcconf2018
コンテンツアップデート用機能の紹介 • Chunk機能によるコンテンツ分割 • Chunk用パッケージの作成 • Chunkデータのダウンロード • Chunkからのアセット取得 #gcconf2018
コンテンツ分割のメリット ① • ストアからの初回ダウンロードサイズの削減 • ストアを介さない コンテンツのアップデート(追加・更新・削除)が可能に #gcconf2018
コンテンツ分割のメリット ② 細かく分けることで 必要に応じた部分的なアップデートが可能に マテリアルだけ更新・再DL #gcconf2018
Chunk機能によるコンテンツ分割 ゲームデータを複数のパッケージ( .pak )に分割 • 分割は 各アセットに設定されたChunk IDに基づく ・・・ Chunk 0 (Chunk ID = 0) #gcconf2018 Chunk 1 (Chunk ID = 1)
Chunk IDは どうやって設定するの? #gcconf2018
Chunk IDを設定するには? 対象アセットを 設定したいChunk IDの情報を持つPrimary Asset として管理する または、そのPrimary Asset の Secondary Asset として管理する #gcconf2018
UE4のアセット管理システム ( UE4.17~ ) 全アセットを Primary Asset と Secondary Asset に分類し Asset Manager というシステムがそれらを管理 Primary Asset Secondary Asset #gcconf2018
UE4のアセット管理システム ( UE4.17~ ) • Primary Asset: Asset Managerによって直接管理されるアセット • Secondary Asset : Primary Assetsに紐づくアセット ( Primary Assetsが直接・間接参照しているアセット ) 公式ドキュメント:アセットの参照 #gcconf2018
キャラクタのBP が Primary Assetの場合 Primary Asset #gcconf2018 Secondary Asset
各 Primary Asset に割り当てられる情報 Primary Asset ID Primary Asset ID : 0 • Asset Managerの管理用 Asset Manager Chunk ID • パッケージ時の分割 / 管理用 • Secondary Assetにも 連鎖的に適用 Chunk ID: 2 #gcconf2018
(6ページ前) Chunk IDを設定するには? 対象アセットを 設定したいChunk IDの情報を持つPrimary Asset として管理する または、そのPrimary Asset の Secondary Asset として管理する #gcconf2018
対象アセットを Primary / Secondary Assetとして 管理するにはどうすればいいの? #gcconf2018
UE4が提供している機能 • Project Setting内のAsset Managerカテゴリ • Primary Asset Label アセット #gcconf2018
Project Settings / Asset Manager 編 Primary Asset Types to Scan • Primary Assetとして管理するアセットを 抽出する際のフィルタ設定 • 対象Primary Asset とそのSecondary Assetへの Chunk IDの設定ルール #gcconf2018
Primary Asset Label アセット編 Chunk IDの設定に特化したアセット • このアセット自体はPrimary Asset (デフォルト設定の場合) • Secondary Assetを明示的に指定する機能 • 指定したSecondary Assetへの Chunk IDの設定ルール #gcconf2018
Primary Asset Labelアセットの作り方 #gcconf2018
複数の設定(アセット)からChunk IDを指定されている場合 例: • Asset Manager からは Chunk ID = 2 で 設定 • Primary Asset Label からは Chunk ID = 3 で設定 対象のアセットは Chunk 2, 3両方に含まれることに! #gcconf2018
Chunk間のアセット競合を回避するために Chunk間の親子関係を定義! • 親Chunkに含まれるアセットは子Chunkには含まれない DefaultEngine.ini [/Script/UnrealEd.ChunkDependencyInfo] +DependencyArray=(ChunkID=100,ParentChunkID=11) +DependencyArray=(ChunkID=101,ParentChunkID=11) #gcconf2018
設定したChunkの確認方法 4.19で改良された Asset Audit の出番! #gcconf2018
Asset Audit Add Chunksボタンを押すことで、各Chunkのリストを表示 • アセット競合も確認可能 • Selected Platformから 実際に作成したパッケージからの情報を取得することも可能 #gcconf2018
Reference Viewer 各アセット間の参照関係を可視化 • 該当アセットが何故このChunkに含まれているかの調査に便利! #gcconf2018
Size Map Chunkに含まれるアセットのサイズの割合を可視化 • Chunkの容量削減の調査に便利! #gcconf2018
ここまでのまとめ Chunk IDを割り当てることで、コンテンツを分割することが可能 • Asset Manager • Primary Asset Label Chunkによる分割結果をエディタ上で確認可能! • Asset Audit #gcconf2018
もう少し詳細な解説はこちら UE4のモバイル開発におけるコンテンツアップデートの話 - Chunk IDとの激闘編 #gcconf2018
コンテンツアップデート用機能の紹介 • Chunk機能によるコンテンツ分割 • Chunk用パッケージの作成 • Chunkデータのダウンロード • Chunkからのアセット取得 #gcconf2018
Chunk用パッケージを作成するには? Chunk に関する設定を事前にしておけば ゲームの実行ファイル( exe ・ apk ・ ipaなど )を作るだけ! • 実行ファイルと同時に 各Chunk毎のパッケージが完成 Chunkに関する事前設定を行う箇所 • Project Settings • Project Launcher #gcconf2018
Project Settings #gcconf2018
Project Launcher #gcconf2018
パッケージ作成処理の完了後 指定した出力先に生成される CloudDir フォルダに コンテンツ配信時に必要なファイルが配置されている CloudDir 内のファイルを 配信用サーバにアップすればOK! #gcconf2018
CloudDir フォルダの中身 各Chunkのデータ Chunk管理用のManifestデータ • Chunkのダウンロード時に使用 #gcconf2018
Manifestの役割 紐付いているChunkの バージョン情報とハッシュ値の管理 Project Settings #gcconf2018 Project Launcher Chunk毎のManifest
バージョン情報とハッシュ値の役割 既にダウンロード済みのChunkを 再ダウンロードするか否かの判定に使用 • ローカルのManifest と サーバ上のManifestの比較 判定の流れ 1. バージョンが異なっている場合は再ダウンロード 2. バージョンが同じだが、 ハッシュ値が異なっている場合は再ダウンロード #gcconf2018
Chunkの更新フローの方針 特定のChunkのみ修正したい場合は バージョンを変えずに、Chunkパッケージを作成・差し替え • 変更がないChunkはバッシュ値が変化しないので 再ダウンロードは行われない 更新対象のChunk1のハッシュ値のみ変化 #gcconf2018
Chunkの更新フローの方針 全Chunkの再ダウンロードを強制したい場合は バージョンを変えて、Chunkパッケージを作成・差し替え • エンジンバージョンの更新や ゲームシステムの変更などによる大型アップデート時 など #gcconf2018
コンテンツアップデート用機能の紹介 • Chunk機能によるコンテンツ分割 • Chunk用パッケージの作成 • Chunkデータのダウンロード • Chunkからのアセット取得 #gcconf2018
まず結論から 起動時に全てのChunkを読み込む仕様の場合 iniに設定追加 + Chunkのダウンロードをリクエストするだけで サーバから全Chunkを自動ダウンロード! #gcconf2018
まず結論から ゲームの進行度などに応じて 必要になったChunkをその都度ダウンロードする仕様の場合 Asset Managerのロード関数を使用すれば 必要になったアセットを持つChunkを自動ダウンロード! #gcconf2018
Chunk一括ダウンロードの機能を使うには 事前準備 • Chunk用パッケージをサーバに配置 • iniファイルにサーバに関する設定を追加 • HttpChunkInstallerプラグインを有効に ランタイムで必要な処理 • HttpChunkInstallerの関数呼び出し #gcconf2018
Chunk用パッケージをサーバに配置 http://192.168.0.11/ChunkData/ 以下に配置する場合 CloudDirフォルダ内のファイルを http://192.168.0.11/ChunkData/ に配置 #gcconf2018
iniファイルへの設定追加 http://192.168.0.11/ChunkData/ 以下に配置する場合 [HTTPChunkInstall] [HTTPOnlineTitleFile] TitleFileSource=Http CloudProtocol=http CloudDomain=192.168.0.11 BaseUrl="192.168.0.11" EnumerateFilesUrl= ChunkData [StreamingInstall] CloudDirectory= ChunkData DefaultProviderName=HTTPChunkInstaller #gcconf2018
HttpChunkInstallerプラグインを有効に デフォルトでは無効になっているので注意 #gcconf2018
【注意】 ランチャー版の場合、 HttpChunkInstallerプラグインを有効にすると パッケージングに失敗する不具合が報告されています この不具合はUE4.19.2で修正予定です UE4.19.1以前のエンジンでHttpChunkIntallerプラグインを 使用する場合は、GithubからDLしてビルドしたUE4をご使用ください #gcconf2018
HttpChunkInstallerの関数呼び出し FHTTPChunkInstall::SetInstallSpeed を使うことで Chunkのダウンロードをリクエスト可能 • 与える引数の値によって ダウンロード時の処理負荷を調整可能 #gcconf2018
HTTPChunkInstallerの関数を使うには 1. Build.csのModuleNamesに “HTTPChunkInstaller”を追加 2. Iniに 以下の文字列を追加 [StreamingInstall] DefaultProviderName=HTTPChunkInstaller 3. #include "HTTPChunkInstaller.h“ 4. FHTTPChunkInstall* ChunkInstall = static_cast<FHTTPChunkInstall*> (FPlatformMisc::GetPlatformChunkInstall()); #gcconf2018
起動時に 全てのChunkを読み込む仕様を実現! #gcconf2018
Tips プラットフォーム固有のiniファイルで設定しておくと Chunkに関するプラットフォーム別対応が楽になります! • [ProjectDirectory]/Config/[Platform]/[Platform]Engine.ini • 公式ドキュメント:コンフィギュレーションファイル WindowsEngine.ini #gcconf2018 AndroidEngine.ini IOSEngine.ini
ロード時に必要なChunkをDLする機能を使うに は? 事前準備 • Chunk用パッケージをサーバに配置 • iniファイルにサーバに関する設定を追加 • Asset Managerの設定を一部変更 ランタイムで必要な処理 • HttpChunkInstallerのSetInstallSpeed関数の呼び出し • Asset Managerによるロード処理を活用 #gcconf2018
Asset Managerの設定を一部変更 Project SettingsのAsset Managerカテゴリにある “Should Acquire Missing Chunks on Load” を有効に! Asset Managerを使ってアセットをロードする際、 もしロード対象のアセットがローカルに存在しない場合、 そのアセットを含むChunkを自動ダウンロードするように! #gcconf2018
つ、つまり、どういうこと…? Asset Managerを経由すれば、ロード対象のアセットが サーバからダウンロード済みか否かを意識しなくてもOK • 未ダウンロードの場合、 ロード時間にChunkのダウンロード時間が含まれるので注意! #gcconf2018
Asset Managerが用意しているロード処理 • Primary Asset の非同期ロード処理 • Primary Asset に紐づく Asset Bundleの非同期ロード処理 #gcconf2018
Primary Asset の非同期ロード処理 基本的な処理はBPノードで提供済み! #gcconf2018
Primary Asset の非同期ロード処理 Primary Asset Types to Scanで 抽出されたPrimary Assetがロード対象 ロード対象のPrimary Assetが 直接参照している Secondary Assetも 同時にロードされます #gcconf2018
Secondary Asset(直接参照) → 同時ロード対象 Secondary Asset(間接参照) → 同時ロード対象外 明示的にロード処理を呼ぶ必要あり #gcconf2018
間接参照のアセットも一緒にロードして欲しいなぁ… でも、直接参照にすると…色々と困ることあるしなぁ… ハァ…ツライ… #gcconf2018
そんな貴方のために Asset Bundle があります!!! #gcconf2018
Asset Bundleとは? 専用のタグ名が設定された Secondary Asset(間接参照) • 現在はC++からのみ利用可能 例:Primary Asset Label の Explicit Assets UPROPERTY(EditAnywhere, Category = PrimaryAssetLabel, meta = (AssetBundles = "Explicit")) TArray<TSoftObjectPtr<UObject>> ExplicitAssets; #gcconf2018
Primary Asset Label が持つAssetBundle • Explicit Assets / Blueprint → Explicit • Label Assets in My Directory → Directory • Asset Collection → Collection #gcconf2018
Asset Bundleの非同期ロード処理 Primary Assetのロード時に ロードしたいAsset Bundleのタグ名を渡せばOK! • Asset Bundleの「追加ロード / アンロード」や「ロード済か確認」も可能! #gcconf2018
Asset Bundleに関するTips Primary AssetへのAsset Bundleの登録は エディタ / ランタイム上で動的に実行可能! • エディタ: UPrimaryAssetLabel::UpdateAssetBundleData() を参考に • ランタイム: UAssetManager::AddDynamicAsset を使用 #gcconf2018
Asset Bundleの運用例 1. キャラクタに関するアセットを管理するPrimary Asset を用意 2. 用途別にタグを分けたAsset Bundleを登録 3. 状況に応じて、必要なAsset Bundleのみをロード #gcconf2018
ここまでのまとめ Chunkのダウンロードは事前準備をしておけば エンジン側で自動的に行なってくれる! Asset Managerのロード関数を使用すれば 必要に応じたChunkの自動ダウンロードを簡単に実現可能 Asset Bundle機能を使えば、 間接参照しているアセットのロード管理を柔軟に行える! #gcconf2018
コンテンツアップデート用機能の紹介 • Chunk機能によるコンテンツ分割 • Chunk用パッケージの作成 • Chunkデータのダウンロード • Chunkからのアセット取得 #gcconf2018
非同期ロード処理の注意点 Asset Managerによる非同期ロード処理は そのアセットのデータをメモリに載せる所まで! レベル上で使用するには ロードしたアセット自身を取ってくる必要がある! #gcconf2018
Primary Assetからの取得 Async Load Primary Asset ( List )の返り値から取得 • UObject型なので注意 #gcconf2018
Asset Bundleからの取得 UAssetManager::GetAssetBundleEntry を使用 • 現状C++での提供のみ • 自作BP関数ライブラリから呼べるようにすると便利! #gcconf2018
ここまでで取得できないアセット Primary Asset 又は Asset Bundleが持つ プロパティや関数などを使っても アクセスできないアセット #gcconf2018
Asset Registryを活用する! Asset Registryからアセットを検索可能 • クラス名・パス名などで検索フィルタを利用可能 • 検索結果( FAssetData ) の GetAsset関数からアセットを取得 #gcconf2018
Asset Registryで抽出したアセットのロード Asset Registryによる検索結果は 未ダウンロードのアセットも含むので注意! • 未ダウンロードの場合、FAssetData::GetAsset の結果はNULLに… Chunkを自動ダウンロードしてくれる UAssetManager::LoadAssetList でロードしましょう! #gcconf2018
Asset Registryによるアセット取得に関して Asset Managerが 「いい感じに」してくれてた処理を 自分で実装することに… • Asset Registryによる検索コストの問題も Primary Asset 又は Asset Bundleから アクセスできるように設計した方が安全! #gcconf2018
ここまでのまとめ • Asset Managerのロード処理だけでは レベル上にはまだ表示されない • メモリに載っているアセットを取得する必要がある • アセットの取得に関する処理の設計は Asset Managerのシステムを活用する形にする • Primary Asset • Asset Bundle #gcconf2018
本日のお品書き • 本日のお題を選んだ理由 • UE4のコンテンツアップデート用機能の紹介 • Battle Breakersにおける運用例 #gcconf2018
こちらも合わせてご確認ください UE4公式ブログ 「チャンク化による高速ダウンロードを可能にするツー ルと最適化の考察」 #gcconf2018
Battle Breakersを選んだ理由 日本で主流の モバイルゲームの形式に近いから! #gcconf2018
Battle Breakersの仕様 300体以上のキャラクタが登場 • さらに、各キャラクタにレア度が存在 起動すると、DLを挟まずに チュートリアルをすぐプレイすることが可能 • チュートリアル終了後や 各ステージの初プレイ時などのタイミングでDL #gcconf2018
Battle Breakersにおける運用テクニック • Chunk IDの設定ルールについて • タイトル固有のPrimary Asset Label • Chunk IDの自動設定 • Chunk間のアセット重複の回避 #gcconf2018
Chunk ID = 0 実行ファイル ( exe ・ apk ・ ipa )に含まれるアセットを管理 • • • • ゲームの起動 ログイン 初回起動時のチュートリアル などに必要なアセット #gcconf2018
Chunk ID = 2 Chunk IDの設定漏れ検出用 どのChunkにも登録されていないアセットは Chunk 2 に 含ませる処理を追加 • Chunk IDがデフォルト値のままだと Chunk ID = 0 に設定されて ( 実行ファイルに含まれて ) しまう #gcconf2018
Chunk ID = 5 ~ 17 キャラクタの表示・音声以外のアセットを管理 • ステージデータ • メニューで使用するUI キャラクタなどで使用される共通アセットもここで管理 • 戦闘演出 など #gcconf2018
Chunk ID = 50~99 ローカライズが必要なアセットを管理 • 使用言語に応じたChunkのみダウンロード こんにちは Hello Bonjour مرحبا هناك Chunk ID = 50 Chunk ID = 51 Chunk ID = 52 Chunk ID = 53 #gcconf2018
Chunk ID = 100 ~ 999 キャラクタ毎のボイス管理 • キャラクタ固有のイベント 毎の音声データ (攻撃時, ダメージ時など) #gcconf2018
Chunk ID = 1000 ~ 1300+ キャラクタ毎の表示に必要なアセットの管理 • Skeletal Mesh • Animation • Texture #gcconf2018
どのように管理しているのか 設定・管理項目毎に タイトル固有のPrimary Asset Labelを作成 Project SettingsのAsset Managerで それらをScan対象として登録 #gcconf2018
Chunk IDの 手動管理は超大変!!! #gcconf2018
現在のChunk ID設定フローの課題 Asset Manager / Primary Asset Labelの機能は提供されているが 手動設定なので、ヒューマンエラーが発生しやすい 「数百 * レア度」 体分のキャラクタの Chunk IDをミスなく正確に管理できるか? #gcconf2018
もしChunk IDの設定を間違った場合 ハッシュ値が変わるので 全ユーザが該当Chunkを強制再ダウンロード! もしChunk IDで制御している箇所があった場合 最悪なケースとして、ユーザ毎の管理情報が壊れる可能性も…! #gcconf2018
やばい! #gcconf2018
なので Battle Breakersでは Chunk IDの設定を一部自動化してます! #gcconf2018
Chunk IDの設定を自動化するには? UAssetManager::UpdateManagementDatabase に Chunk IDの自動設定処理を追加する! • アセット管理システムのデータベースの更新処理用 • データベースに関連する Asset ManagerやPrimary Asset Labelの設定変更時に実行 #gcconf2018
Asset Managerをカスタマイズする場合 プロジェクト用に拡張したAsset Managerのクラスを エンジンに認識させる事が可能です • つまり、エンジンコードに手を入れなくていい! 詳細な手順は以下のドキュメントをご確認ください アセット管理 / プライマリアセットを登録しディスクからロードする #gcconf2018
Battle Breakersで行っている処理の例 ① 課題 • 使用用途・タイミングが同じ場合は同じChunkに配置したい • 1つのPrimary Assetで管理するのは非効率 • 手動でChunk IDを制御したくない 対象のPrimary Assetがとあるカテゴリに属する場合は そのカテゴリ用のChunk IDを自動設定 #gcconf2018
Battle Breakersで行っている処理の例 ② 数十分前のスライドより Chunk間の親子関係設定も 手動で行うのは辛すぎる! #gcconf2018
Battle Breakersで行っている処理の例 ② Chunk間の親子関係をコード内で設定し その結果を ini ファイルに出力する処理を実装 • 共通アセットの使用が確定している箇所は 共通アセット用のChunk ID、親子関係を自動設定 • エディタ上から親子関係を制御できるように プロパティを追加 #gcconf2018
Battle Breakersで行っている処理の例 ③ 課題 • 数百体のキャラクタ * オプション( レア度など )という膨大な数を 管理する必要がある • キャラクタ毎にユニークなChunk IDを設定 • オプション違いは同じChunk IDに設定 #gcconf2018
新規キャラ用Primary Assetに対しての設定ルール 1. Primary Asset ID名は キャラクタ名 + オプションというルールで設定 2. Chunk IDの自動設定処理時に Primary Asset IDからキャラクタ名を抽出 3. 抽出したキャラクタ名が既存のものなら 同じChunk IDを設定 新規なら新しいChunk IDを設定 中学生_N #gcconf2018 中学生_SSR
ここまでのまとめ Chunk IDの手動管理は ゲームの規模が大きくなるにつれてリスクが高まる Chunk IDの自動設定の仕組みを用意することで ヒューマンエラーを回避しつつ、作業効率を向上できる #gcconf2018
本日のまとめ • より良いコンテンツアップデートの仕組みを構築するには Chunkによるコンテンツ分割が不可欠 • Chunk IDの設定方法は複数存在 • Asset Manager / Primary Asset Label / C++コード #gcconf2018
本日のまとめ Chunkのダウンロード ・ データ取得に関して UE4の標準機能が一通りカバー済み • Asset Manager, Manifest, HttpChunkInstaller, Asset Bundle #gcconf2018
本日のまとめ • Chunk IDの設定ミスは 重大な問題を引き起こす可能性がある • Chunk IDの自動設定処理を用意することで ヒューマンエラーの回避・作業効率の向上を実現 • Battle Breakersにおける運用事例 #gcconf2018
各仕様を把握した上で タイトルに適したフローを構築することが重要! お困りの際は是非ご相談ください! #gcconf2018
ご清聴 ありがとうございました! 本講演に関する質問はこちらからどうぞ! E-mail : [email protected] Twitter : @pafuhana1213 展示ブースにEGJのスタッフがいますので 本講演に関すること以外の 質問も是非どうぞ! #gcconf2018