
工場長のみなさん、こんにちは!
この一週間はプログラムの最適化に取り組んでまいりましたので、作業内容をご報告いたします。
まえがき
本作Lazy Witch's Factoryは後半に差し掛かるにつれてオブジェクト数が劇的に増えていくゲームです。
過去、コンベアの最適化では動作速度が20倍以上に跳ね上がった実績もあり、最適化の必要性は極めて高いと言えます。
特に問題となっていたのが、大量の使い魔オブジェクトを配置した際の動作負荷でした。
使い魔オブジェクト1つ
使い魔1体は、
「3Dの足場」
「アニメーションする複数のSpriteRenderer」
「Spineモデル」
で構成されています。
Playtestで収集したアンケートによると現代のミドルエンドゲーミングPCですらもカクつく様子でした。
主に2Dで構成された軽量なはずのオブジェクトを並べているだけなのですが、GPUへの負荷が不当に高い状態となっているようです。
これを受けて実施した負荷軽減の事例を共有します。
GPU負荷対策の例
①Spine機能の「クリッピング」の使用中止
黒目部分が白眼をはみ出ないようにしてくれる便利な機能クリッピングの計算それ自体が重いらしく、全てのメッシュを再計算するような処理が入ってしまうみたいです。
ウィッチとレイヴンの瞼の部分で使用されており、GPUに負荷がかかっていたため、モデルを改変しクリッピングを使わずに表現する形にしました。
②SRP Batchの適用範囲拡大
Unityによる描画の序盤。まず最初に地下部分にあたるコンベアが描画されているUnityによる画面の描画方法は、「最も奥にあるものから順番にGPUへ描画命令を出す」というもの。
Unityが同じレイヤーにあるとみなしたものは、GPUへの問い合わせ1回でまとめて描画されるようになります。問い合わせが少ないほど、GPU負荷は低くなる仕組みです。
今回のプロジェクトでは問い合わせをまとめる方法にSRP Batcherというものを採用しているのですが、使い魔オブジェクトでもこれが綺麗に適用されるように修正しました。
今回行った対応では以下の2つが効果を発揮しました。
・オブジェクト内のSortingLayer指定でDefaultを使わない
元々使い魔オブジェクトを基準にしようと考えてDefaultレイヤーに配置していたのですが、Defaultの処理が特殊なのかバッチが効いていませんでした。別レイヤーを用意するだけで解決しました。
・各種SpriteRendererに共通のMaterialを指定
Materialが同じオブジェクトでないとバッチをまとめる対象にならないため、可能な範囲でMaterialを共通化しました。
結果、使い魔1体ごとにドローコールが合計10回以上呼び出されていたのが、何体呼び出しても10回程度のドローコールにまとまるようになりました。
③非表示時のグラフィック処理の省略
Update When Invisibleの項目から変更できるSpineはデフォルトではカメラ外に出てもアニメーションを実行しているらしく、これが負荷の一端を担っていました。
領域外の場合何もしないというオプションもあったのですが、これはアニメーションとキャラの行動が同期しない原因になる可能性もあったので、Meshの更新のみを停止させました。
④書き出しサイズをギリギリまで切り詰める
文字通りです。
対応を予定している4Kで線が滲まないギリギリの範囲で書き出しを行いました。
以上①~④の修正を行うことで、GPUへの負荷は1マップを使い魔で埋め尽くす400体の配置でもほぼ気にならなくなりました。
現在、引き続きCPUへの負荷を下げる対策を行っています。
各変更とも非常に地味なので記事であえて取り上げることはしませんが、体験版でその効果を実感していただけるようがんばります。
クラウドファンディングの受付期間は残り10日となりました。
ご支援がまだの方はぜひご検討お願いします。
次の活動報告では、ストレッチゴール達成時の追加コンテンツについて、現時点の企画内容をご紹介する予定です!



