18.7K Views
May 27, 21
スライド概要
動画アーカイブ:
https://www.youtube.com/watch?v=TkMv8MZJIHw
講演内容:
SAMURAI JACK: BATTLE THROUGH TIMEはアメリカのテレビアニメのゲーム化です。比較的小規模少人数のタイトルだったため、UE4の機能をなるべくそのまま使用してオーソドックスに開発をしました。開発事例をグラフィック、エンジン対応、プラットフォーム、パフォーマンス、AIなどを広く浅くお話したいと思います。
講演者:
田中 達大 (ソレイユ株式会社 シニアソフトウェアエンジニア)
上野 能弘 (株式会社ブラストエッジゲームズ CTO)
松田 理孝 (株式会社ブラストエッジゲームズ リードエンジニア)
UNREAL FEST EXTREME 2021 SUMMER公式サイト配信ページ:
https://unrealengine.jp/unrealfest/timetable/game-soleil.html
Unreal Engineを開発・提供しているエピック ゲームズ ジャパンによる公式アカウントです。 勉強会や配信などで行った講演資料を公開しています。 公式サイトはこちら https://www.unrealengine.com/ja/
SAMURAI JACK 開発事例: 海外むけアクションゲー ムを オーソドックスに作ってみた ソレイユ株式会社 シニアソフトウェアエンジニア 田中達大 SAMURAI JACK: BATTLE THROUGH TIME software © 2021 Cartoon Network, Adult Swim, the logo, Samurai Jack and all related characters elements are trademarks of and © Cartoon Network, a WarnerMedia company. All Rights Reserved.
はじめに
はじめに 2020年に発売されたゲーム SAMURAI JACK: BATTLE THROUGH TIME の制作事例についてお話します。 前半はソレイユ株式会社 田中が開発全体について。 後半はキャラクター、AIなどを担当したブラストエッジゲーム ズの上野、松田がお話します。
前半のアジェンダ このスライドのアジェンダ
前半のアジェンダ • • • • • • • • 自己紹介、会社紹介 SAMURAI JACKとは 開発方針 UE4エンジン改造総ざらい グラフィックスについて ライティングシナリオ運用 最適化ポイント その他小ネタ集
自己紹介、会社紹介
自己紹介・田中達大 • ソレイユ株式会社シニアソフトウェアエンジニア • 主にUE4プロジェクトのグラフィックス関連、技術サポート をやってます。 • ゲーム業界歴30年以上の年寄り • エンジン改造大好き • SAMURAI JACKでは技術・プログラムのディレクションを担 当、プラットフォーム対応、最適化なども。
会社紹介・ソレイユ株式会社 • リリースタイトル • NARUTO TO BORUTO シノビストライカー • NINJARA • SAMURAI JACK: BATTLE THROUGH TIME • 現在も複数プロジェクト開発進行中 アクションゲームを得意とするゲームデベロッパー UE4がメインだけど他のエンジンもやるよ。 新卒採用もあるのでウェブサイトを御覧ください。 https://soleilgamestudios.com/jp/
SAMURAI JACKとは 正式名称:SAMURAI JACK: BATTLE THROUGH TIME 国内タイトル:サムライジャック 時空の戦い(DMM様から販売)
SAMURAI JACKって? 主に海外で放映されていた人気アニメ。 日本でもカートゥーンネットワークで放映されていた。 サムライというだけあって、一応ジャックは日本人らしい。 実は日本要素はあまりない。 シーズン4まで放映されてしばらく未完だったが、2017年に シーズン5が放映されて完結した。 • 欧米ではけっこう人気。 • 最近カートゥーンネットワークでリマスターで再放送された。 • • • • •
SAMURAI JACK BATTLE THORUGH TIMEって? そんなSAMURAI JACKのアニメを原作に制作 されたアクションゲームが SAMURAI JACK BATTLE THROUGH TIME です。シーズン5をベースに各シーズンの主な エピソードをモチーフに構成されています。 主人公のジャックを操り、多彩な武器を駆使し て冒険を進める内容となっています。
開発方針 どんな方針や考え方で開発されたか
開発方針 • • • • • • 原作アニメファンを大事に、楽しんでもらえるように。 原作を踏襲したストーリー。 広い層をターゲットにしつつも手応えのあるアクション。 オーソドックスなTPSアクション。 UE4を使って効率よく開発したい。 どのプラットフォームでも同じ体験を
開発方針 • 原作アニメファンを大事に、楽しんでもらえるように • 原作を踏襲したストーリー AdultSwim社の厳しい監修がありました。シナリオはアニメ 版のシナリオライターが作成。原作者のゲンディ・タルタコフ スキー氏からも数々のフィードバックを頂きました。 個人的にも原作アニメファンが喜んでもらえるストーリーに 仕上がっていてると思っています。
開発方針 • 広い層をターゲットにしつつも手応えのあるアクション • オーソドックスなTPSアクション この点は弊社アクションチーム、アニメーションチームであ る元NINJA GAIDEN開発チームのノウハウが活かされた。 実際の制作には多くの開発会社様による協力がありました。
開発方針 • UE4を使って効率よく開発したい • どのプラットフォームでも同じ体験を UE4さまさまです。特にマルチプラットフォーム開発の容易 さは本当に助かりました。 カットシーンは外部の会社をメインに作成してもらいました が、UE4に慣れていない会社も比較的短期間で良いカットシー ンを作成してくれました。Sequencer大活躍。
開発環境 UE4 4.22.3(スタート時は4.20) Visual Studio 2017 対応プラットフォームはWin64/PS4/XBOX ONE/Switch 後にiOS(Apple Arcade)も追加された。iOS版はスペインの会 社が担当 • バージョン管理はPerforce、CIはTeamcity • プログラマーは10名程度(のべトータルで20名くらい) • • • •
UE4エンジン改造総ざらい 実はそんなに改造してないですが
UE4のエンジン改造 • 弊社タイトル(というか僕が手掛けたプロジェクト)では最 もエンジン改造が少ないかも。(NINJARAは別チームなので 除外) • とはいえ必要なエンジン改造はためらわないポリシー。 • 最近のUE4のアップデートマージは昔ほど問題が起きない。 エンジンアップデート時のマージは1、2日で完了していた。 • 以前ほどエンジンのコア部分が大きく変わることが無くなっ たのが大きい。(メモリ管理、ローディングなど)
UE4の改造 • Static Meshの使用していないUVセットを削除する ムダなUVセットを持つアセットが地味にGPU負荷になる場合 があったので。 • マテリアルのシェーディングモデルを追加 一部キャラにアウトラインを描画するため。(後述) • AnimNotifyのインポート アニメーションを入れ替えたときのAnimNotifyの再設定用 • ローカライズのデフォルト言語を強制設定する 対応言語以外ならデフォルト言語に強制設定
UE4の改造 • Windowsのフルスクリーン挙動の修正 タイトルバーなどが無いボーダレスWindowモード追加 Ctl-Enterでのフルスクリーン切り替えの抑止など • ゲーム画面をRender Targetにキャプチャする機能 画面をキャプチャしたものを使用する演出用。ゲーム画面だけのものと、 UMGごとキャプチャするものを作成 • LandscapeのDynamic Shadowを描画しない設定 最適化の項目で後述
UE4の改造 • アスペクト比が違うディスプレイのレターボックス対応 レターボックス化でUMGの位置がずれる問題などの対応 • エンジンの不具合対応 Hotfixの適用や、細かいクラッシュ対応など • プラットフォームごとの規約対応 けっこう細々とありましたがプラットフォームの詳細は非公開なので、 詳しくは語りません。コントローラーの抜き差しとかユーザー交代とか そういう類。
UE4の改造まとめ • 全くエンジンに手を入れないのは難しい。不具合修正やプラ ットフォーム対応などはどうしても必要に。 • 変更箇所にしっかり検索できるようなコメントを入れておく ことが大事。 • 改造しなくても出来る方法をなるべく考える。 • 無いと思ってた機能もよく調べるとすでにエンジンに実装さ れていることもある。 • 継承したいクラスにENGINE_APIなどのマクロが付いてない、 privateメンバーにアクセスしたいのでGetterを追加なども
グラフィックスについて
グラフィックス • UE4のライティング・マテリアルシステムをほぼそのまま使 用。 • セルシェーディングでもPBRでも無い • キャラの肌はサブサーフェス • 一部だけアウトライン • 雰囲気づくりはVolumetric Fogとアニメをベースにした独特 の色遣いで
アウトライン 局所的にどうしてもアウトラインが欲しかった。 • ジャックの鼻筋 • ジャックの顔と首の間 • 指の間 鼻筋はメッシュを配置してカメラ方向で左右切り替え描画 それ以外は専用のアウトラインを実装。ポストプロセスで生成。
ジャックの鼻筋 鼻筋用のメッシュを配置。顔の向きで左右の表示を制御 カットシーンなどで正面を向いているときは左右どちらかに固 定した。 © & ™ Cartoon Network, Adult Swim 2021 © & ™ Cartoon Network, Adult Swim 2021
アウトライン メッシュの頂点カラーにアウトラインの差分情報を格納。 GBufferのスペキュラに情報を出力。キャラクターシェーダーの スペキュラは内部で0.5に固定してGBuffer情報を使用しないよ うにした。 ポストプロセスでスペキュラ値(アウトライン用のパラメータ ー)を参照してアウトライン生成 地味だけどこだわりポイントだった
アウトラインあり © & ™ Cartoon Network, Adult Swim 2021
アウトラインなし © & ™ Cartoon Network, Adult Swim 2021
アウトライン わかりにくい違いですが。 キャラクターデザインとして大事だったようです。
ライティングシナリオ運用
ライティングシナリオの切り替え • ステージ内でライティングが大きく変更になる場合に使用 • 屋外から屋内など、同じパーシスタントレベル内でライティ ング環境は複数というシチュエーションに対応したかった • サブレベルが複数のライティング環境を持つというパターン は無かった。同じサブレベルだが、昼と夜みたいなパターン。 • レベルの途中でライティング変化する場合に使用。 • ただし、少々イレギュラー。UE4は動的にライティングシナ リオを変更することを考慮していないかも?
ライティングシナリオの切り替え 通常はライトマップはサブレベルごとに、Volumetric Lightmapはパーシスタントレベルに生成される。 ライティングシナリオ設定のサブレベルでライトビルドを行 うと、ライトマップ、Volumetric Lightmap共にライティング シナリオ設定のサブレベルに生成される。 ライティングシナリオ設定のサブレベルと、それに影響され るサブレベルを切り替えてしまおうという算段。 とは言えシームレスにライティングシナリオの切り替えはで きない。
ライティングシナリオの切り替え • 具体例1 最初のステージの前半の鉱山と後半の沼地 色味の違いがわかりやすいように、Volumetric Lightmapを可 視化して、白いスフィアを置きました。 © & ™ Cartoon Network, Adult Swim 2021 © & ™ Cartoon Network, Adult Swim 2021
ライティングシナリオの切り替え • 具体例2 砂漠と宇宙船の中 © & ™ Cartoon Network, Adult Swim 2021 © & ™ Cartoon Network, Adult Swim 2021
ライティングシナリオの切り替え ライトビルドの手順 • ライティングシナリオとそのシナリオでライティングされる サブレベルだけ表示状態にする。 • その状態でライトビルドを実行する • Volumetric Lightmapがライティングシナリオレベルに作成 される。 • そのレベルのライティングシナリオの数だけ上記を実行。 • 実際には表示レベルを切り替えるヘルパーアクターを用意し た。
ライティングシナリオの切り替え 注意点 • 切り替えは一瞬で行われるわけではないので、切り替え中は フェードしておく • レベルの読み込み順番によってはうまく切り替わらなかった りクラッシュすることがあった • フェードアウト→現在のライティングシナリオ関連サブレベ ルをUnload→新しいライティングシナリオ関連サブレベルを Load→表示状態になったらフェードイン
ライティングシナリオのライトビルド
サブレベルの表示管理 • チェックポイント式のゲームなので、チェックポイントごと に必要なサブレベルのリストを持ち、チェックポイント通過 で前後のチェックポイントに必要なサブレベルをロード、不 要なサブレベルをアンロード • ライティングシナリオの切り替えやプリロードはトリガーで • Level Streaming Volumeは使用せずにすべて手動コントロ ール • あまり前に戻ったりせず分岐が少ないゲームなので手動の方 が細かいコントロールができてよかった。
UIについて UIの方針 • アウトゲームUIはアニメのイメージをスタイリュッシュに • インゲームUIは最低限、なるべく表示しない。 という方針でした。当初はジャックのHPゲージも無く、だんだ ん服が破れて髪が乱れることでHP減少を表現していました。 しかし、やはりHPの残りがわかりにくいという意見が多く、HP ゲージを表示することに。 敵のHPもターゲットした対象だけ表示することに。
UIについて 最近の海外ゲームはUIがシンプルな傾向にあります。 これは描画負荷から見ても、開発工数から見ても有利なので UIは極力少なくし、どうしても必要なものを足す方針でした HPゲージ以外にも、レーダーを実装しなかったので、目的地 がわかりにくいという指摘がありました。 そこでレーダーは表示しないが、ボタンを押すとカメラが目 的地の方を向くという機能を入れました。単純に、各エリアご とに目的地マーカーを設定しておき、その方向を向くだけです が、迷わなくなりました。
ローカライズ ローカライズに関してはUE4のローカリゼーションダッシュ ボードを使用した正攻法でチャレンジしました。 これに関してはLocalization Deep Diveで弊社郷津が講演し た内容を御覧ください。この時点では未発表のタイトルだった ので、具体的なタイトル名には言及していませんが、サムライ ジャックのローカライズに関しての内容でした。 UE4:Localization Deep Dive 最新UE4タイトルでのローカライズ事例
ローカライズ 実のところ、ローカリゼーションダッシュボードはUE4エデ ィタのローカライズ用に作られたものかなと思うので、ゲーム クライアントのローカライズはアセットローカリゼーションで 切り替える方が良かったかなと思っています。 ソースコード内のテキストもローカライズしたい場合にはロ ーカリゼーションダッシュボードが便利だとは思います。 どちらかだけでなく組み合わせての運用もありかもしれない ですね。
最適化ポイント
最適化ポイント • なるべく60fps出したかった。一部プラットフォームは30fps • Dynamic Resolutionは使用しているが、なるべく高めの解像 度を保ちたかった。 • 敵が大量に出るゲームでは無いし、樹木、草が大量に出るゲ ームでは無いのでそこまで苦労しない・・・と思ったことも ありました。 • ステージによっては草や樹木が多く出てきて結局苦労した。
最適化ポイント 割と当たり前のことをやりました。 • ProfileGPU,ProfileCPUでざっと計測 • あたりをつけて修正して再計測 • 気になるところはプラットフォームのプロファイラで計測 とにかく計測すること。勘で「ここが重いんだろうな」と思っ たところに手を入れてもムダに終わることが多い。先入観は危 険。 プラットフォームのプロファイラは優秀。ボトルネックを分析 しやすい。
最適化ポイント グラフィックスで問題になったもの • Foliage • ライトの数 • シャドウ • アクター数 • Volumetric Fog わりとあたりまえのことをやってます。
最適化ポイント(Foliage) Foliageが重たい理由は • 数を出したい • マテリアルがMaskedになる場合が多い • 遠くまで表示されると頂点が密集しがち など。 特にMaskedなマテリアルを大量に描画するのはけっこうな負荷 になる。なるべく遠くまでは表示しない、数を出さなくても見 栄えがするように工夫する。
最適化ポイント(ライト) ライトのポイントは • なるべくStaticにする。キャラクタを照らすもの、動的な影を つくりたいものだけStationary • オーバーラップに注意。なるべく2つまで。特にシャドウを 生成するライトのオーバーラップには注意する • 距離設定をきちんとして距離で無効化。画角内に遠方のライ トがたくさん入っていたりすると負荷が高い。 • ポイントライト、スポットライトの範囲を極力切り詰める • エフェクトのライトには注意
最適化ポイント(シャドウ) • 動的なシャドウを極力減らす。とはいえ、キャラに落ちる影 は作りたい。動的シャドウを作るメッシュを厳選 • ポイントライトでシャドウをつくらない • Landscapeの動的シャドウを切った。地形で影を作る必要が ある場合はStatic Meshで作る。 • Inset Shadowsの設定に注意。
最適化ポイント(アクター数) 一度に描画するアクターを減らすと当然負荷は下がる • サブレベルを細かくわけて必要なレベルだけ表示する • CullDistanceVolumeを細かく設定 • マージである程度まとめる(まとめすぎに注意) 遠くの方まで見えすぎないようにレベルデザインにも配慮。
最適化ポイント(Volumetric Fog) Volumetric Fogはかなり多用したが、やはり重い。特にコンソ ールゲーム機。 3Dテクスチャの解像度で軽減可能。コンソールごと、ステージ ごとに細かく設定。 r.VolumetricFog.GridSizeZ r.VolumetricFog.GridPixelSize などがパフォーマンスへの影響が大きい。 荒くするとマッハバンドが目立ったりするので注意深く設定。
最適化ポイント(エフェクト) • エフェクトでライトを発生させる場合は慎重に • 複数発生しないように注意。BPで制御した方が良い場合も • ポイントライトの範囲が大きくならないように注意 • Cast Shadowは極力禁止 • メッシュパーティクルは頂点数少なめに。できればLODも作 る。細かくて頂点数が多いものがたくさんでると激重になり やすい。 実際、エフェクトのライトが負荷になるケースが多かった。エ フェクトは常時出てるわけではないので追っかけにくい。
最適化ポイント(ポストプロセスマテリアル) ポストプロセスマテリアルは仕様が固まったらカスタムノード でコードで書き直すと速くなることがあります。 Dynamic Brunchで必要なピクセルだけ重い処理を行う、変数 スコープの最適化、計算の最適化など。 シノビストライカーでは倍くらい速くなった。
最適化設定アクター サブレベルに最適化パラメーター設定用のアクターを配置して、 BeginPlayで設定を実行するようにしていました。 各種のお決まりパラメーター以外はコンソールコマンドを設定 しておく仕様。 ターゲットのプラットフォームごとに違うパラメーターを設定 できるようにしていました。
最適化ポイント(CPU) 敵が同時に多数Spawnするとヒッチの原因になりがち。時間差 でSpawnさせ1フレームで多数Spawnしないように。 コリジョン判定は問題になりがち。ステージギミックで回転し ているものなどは近くに行くまで止めておく。あるいはコリジ ョンを無効にしておく。複数のコリジョンで構成されたものが 回転していたりすると無視できない負荷になる。
その他小ネタ集
オクルージョンカリング ダンジョン内でカメラが大きく動くと気になるアーティファク トが出る。 オクルージョンカリングが間に合わず、描画が抜けて一番外側 の明るい天球が一瞬見えてしまうのが原因でした。
© & ™ Cartoon Network, Adult Swim 2021
オクルージョンカリング 一瞬とは言え、けっこう気になります。 対処法として有効だったのは、外を暗くするでした。 外が暗ければほとんど気になりません。 メッシュのバウンドを調整したり、オクルージョンカリングの パラメーターを調整したりという正攻法もあるのですが、非常 に手間がかかるのと、パフォーマンス低下につながるので。 ということでダンジョンに入ったところで天球を非表示にして 外を真っ暗にすることで対応しました。
Destructible Mesh 壊れ物はDestructible Meshで作成。しかし細かく分割すると描 画がとても重いので、壊れるまではStatic Meshで配置して壊れ た瞬間置き換える。 とにかく頂点数の多いメッシュが遠くに描画されると頂点が密 集して負荷が激増します。 ワイヤフレーム描画で真っ白にならないように注意。
ワープポータル ワープ先にSceneCaptureComponentを配置して RenderTargetに描画。メインのカメラ位置でCapture側のカメ ラ位置を動かして覗き込んでいるように見せた。 当然描画が重くなるので戦闘中は出ないようにレベルデザイン で対応。
ワープポータル © & ™ Cartoon Network, Adult Swim 2021
画面分割演出 原作アニメで多用されている演出なのでどこかに使いたかった。 ゲーム画面をキャプチャしたものを演出用のポストプロセスで 画面に重ねることで実現しています。 実際の様子は講演動画を御覧ください
画面分割演出 タイミングはシーケンサーで行っています。 • 専用ポストプロセスで画面全体をマスク • 上部のマスクを解除しながらシーン再生 • 画面をキャプチャして上部のマスク部分に貼り付け • カメラを変更して、下部のマスク解除しながらシーン再生 という流れ。 この数秒がまあまあな手間でした。
ポストプロセスマテリアル エフェクト系、アウトラインのポストプロセスマテリアルをい くつか使用していますが、ポストプロセスボリュームではなく、 プレイヤーBPにPostprocessComponentで持たせています。 レベルにいちいちPostprocessVolumeを配置する必要が無く、 BPから制御もしやすくて便利。 レベルに紐づくマテリアルなのか、プレイヤーに紐づくマテリ アルなのかで切り分けるのが良さそうです。