【レポート】クライアントエンジニアが語る、ゲーム開発技術勉強会! - KLab TECH Meetup #2 -
2017年12月26日(火)19時20分より「クライアントエンジニアが語る、ゲーム開発技術勉強会!パフォーマンスチューニング、運用〜新しい技術導入など様々な取組事例をお話しします- KLab TECH Meetup #2 -」が開催されました。
約3ヶ月振りの開催となった「KLab TECH Meetup」。前回と同様に参加申し込み枠(100名)はすぐに満席を迎えました。
当日の登壇者と講演のテーマは下記の通りです。
「シーン遷移の最適化と実装したツール紹介」
KLab株式会社 大野友貴人さん
「Unityでの大規模開発アーキテクチャ」
KLab株式会社 細野章平さん
「リアルタイムリップシンク実現 高品質x省エネの実装手法紹介」
KLab株式会社 陶鋭さん
「アセットバンドルに関する試行錯誤の話」
KLab株式会社 真子拓馬さん
「リズムゲームのためのパフォーマンスチューニング」
KLab株式会社 中島将浩さん
それでは内容を紹介します!
シーン遷移の最適化と実装したツール紹介
最初の登壇は大野さんです。
大野友貴人(おおの・ゆきと)/KLab株式会社 クライアントエンジニア。学生時代はOSSゲーム開発にコミット。ゲーム会社でリードエンジニアを務めた後、2015年にKLabへ入社。リズムゲーム好き。
大野さんは自身が開発を担当した3Dアクションゲームにおいて行なったチューニングについて紹介します。
大野さんはまず、基礎知識から学びました。
「とりあえずプロファイラを使ってみたり、断片的に検索して情報を得たりとかなり非効率な試みをしていました。しかし今振り返ってみると、『Unity』の様々な公式ドキュメントを読むべきでした。現在は公式ドキュメントがとても充実しているので、しっかり読みこむことは重要だと感じます。
標準のプロファイラーを使うときはログを切らないとノイズになってしまったり、『Profiler.maxNumbersOfSamplesPerFrame』プロパティを設定することが必要です」(大野さん)
続いて大野さんから開発を担当した案件で実際に改善を実施した4つの事例が紹介されました。
課題1:シーン切り替え時に行われる通信処理の結果の返りが遅い
「これまではシーンの遷移が開始された際、フェードアウトが終了した後にシーンをロードし、そのシーンを初期化するために通信を挟んでいました。さらにこのサーバーもあまり速くないという問題もありました。
そこで、シーンの遷移が決定した時点で即座にリクエストを投げ、シーンのロードが終了したタイミングでレスポンスをもらうように変更しました。これにより画面のフェードイン、フェードアウトとシーンのロード時間を通信待ちに割り上げることができたので改善につながっています」(大野さん)
課題2:マスタデータへのアクセスが遅いパターンがいくつもある
「『キャラクタマスクラス』『クエストマスタクラス』などのマスタクラスには手書きのメソッドが定義されていました。そのためキャッシュに乗っていなかったり、キャッシュに乗っているのに使っていないというケースもありました。
この状況を改善するためにまずキャッシュの機構を作って共通化部分を実装します。その後、かなり量はあったのですがひとつずつコードを精査し、共通化処理に差し替えていきました。スペックの低い端末では遷移が1秒以上速くなることもありました」(大野さん)
課題3:「Instantiate」が遅いパターンがある
「例えばクエスト選択画面にはクエストごとのオブジェクトがあるのですが、非アクティブな演出が多く含まれいるために生成に時間が掛かっていたんです。
この演出を別の「Prefab」に切り出すことで、クエスト選択画面の速度は1.3倍に改善しました」(大野さん)
課題4:文字列のパース処理が遅い
「まず『json』の標準ライブラリ『StringReader』を使用している部分が遅かったので、自前で『reader』を書いてスピードを高めています。
またこちらも標準ライブラリの『DateTime.Parse』に時間が掛かっていたので、フォーマットがわかっているマスターデータまわりなどにパッチを当てて早くしています。
これらの結果、一番効果的だったシーンでは倍の速度を達成することができました」(大野さん)
さらに大野さんは改善に利用したツールを共有。
「この案件では1行変えただけでコンパイルに2分も掛かってしまうことがあり、気軽に試行錯誤ができない状況でした。そこで、狙ったファイルだけ好きなタイミングでコンパイルして実行するランタイムコンパイラを作りました。
また、チャットツール『Slack』に対してAPIを提供する『Slack.cs』というクラスを作っています。スクリーンショットやバイナリを簡単に送れる点が、特に調査段階ではよかったですね。
他にはゲーム内を全て自動で回ってくれるデバッグ機能、検証用のプログラムを任意のタイミングで実行できる機能も作ってよかったと感じています」(大野さん)
最後に大野さんは「当たり前のことを当たり前にやれば、シーン遷移はきちんと早くなりました。ツールを作って開発や計測の効率をあげることはとても重要だと感じます」とまとめました。
Unityでの大規模開発アーキテクチャ
2人目の登壇者は細野さんです。
細野章平(ほその・しょうへい)/KLab株式会社 クライアントエンジニア。埼玉県出身。東京電機大学卒。2013年に新卒でKLabへ入社。初音ミク好き。
細野さんは自身が初めて取り組んだ『Unity』での大規模開発アーキテクチャについて発表しました。
「以前、社内には『Unity』で標準化されたアーキテクチャはありませんでした。しかし、人によって実装方法がかなり異なり、コンフリクトも多発するので作業は他のメンバーに依存しがちになってしまいます。また、クライアントとサーバーで同一のロジックが存在し、各担当が個別に実装している状態でした。
そこで、クライアントとサーバーで統合テストを実施しつつ、他人に依存せずに開発できるようにしたいと考えたんです」(細野さん)
細野さんはクライアントとサーバーの統合テストを実現するために実施した2つの取り組みについて説明しました。
取り組み1:ビジネスロジックと『Unity』の分離
「統合テストを行なうためには、『Unity』に依存しない小さなクライアントがまず必要だと考えました。そしてテストすべき箇所はビジネスロジックに限定します。『View』は変更が入るものなので、恒常的なテストの対象にはしていません。さらに外部との依存が最小になるように『Wrapper』を置くようにしています。
次にテスト構成についてですが、サーバーとの統合テストの場合にはモック通信ライブラリを当てて、コンパイルしたクライアントを使います。『ServerTest』時には『GameServer』とクライアントが参照するテストデータが入った『SQLite』ファイルを生成しました。『ServerTest』がビジネスロッジク内の『UseCase』を実行し、最終的なクライアントの状態が正しいかを検証します。
これにより統合テストができるようになりましたが、実際にクライアントをつなぎこむためにはまずモックだった通信ライブラリを置き換えます。そして、エントリポイントをViewをトリガーとする『Presenter』に差し替え、『Sqlite』を実際のマスタデータに相当するものへ置き換えるわけです」(細野さん)
細野さんはビジネスロジックを分離することで実現できたこととして、次の3点を挙げました。
- ビジネスロジック部分はテストが可能な状態を維持できるため、クライアントとサーバーで状態の違いに苦しむ必要がなくなる
- 分離することで『Unity』の知識がなくても、C#の基礎知識でビジネスロジック部分を実装できる
- 実装要件にビジネスロジックの分離という強い縛りができたため、『Presenter』と『Domain』が明確に分けられ、単体テストも簡単にできる状態になった
取り組み2:イベント駆動を目指す
「『Unity』の実装をしていると『View』同士が依存し合います。例えば『シーンAの作業が終わるまでシーンBの実装が出来ない』という状況になり、シーンAとシーンBの担当者が異なると大変です。データ的にもワークフロー的にもつらい環境ですね。
この課題を解決するためにイベント駆動実装に取り組みます。まずはデータの流れを一方向にしてキレイにしました。また、ビジネスロジック側はキャッシュされた値に変更があれば『Presenter』に通知する仕組みをつくりました」(細野さん)
このイベント駆動を実装したことで実現したのは下記の3点です。
- ビジネスロジックの『Interface』さえ定義しておけば、残りの実装は後回しにすることができるようになった
- 各『View』の更新をイベントに任せられるようになったことで依存が減り、『View』を細かく分割できるようになった
- 『View』を細かく分割できるようになった結果、ビジネスロジックを触る側の『View』と、表示するだけの『View』での作業の分割が実現した
最後に細野さんは「導入時にしんどかった点」を振り返り講演を終えました。
次のページ :
リアルタイムリップシンク実現 高品質x省エネの実装手法紹介