35.5K 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から制御もしやすくて便利。 レベルに紐づくマテリアルなのか、プレイヤーに紐づくマテリ アルなのかで切り分けるのが良さそうです。
マルチプラットフォーム PC(Epic Game Store/Steam),PS4,XBOX ONE,Switch,iOS プラットフォームごとに特殊な対応はあまり必要なかった(iOS 除く) iOS移植はスペインのデベロッパーが行った。 基本的にはUE4の機能でプラットフォームごとの設定で調整。 Dynamic Resolutionの解像度設定、テクスチャサイズ、 minLodなど。Iniファイルでの設定とゲーム中にBPから随時設 定。
資料チラみせ © & ™ Cartoon Network, Adult Swim 2021 © & ™ Cartoon Network, Adult Swim 2021
まとめ
まとめ ありがたいことに、SAMURAI JACK: BATTLE THROUGH TIMEは高評価を頂いています。2年弱の比較的短めの開発期間 で結果は出せたと感じています。 UE4はマルチプラットフォームでのゲーム制作に適してると改 めて思いました。 iOS版ももちろんUE4です。コンソールと遜色のない素晴らしい 移植です。
まとめ SAMURAI JACKの完成には多くの会社の協力がありました。 関係各社のみなさまに、改めて感謝の意を伝えたいと思います。 ありがとうございました。 できれば実際にプレイしてスタッフロールでどんな会社が関わ ったのか確認していただければ幸いです。 ざっと数えてみましたが、25社、350名くらいの方の協力があ りました。
ブラストエッジゲームズ パート 後半はブラストエッジゲームズより、組行動、敵の実装について ご紹介させていただきます。
会社紹介・ブラストエッジゲームズ • コンソール開発経験が豊富なメンバーで構成され、ハイクオ リティなタイトルを制作することを目的に設立されたゲーム スタジオです • 新宿御苑前のオフィスでスタッフは38名 • UE4は本タイトルで初経験 • 現在もUE4での開発をしており、今後もUE4を軸とした開発 を進めていく予定となります • UE4でのゲーム開発をしたいスタッフを鋭意募集中です! https://www.blastedge-games.co.jp/
自己紹介・上野能弘 • • • • • ブラストエッジゲームズCTO ゲーム業界歴20年 主にコンソールのネイティブ開発を経験してきました 最近は進行管理的な役回りが多めです SAMURAI JACKでもエンジニアの進行管理と、細かい部分の 実装やサポートがメインでした
SAMURAI JACKでの組行動の 実装
はじめに SAMURAI JACK BATTLE THROUGH TIME(以降SJと表記)で 組行動をレベルシーケンスで実装したのでその事例を紹介しま す。
目次 • • • • 組行動とは レベルシーケンスで組行動 やってみた感想 おまけ:トランスフォームの取り込み
組行動とは • 所謂「投げ」と言われているもの全般です。SJでは組行動と 呼んでいました。 • 一般的に組行動への要求として、「演出したい、見せたい」 と、「極めてシーケンシャルである」があるので、レベルシ ーケンスとの相性が良いと判断し、SJではレベルシーケンス で実装しました。 ゲームによって多少それが指す範囲は変わると思います。
レベルシーケンスで組行動 レベルシーケンスには様々場面で使えますが、組行動を表現す るのにも適しています。ネット上にもいくつか例が存在してい ると思います。
レベルシーケンスで組行動 非常にありがたいスライド https://www.slideshare.net/EpicGamesJapan/gcc2019ue4 sequencer の p153~ が組行動の説明になっています。 こちらのスライドは他の部分も非常に参考になるのでおすすめ です。
レベルシーケンスで組行動 先程のスライドとだいぶ内容は重複していますが、SJでレベル シーケンスを使って実装した内容を紹介します。
レベルシーケンスで組行動 • レベルシーケンスを任意の場所で再生できるようにする • レベルシーケンスにそのレベルにいるアクターをバインドす る • トランスフォームトラックの制御 • プロジェクトに合わせた細かいこと
レベルシーケンスで組行動 レベルシーケンスを任意の場所で再生できるようにする LevelSequenceActorのInstanceDataを変更し、基準となるア クターにアタッチする必要がありましたが、レベル上に配置し て変更するか、C++で頑張るかしかなく、BPでは変更できませ んでした。 ※4.23で変更可能になる予定だったようですが、SJは4.22での リリースでしたので把握しておりません。
レベルシーケンスで組行動
レベルシーケンスを任意の場所で再生できるようにする
• SJではC++で書き換えできるようにしました。
• LevelSequencrActorを継承したアクターにオリジン用アクタ
ーを設定する以下のような関数を追加しました。
void ASJ_LevelSequenceActor::SetTransformOriginActor(AActor* Actor)
{
UDefaultLevelSequenceInstanceData*
p = Cast<UDefaultLevelSequenceInstanceData>(DefaultInstanceData);
if(p)
{
bOverrideInstanceData = Actor != nullptr;
p->TransformOriginActor = Actor;
}
}
レベルシーケンスで組行動 レベルシーケンスを任意の場所で再生できるようにする BPだけで対処するなら、煩雑ですが、各レベルに OverrideInstanceDataにチェックを入れた LevelSequenceActorと、それのTransformOriginActorが指す アクターを置いておくのが良いと思います
レベルシーケンスで組行動 レベルシーケンスにそのレベルにいるアクターをバインドする • 特定のレベルの特定のアクターを操作しているシーケンスで 任意のアクターを操作するための処理です。 • AddBindingノードを使ってゲーム中のアクターをシーケンス の操作対象とバインドしてました。
レベルシーケンスで組行動 レベルシーケンスにそのレベルにいるアクターをバインドする このノードに渡すための、シーケンス内のバインド先を取得す るノードGetSequenceBindingの引数が入力ピンでなかったた め、組行動の数だけ組行動起動処理を書いてました。今はタグ で指定できるみたいですね。 ワニロボットがジャックに 投げられるシーケンスの起 動部分。折りたたまれたノ ードの中に武器ごとの組行 動の起動がある。
トランスフォームトラックの制御 必須というわけでは無いのですが非常に助けられたのでご紹介
トランスフォームトラックの制御 • トランスフォームトラックとルートモーションを使い分ける • 細かな有効化設定
トランスフォームトラックの制御 トランスフォームトラックとルートモーションを使い分ける トランスフォームトラックとルートモーションでの移動の特徴 は • トランスフォームトラックは 強力にキャラの位置を固定してくれる(環境を無視する)。 • ルートモーションは 地形などにぶつかって動いてくれる(環境に依存する)
トランスフォームトラックの制御 トランスフォームトラックとルートモーションを使い分ける これらの特性からシーケンスの最初の方はトランスフォームで 制御し、後半はルートモーションで動かすと多少地形変化に対 応できるようになる。 そのためトランスフォームで動かす範囲とルートモーションで 動かす範囲は自由に調整したい。
トランスフォームトラックの制御 トランスフォームトラックとルートモーションを使い分ける ということでデータを作るときは • アニメーションはルートモーション付きで作ってもらう • トランスフォームトラックにもすべて座標を入れてもらう としてもらえば • トランスフォームトラックの長さを変えることで自由にトラ ンスフォームの影響範囲を調整できる。 • トランスフォームトラックが有効なところでは、トランスフ ォームによる座標指定が強いのでルートモーションは無視さ れる。
トランスフォームトラックの制御 トランスフォームトラックとルートモーションを使い分ける 実際のデータはこんな感じです
トランスフォームトラックの制御 細かな有効化設定 • シーケンサはトラックごとに有効/無効ができます が、トランスフォームトラックはさらにチャンネル ごとに有効/無効ができます。 • 打撃系の組行動など縦方向に制御する必要がない場 合は、位置のZのチェックを外せば高さが固定され なくなります。 トランスフォームトラックのセ クションの中のキーに触らない 場所で右クリック(注意:トラン スフォームトラックが短すぎる とクリックできません)
プロジェクトに合わせた細かいこと • • • • • • • • 関連キャラを止めてシーケンスに身を任せる OnStopディスパッチャで終了通知 ダメージを与えたり与えなかったりする仕組み 移動に補間を入れる 移動にSweepを入れる イベントでアニメーション再生 イベントで条件分岐 カメラの選択 etc...
やってみた感想 良かったところ • レベルシーケンスは非常に自由度が高かった • アーティストにおまかせでできる部分が多い • ある程度はシーケンスエディタで確認できる • 組行動に関して、エンジニアリングコストがだいぶ省けたと 思います。
やってみた感想 苦労したところ • プロジェクト中のシーケンサーの仕様変更が辛かったです • イベントがBP必須になったため、組行動用シーケンスを組め るアーティストが極端に減ったことです • そもそもアーティストがレベルシーケンスを使えないとこの 方法を取るメリットが減ります
おまけ:トランスフォームトラックの設 定 • SJではトランスフォームトラックは外部のDCCツールで得た ものを取り込んでいました。 • ここではUE4.26で 「アニメーションルートからイン ポート」を使って、アニメーショ ンのルートノードのアニメーショ ンをトランスフォームに設定する 際に気がついた注意点を書こうと 思います。 これ
おまけ:トランスフォームトラックの設 定 • モデルの基本姿勢は可能な限りルートノードの位置も回転も0 にする。 • 取り込んだトランスフォームトラックのブレンドモードはそ のままだと「Additive」です。 • シーケンス中、1キャラ1本のアニメーションで最初から最後 までまかなえていると楽。
おまけ:トランスフォームトラックの設 定 モデルの基本姿勢は可能な限りルートノードの位置も回転も 0にする。 • 4.26の「アニメーションルートからインポート」は位 置も回転も0からの相対位置しかサポートしていません。 • このためアニメーションビュアーのルートモーションの 設定の「Root Motion Root Lock」を「Zero」に設定 して正常な姿勢にならないモーションは「アニメーショ ンルートからインポート」では現在は素直に取り込むこ とはできません。 • どうしても基本姿勢が直せない場合はエンジニアに対応 してもらうしか無いと思います。
おまけ:トランスフォームトラックの設 定 取り込んだトランスフォームトラックのブレンドモードはその ままだと「Additive」です。 • 以前のUEではインポートしたセクションは「Absolute」でし た。そのうえで「ウェイト」のチャンネルが隠れていたので 罠になっていたと思います。 • 4.26では「Additive」なので見た目は解りやすいと思います。 • 「Additive」は他にトラックが無いと、シーケンス外での位 置に足す動作をするようです。 • 煩わしければ他のトラックを消して「Absolute」にしてしま うのが良いと思います。
おまけ:トランスフォームトラックの設 定 シーケンス中、1キャラ1本のアニメーションで最初から最後ま でまかなえていると楽。 取り込んだトランスフォームは、必ず0フレーム目からになっ ているので、移動するのが煩わしい(ミスも出る)というだけです。 外部ツールでモーションを専用に作ってもらえる環境なら1本で 作った方が無難だと思います。
敵の実装 松田理孝 株式会社ブラストエッジゲームズ リードエンジニア
アジェンダ • • • • • 自己紹介 敵の実装方針について BehaviorTreeを中心にした敵単体の実装 敵のグループ行動の実装 まとめ
自己紹介 • 松田理孝(マツダヨシタカ) • 株式会社ブラストエッジゲームズ リードエンジニア • 業界10年目 • ブラウザ、スマフォのゲーム開発を経てコンシューマへ • • RPGメインだったため、今回アクションを初めて担当 サーバ、クライアントの両刀 • 現在はUE4でモバイル案件のリードプログラマ • UE4でモバイル案件は初めて
敵の実装方針について
敵のコンセプト • アニメ原作のIPであり、ソレイユさんの新作である • ゲームの苦手な一部のアニメファンの方 • ソレイユさんのアクションゲームファンの方 • 両者に良さを届けなければいけない • 原作に近いチャンバラ感 • プレイヤーの動きが気持ちいいので、それに応えるようなAI • 時代劇の殺陣
「チャンバラ感」の表現 距離の遠いやつは 素振りしたりして にぎやかし行動をする 一定数以上、 同時にプレイヤーを 攻撃しない 近くの敵は プレイヤーに 攻撃する プレイヤー © & ™ Cartoon Network, Adult Swim 2021
「チャンバラ感」の表現 ボス扱いの敵 遠くから嫌がらせ 空中から嫌がらせ プレイヤー © & ™ Cartoon Network, Adult Swim 2021
理不尽にならないように 嫌がらせの場合は まともに狙わない 遠距離でも 同時に撃たない プレイヤー © & ™ Cartoon Network, Adult Swim 2021
戦闘が単調にならないように 地面に潜って 飛び出し攻撃する敵 デカールで 地面もぐりの表現 プレイヤー © & ™ Cartoon Network, Adult Swim 2021
一方的にならないように プレイヤーがダウン中は 賢く待つ プレイヤー © & ™ Cartoon Network, Adult Swim 2021
敵の実装方針について • プレイヤーと違い、AIで動く • AIController、BehaviorTreeを使用 • 難易度に応じた差別化が必要 • 敵の種類、数、AIなど… • 外からアクションプランナーが調整できるように • UE4を頼る、UE4にないものはしない • オーソドックスに作る
BehaviorTreeを中心にした 敵単体の実装
BehaviorTreeの使い方 • 共通のものは共通BehaviorTreeとする • • • • 移動、プレイヤーのほうを向く、間合いを取る 防御、回避行動 被ダメージ中 待ち行動 • カットシーン、プレイヤーの必殺技演出中など • 敵の固有の行動はサブツリーとする • ほぼ攻撃行動のため、攻撃中以外は共通行動が多い
共通BehaviorTree
共通BehaviorTree バトル中では ない部分 バトル中の部分
共通BehaviorTree 敵ごとの個々の行動のほとんどは バトル中の攻撃行動の違いなので、 この下にサブツリーで繋げている
敵の状態 • AI行動中の状態 • バトル中以外(パトロール中) • バトル中 • 上記の2つの切り替え中 • • 発見行動 撤退行動 • ライフサイクルの状態 • 登場前、登場、AI行動、倒された後
AI行動中の状態 • パトロール中 • 登場してからはこの状態 • バトル中 • プレイヤーとエンカウントすると、この状態に移行 • 上記の2つの切り替え中 • 発見行動 • • 1人が発見したことを仲間に伝え、グループで攻撃状態に移る 撤退行動
AI行動中のBehaviorTreeの管理 • キャラクターはBehaviorTreeに従う • TaskNodeの指示した通りに動く • BehaviorTreeはAIControllerに従う • AIControllerからBehaviorTreeを完全に制御する • AIControllerはBehaviorTreeの状態を完全に把握する
AIControllerに従うことのメリット • 他部分のイベントの処理を一括で担うことができる • リアクティブにTaskNodeを切り替えることができる • BehaviorTreeのフロー制御と併用できる • TaskNodeが終わったら次のTaskNodeに入る部分はBehaviorTree • 特定のイベントが来た際に特定のTaskNodeに移動させる • BehaviorTreeに介入することを可能にする一つの方法
AI行動中のイベント処理 普段は BehaviorTreeに沿った AI行動をする Player AnimNotify/ AnimNotifyState AIController SpawnPoint そのほか BehaviorTree
AI行動中のイベント処理 Player AnimNotify/ AnimNotifyState AIController イベント発生 SpawnPoint そのほか BehaviorTree
AI行動中のイベント処理 Player 実行中の TaskNodeを 取得 AnimNotify/ AnimNotifyState AIController イベント SpawnPoint そのほか BehaviorTree
AI行動中のイベント処理 Player 実行中の TaskNodeを 取得 AnimNotify/ AnimNotifyState AIController イベント SpawnPoint そのほか 結果としてDecoratorを経て 狙ったTaskNodeに入る BehaviorTree パラメータを 設定して BehaviorTreeを Restart
AI行動中のイベント処理 Player 実行中の TaskNodeを 取得 AnimNotify/ AnimNotifyState AIController イベント SpawnPoint そのほか 結果としてDecoratorを経て 狙ったTaskNodeに入る BehaviorTree パラメータを 設定して BehaviorTreeを Restart AEnemyCharactar
実行中のTaskNodeの取得 UTaskNode* AMyAIController::GetCurrentTaskNode() { UBTNode* activeNode = behaviorTreeComponent->GetActiveNode(); FBehaviorTreeSearchData searchedData = FBehaviorTreeSearchData(*behaviorTreeComponent); UTaskNode* instancedNode = activeNode->GetNodeInstance(searchedData); return instancedNode; }
TaskNodeの拡張 • TaskNodeから得たい情報 • 敵が今何をしているのか • • TaskにAttributeをいう「属性」を持たせる 攻撃中、ガード中、被ダメ中、遠くから嫌がらせ中… • 徹底してすべての状態をBehaviorTreeに持っていくことに • AIContollerは「自分がどういう状態か」という変数を持たない • BehaviorTreeが被ダメージ行動中なら被ダメージ状態 • • という形を他でも徹底する 共通BehaviorTreeがこのあたりの多くを吸収する
独自CompositeNodeの作成 連続して同じ子ノードを選ばない。 間合いを 取り続けることはない
独自CompositeNodeの作成 子を確率抽選 敵の行動が単調にならないかつ、 動きが読みやすくならないように。
敵のグループ行動の実装
敵の状態(再掲) • AI行動中の状態 • バトル中以外(パトロール中) • バトル中 • 上記の2つの切り替え中 • • 発見行動 撤退行動 • ライフサイクルの状態 • 登場前、登場、AI行動、倒された後
ライフサイクルの状態 • EnemySpawnPoint • 敵の登場地点を示すActor • 難易度に応じてスポーンする敵情報を持つ • イベントを受け、敵をスポーン • TriggerBoxにプレイヤーが入った • 別のSpawnPointの敵が倒された • 後で解説します • スポーンした敵が倒された時の処理
SpawnPointの配置
Spawnの例 © & ™ Cartoon Network, Adult Swim 2021 プレイヤーが近づいたら 水の中から飛び出す 補充された子 © & ™ Cartoon Network, Adult Swim 2021 敵が倒されたらその分 後ろで補充する
グループ行動 • SpawnPoint同士の紐づけ • 1ウェーブの敵を1グループとする • 前のウェーブが終われば起動する • 同時に出てくる敵の数 • 難易度ごとに変えられる • 攻撃権限の数 • プレイヤーに攻撃可能 • プレイヤーの近くでにぎやかし • より遠くでにぎやかし
「チャンバラ感」の表現(再掲) 距離の遠いやつは 素振りしたりして にぎやかし行動をする 高難易度だと この子も攻撃をする 近くの敵は プレイヤーに 攻撃する プレイヤー © & ™ Cartoon Network, Adult Swim 2021
「チャンバラ感」の実装 • フィールドに出ている敵に個々に行動権を与える • プレイヤーに攻撃していい敵は制限(1匹か2匹) • プレイヤーに近い敵から順に権利を付与 • 周りは当たらない攻撃や回避、防御をしてにぎやかしをする • 上記の行動権が変わったことをAIControllerに通知 • すべての敵が倒されたらイベントを発火 • ギミックが動く、宝箱が出る、カットシーンの再生…
「チャンバラ感」の制御 敵固有の行動を サブツリーで設定
「チャンバラ感」の制御 EnemyGroupManager 自分の管理する敵の行動権限を制御 AIController EnemyGroupManagerから言われたことと、 自身の状態を合わせてBehaviorTreeに伝える BehaviorTree AIControllerに指示された行動権限で思考する AEnemyCharacter フィールド上で動き回る
まとめ
良かった点 • チャンバラ感は良いレベルで達成できた • カジュアル層~ハードコア層まで • BehaviorTreeが素直に動いてくれた • Restart頻繁にして大丈夫かなとか思ったけど… • 後からきた追加要件にも共通部分で対応できた • カットシーン中に敵を止める、など • イベントを送って待つだけなので工数も安かった
反省点 • 完全にBehaviorTreeのポテンシャルを引き出せなかった • 自分に完全なBehaviorTreeのノウハウがなかった • 特にServiceとBlackboardを活かしきれなかった • アニメIP特有の特殊な行動の敵は結局固有に • 倒したら分裂して増えるとか • 敵を生む敵とか
BehaviorTreeは楽しい
ご清聴ありがとうございました 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.