2.5K Views
July 28, 26
スライド概要
Unreal Engineを開発・提供しているエピック ゲームズ ジャパンによる公式アカウントです。 勉強会や配信などで行った講演資料を公開しています。 公式サイトはこちら https://www.unrealengine.com/ja/
EPIC PRESENTATION 2026 テック&ゲームプレイ振り返り プログラマーとデザイナーの理想的なコラボレーションを求めて 発表者:Tom Guillermin、Sandfall Interactive
プログラマーとデザイナーの理想的なコラボレーションを求めて (クリエイティブビジョンを支える技術についての、Unreal視点の振り返り) …
Bonjour, mes amis !(皆さん、こんにちは!) Sandfall Interactiveの前の経歴: Tom Guillermin テクニカルディレクター & リードプログラマー ★ 2017年にUbisoftに入社して、ゲームプレイプログラマーとして5年間 ★ 関わったタイトル: ★ ○ Tom Clancy’s Ghost Recon(オフライン&4人協力プレイ) ○ The Division 2(オンラインマルチプレイ) ○ Beyond Good & Evil 2(オンラインマルチプレイ・まだ開発中) JRPG熱は Guillaume (Broche) ほどではないけど、GBAの Golden Sun 1・2(黄金の太陽) が大好き Sandfall でのテクニカルディレクターとしての仕事: ★ バトルシステムの中核をプログラミング ★ ゲームデザイナーの要望に応えるスクリプト機能の追加 ★ プロジェクト全体の技術面を統括: パフォーマンス、パッケージング、ツール&ワークフロー、社内ITインフラ
本日:CO:E33 のクリエイティブビジョンを支える 技術についての、Unreal視点の振り返り 本日の2つの大きな問い: ★ 何が うまくいったか? (●'◡' ●) ★ 何が うまくいかなかったか? (●′⌒`●) アジェンダ: - - - Unreal との働き方 バージョンの変遷 スタジオ構成 命を救ってくれた、そしてお気に入りのUE機能 機能とゲームコンテンツの制作 概要 カスタムツール スクリプトツールボックス 深掘り:ゲームデザイナーがLuminasでバトルシステムを調整できるという挑戦 ゲームのパッケージングとリリース 様々な苦労話 :-)
Unreal との働き方 エンジンのバージョン Sandfall での Unreal Engine バージョン の変遷: - プロジェクトは 4.21.2 で 2019年1月にスタート 同じプロジェクトファイル(“Sandfall.uproject”)を最初の試作から製品版までずっと使用(本当に!) 4.26 までのアップデートはすべて対応 UE 4.26 から自前でエンジンをコンパイル開始 バーティカルスライスを 4.26 で出荷 5.0 Preview を別ブランチでテスト Nanite、Lumen、Metahuman にワクワク (同時に、ゲーム全体をライティングし直すと気づいた瞬間でもある ) - 5.0.0 はリリースされてすぐアップデート! - その後 5.1.X、5.2.X、5.3.X の中間アップデートもすべて対応し、最終的に 5.4 へ - Clair Obscur: Expedition 33 を 全プラットフォームで 5.4.3 でリリース
Unreal との働き方 エンジンのバージョン そう、バージョンが多い! 何が うまくいったか? (●'◡' ●) - 新しいワークフローを可能にする新機能:Nanite、Lumen、Metahuman バグ修正とパフォーマンス改善が無料で手に入る 何が いまいちだったか? (●′⌒`●) - 移行にプログラマーの時間がかかることがある UE 5.0のPreview版 は移行に時間がかかり、しかもリリース版5.0とはかなり違っていた
Unreal との働き方 Sandfall のスタジオ構成 おなじみの P4 + + + - 堅牢で業界標準 Unreal との統合が優秀 Epic の P4 にアクセスできる! 5人を超えるとライセンス費用が高 い Unreal Game Sync + + + 同期やブランチの切り替えが簡単 エンジンバイナリの配布が簡単 ビルド情報を付けるタグシステム Teamcity - (本番後半で導入) 自動化を作るのが簡単: ビルドログやエラーなどの確認が簡単 メトリクス機能が統合されている
Unreal との働き方 Sandfall の開発思想 - エンジンの大きな改造やリファクタリングはしない - EpicのP4/Github/EPSからのバグ修正は取り込む - Unreal Engineの標準的なアプローチと機能(Actor、Component、Data Asset、Sequencer)を 活用している - 可能な限り、自作せずネイティブのUnrealツールを使う - 複雑なエンジン機能は、サポートされているプラグインを活用しています。(例:3D UI) うまくいった点: (●'◡' ●) - プログラマーがゲームプレイ機能の制作により多くの時間を使える ほぼバニラなのでエンジンのアップデートが楽 いまいちだった点: (●′⌒`●) - コンテンツ制作のUXがUEの標準プロパティエディタのまま => デザイナーがワークフロー上あまり導かれない
Unreal との働き方 エンジンのネイティブ機能が強い味方に Sandfall のプログラマーはたった4人 でも実際には、200人超のエンジンチームが私たちのためにUEに働いている! → 独立系スタジオでは自前で作る時間がない高度な機能がたくさん: メリット: エンジンではなく ゲームそのもの の制作に集中できる デメリット: - Unreal Engineの流儀に従う - 利用できるツールを理解するのに追加の手間がかかることがある(ドキュメンテーション)
Unreal との働き方 エンジン機能を活用する 各機能が Sandfall の働き方にどう影響したか: グラフィックス ● Nanite: ○ +:アーティストがポリゴン数を気にする時間が激減! ○ -:最適化が直感的でないことも(例:小さいオブジェクト/ジオメトリのコスト) ● Lumen:大きなゲームチェンジャー: ○ 以前:バーティカルスライスではUE4の動的ライティングを使用。雰囲気の変化が多くスムーズな遷移が必要だっ た ⇒ パフォーマンスに大問題、このままだとリリース不可能 ○ + :環境アーティストの高い表現の自由度 ○ -:全部ライティングし直す必要があったが、その価値があった ● Virtual Shadow Maps: ○ 新技術=Invalidation Cacheを使った新しい最適化手法エディターのデバッグビューで簡単に確認できます。 ○ Nanite に全振りせざるを得なくなる(悪いことばかりではない!) ■ (実際にVSMのおかげで、Nanite化し忘れたアセットをいくつか発見!) ● Niagara:VFXアーティストのLeoは、UE4の実験的プラグイン時代から夢中
Unreal との働き方 エンジン機能を活用する 各機能がSandfallの働き方にどう影響したか: キャラクターパイプライン - Metahuman 最初はCharacter Creatorを使用した(プロモ動画まで作った!) MetaHumanが使えるようになって、すぐに導入 リスカルプトのチュートリアルをYouTubeで最初に公開したのは私たち! - アニメーションシステム(Anim Graph/ABP): Guillaumeとテクニカルアニメーターが、プログラマーの手を借りず自分たちでアニメーションシステム を構築 高いクリエイティビティの自由度 特定コンテンツ向けの専用機能を作れる(例:カットシーン)
Unreal との働き方 エンジン機能を活用する 各機能が Sandfall の働き方にどう影響したか: ゲームコンテンツ ● ● ビジュアルスクリプティング(Blueprint):ゲームプレイロジックの95% ○ +:おそらく史上最も堅牢で完成度の高いビジュアルスクリプティングツール ○ +:「視覚型の頭」の人にも使いやすい ○ -:マージ周りのツールに一部制約あり Sequencer:非常に強力なWYSIWYG(見たまま編集)ツール (先ほどGuillaumeの愛が伝わったと思います) 開発ツール ● Editor Tools Framework : アセット操作やエディターパネルなど、UE標準のエディターツールを活用 ● データ検証(Data Validation) ● 自動テスト 残念ながら、テスト環境を維持するのが難しかったため、途中で利用をやめた
Unreal との働き方 エンジン機能を活用する AutoTest_DualScreen.mp4 自動テストフレームワークの映像(2021年)
Unreal との働き方 エンジン機能を活用する 各機能が Sandfall の働き方にどう影響したか 最適化 ● ● World Partition ○ 以前は Level Streaming を使っていて、ロード時にカクつきが発生 ○ WPでストリーミング性能が大幅に改善(特にSpatialHash) HLOD ○ 広大なワールドマップと長い描画距離では、本当に命を救った DevOps&リリース ● ● ● ● パッケージング処理 MPCでのクック commandlet UGS
Unreal との働き方 エンジン機能を活用する まとめ: メリット: - エンジンではなくゲームそのものの制作に集中できた - デメリット: - Unreal Engineの流儀に従うことが必要 「Unreal Engineの流儀に従う」のは分かりにくい場合があり、利用できるツール/ドキュメ ンテーションを理解するのに追加の手間がかかる
Unreal との働き方 開発思想:カスタムツール UIナビゲーション: ネイティブのSlateでのフォーカス管理は…なかなか複雑になりがち そこで独自のシステムを実装: そして機能がどんどん必要に…(複数階層、ループなど)
Unreal との働き方 開発思想:カスタムツール メリット: - ナビゲーション挙動を完全に制御できる デメリット: - ユーザーの手作業が多い(例:エッジや階層の宣言) - 「走りながら作る」ようなもの - 既存メニューを壊さずに保守・拡張するのがすぐに複雑になった - 貴重なプログラマーの時間を使ってしまって… - …しかも後で分かったが、それはCommonUIがネイティブで対応していた!
Unreal との働き方 開発思想:カスタムツール 完全にCommonUIへ移行した
Unreal との働き方 プラグイン CO:E33 では多くのプラグインを使用: - - Unreal プラグイン(約30個) - CommonUI - MetaSound - GeometryScripting - レンダリング:Water、HairStrands 外部プラグイン(約25個) - 3C:ALS(Advanced Locomotion System) - UI:Niagara UI、LGUI(バトル) - アニメーション:MeshMorpher、KawaiiPhysics、DragonIK 19
Unreal との働き方 プラグイン うまくいった点: - - 導入が簡単 自前で作る時間がない複雑なエンジン機能が手に入る 非プログラマーでも素早く機能を試作できる 他の開発者のアプローチはとても参考になります いまいちだった点: - - 不要な機能を削ぎ落とす必要があるプラグインもあった(余計なCPUやメモリのコスト) コンソールでうまく動かないプラグインもあった プラグインは移行を難しくする場合がある 4.26から5.0への移行は意外にもスムーズだった 非推奨APIを使用していた一部のプラグインを除く
ゲームを作る Sandfall におけるプログラマー ⇔ デザイナーの連携 できるだけ多くのゲームコンテンツをどう作るか? 主な制約:プログラマーのリソースが限られている ⇒ゲームデザイナーが何でも作れて、自分で直せる環境を作る ● ● 宣言的データ ○ データ検証 命令型スクリプト ○ エラーフィードバック
ゲームを作る Data Assetだらけ ● ● 宣言的データで最も気に入っている機能のひとつ 用途 : ○ スキルの定義 ○ スキルグラフ ○ アイテム ○ レベルスクリプト用アクション(シネマティック、 ゲーム内会話、BGM切り替え など) ○ 条件判定 ■ レベルスクリプト ■ 実績 ○ 等々 Sandfall Interactive - Confidential - Do Not Share
ゲームを作る データのポリモーフィズム お気に入りのデータ機能: ● ● EditInlineNew + Instanced サブタイプを選び、固有のプロパティを設定可能 サブタイプごとに異なるプロパティ: UX: nice type selector
ゲームデータ用のツール スキルエディタ:ドラッグ&ドロップ対応のシンプル なUMGキャンバス 個別スキル編集UIはShowObjectDialogを使用 (つまり、クラスから自動でMVVM) 24
CO:E33 のスクリプトツールボックス ● 基本のライフサイクルイベント: スキル発動/ダメージ、敵ターンの開始、バフの有効化/無効化 ● システムが公開するイベントディスパッチャーを通じてゲームプレイに反応する ● インターフェース関数の実装で挙動をオーバーライド: ○ ゲームプレイのアクション(例:バフ付与)をオブジェクトとして表現。有効なバフ間で受け渡され、変更可能 ■ 例:早期キャンセル、パラメータ変更など ○ Gameplay Actionオブジェクトを変更する ■ 例:バフの適用を防ぐ: ● 例:Longer Rush:Rushのターンを2つ延長 ○ Rushバフの適用を検知 ○ 効果時間を延長 ● 例:Greater Speed:「+25%Rushスピード上昇」 ○ 元の Rushバフをキャンセル ○ その代わりにカスタムバフを適用 ○ 多段階のダメージ計算を、別々のイベントで変更する ○ 各ステップで2つのダメージ修正プールを使用:加算&乗算
バフシステム:バトルシステムの中核 - - - 最も古いバトルシステムの一つ 基本原則: 指定したターン数の間、キャラクターにBlueprintスクリプ トを適用 バフは主要なバトル機能のほとんどの挙動を変えることができる: ステータス 属性相性 ダメージ&回復量 AP消費 防御行動をブロック 他のバフの適用を防ぐ 一部のアクションをキャンセル 等々 26
バフシステム:バトルシステムの中核 Clair Obscur : Expedition33ではバフが実に多くの用途で使われている! 状態異常:火傷、麻痺など パッシブ効果 装備、武器 & 習得したパッシブ ヒーロー 固有のメカニクス 例: VersoのPerfection、ScielのSun/Moon/Twilight 敵 固有の挙動 例:Braseleur は火と氷の属性を切り替える 例:Mime …さらに内部的な用途も:マーカーとして便利 (例:クールダウン) 27
バフシステム:バトルシステムの中核 - - ゲームデザイナーは、できるだけ多彩なパッシブ効果を作りたがっていた。 プレイヤーが最大限の自由にビルドを作れることを目指しました。 あるパッシブ効果が別のものを発動できるので、シナジーが生まれる。 ただしプレイヤーの作るものを全部は予測できないため、システムの制御は難しくなる! 結果、こうなることも… :
バフですべてを変更する - バフは限られたターン数だけ持続し、その後無効化される - そのため、キャラクター/バトルを発動前の状態に戻せる必要がある - つまり、バフのBPからシステムのプリミティブ変数(float、bool など)を直接変更してはいけない また、複数のバフが同じ要素を変更しうる ⇒ 同じ値への複数バフによる同時変更をサポートする必要がある ⇒ バフの発動順が挙動に影響してはいけない(例:MaelleのVirtuoseは、プレイヤーが期待する 200%のダメージを常に出さなければならない)
バフですべてを変更する - この問題に対処するため、Handle を生成するModifier Stackのシステムを使う - ゲームプレイ機能が、変更可能な値を提供する(例:キャラクターのステータス上昇) - どのスクリプトも、その機能にModifierをプッシュできる - 見返りにHandle(=一意のID)を受け取る - 変更を取り消したくなったら、そのHandleをシステムに返す。システムは対応するModifierを 無効化する → きれいに無効化する責任は、GDコンテンツではなくシステム側にある (例:Modifier除去後の新しいステータス値を計算する)
混沌を整理する:バフ 簡単な例 Verso のステータスシステム Speed=100 Speed=150 Speed=170 Speed=120 Speed=100 Modifier 002: Speed+20% Modifier 001: Speed+50% Speed +50% Handle ID: 001 ID: 001 バフ1 有効化 無効化 Speed +20% Handle ID: 001 ID: 002 バフ2 有効化 無効化
混沌を整理する:バフ スタック方式:変更の追跡には堅牢 GDによるHandle管理は、無効化ロジックに手作業が増えてしまいます バフのスクリプトで正しく削除されないと、「孤児」したModifierが残ることがある ⇒ より良い解決策は、Modifierを発端のUObjectに紐づけて無効化を自動化することだった
混沌を整理する:パッシブ効果 - 問題は値の種類によって扱い方が異なる、主なものは、Bool型と数値型の2つです: Bool値は「Block」と「Force」の2種類に分かれています。どちらを優先するかは、システムが自動で判断 します。 例: PreventDeath, BlockBreakDamage, ForcedAutoAttack - ダメージには、ゲームデザイナーが使える2種類のModifierがある:加算 - Modifierは演算ごとにまとめられ、順番に関係なく集計される と 乗算 バフ1 バフ2 加算1 加算2 加算の合計 +15% +50% +65% = 165% 乗算 バフ3 200% 乗算の合計 200% 総計 165% x 200% = 330%
混沌を整理する:パッシブ効果 - 多くのパッシブ効果が1つのゲームプレイ イベントから発動しうる - 1つのパッシブ効果が別のものを発動 できる - プレイヤーのビルド次第で、何が起きる か事前には分からない
デザイナー向けの再利用可能なビルディングブロック プログラマー向けの基本原則: - プログラマーはBPでゲームプレイ機能をデザイナー向けの「ブラックボックス」として作る - プランナーが利用できる汎用的な構築ブロックを公開する - システムをデータの生成/管理(戦闘、クエスト、フラグ、インベントリなど)に向けて 設計する プランナーは利用可能なすべてのBlueprint機能を自由に使える クエストシステム クエストのスクリプトAPI クエストのスクリプト/コンテンツ コード&Blueprint、プログラマーのみ Blueprint、プログラマーのみ Blueprint、デザイナー(+プログラマー) 35
ゲームをリリースする E33での反復開発 継続的インテグレーション:Teamcity さまざまなシナリオの自動化: ● ● ● ● ● ● ● UGS向けにエディタバイナリをビルド&公開 ○ コード変更後に自動実行 毎晩プロジェクトをパッケージング ○ 選択可能:プラットフォーム、ビルド構成、カスタムパラメータなど パッケージをNASにアーカイブ Steamへアップロード/新ビルドでSteamベータブランチを更新 navmeshの再ビルド 全プラットフォーム向けのパッケージング・アーカイブを一括実行するマクロ Discord に更新を送るカスタムステップ
ゲームをリリースする E33での反復開発 継続的インテグレーション:Teamcity さまざまなシナリオの自動化: ● ● ● ● ● ● ● + + - UGS 向けにエディタバイナリをビルド&公開 ○ コード変更後に自動実行 毎晩プロジェクトをパッケージング ○ 選択可能:プラットフォーム、ビルド構成、カスタムパラメータなど パッケージを NAS にアーカイブ Steam へアップロード/新ビルドで Steam ベータブランチを更新 navmesh の再ビルド 全プラットフォームでパッケージング+アーカイブを実行するメタ自動化 Discord に更新を送るカスタムステップ 毎晩ビルドを開始する精神的負担がない 毎日のビルドで、プロジェクトが確実にパッケージ化できると保証される 自動化の初期設定には時間がかかることがある プロジェクト内に壊れたアセットが1つでもあると=パッケージング全体が失敗=そ の日はビルドなし Teamcity - (本番後半で導入) - 自動化を作るのが簡単: - ビルドログやエラーなどの確認が簡単 - メトリクス機能が統合されている Sandfall Interactive - Confidential - Do Not Share
ゲームをリリースする E33での反復開発:Teamcity 統合メトリクス: + + - ● ビルド時間 ● Cook済みアセットのサイズ ● ビルドサイズ 毎晩ビルドを開始することを気にしなくてよくなりました。 毎日のビルドで、プロジェクトが確実にパッケージ化できると保証される 自動化の初期設定には時間がかかることがある プロジェクト内に壊れたアセットが1つでもあると=パッケージング全体が失敗=その日はビルドなし
ゲームをリリースする E33 のリリース CO:E33をリリースするためのP4のブランチモデル: + + - 私たちが作ったいくつかのカスタムDevOpsツール: nextcontent: 次のパッチ(=バグだらけ) ↓ main: 現在のパッチ(=少しバグあり) ↓ release:リリースと緊急修正のみ(=非常に安定) 問題の原因になりそうな新しいコンテンツを切り分けやすくなる ブランチの再利用=メンテナンスの負担が少ない ブランチの再利用=チームにとって分かりにくい Upstreamの変更でマージできなくなる場合がある - 安定性のため:Changelist承認ツール (Discord 上) - 対象のChangelistに含まれるすべてのファイル の依存関係を解析するマージツール (Horde+Robomerge でもよかったが、すべ てをきちんと設定する時間がなかった :-( )
結論(?) Axel Riffardから、CO:E33で最も興味深かった技術的課題について聞かれた。 でも私たちの一番の秘訣は、技術が決して邪魔をせず、クリエイティブビジョンをただ支えること 小さなチームなので、技術的な選択をする際はシンプルさ優先で進めた 既製の機能を使い、使い方を学んで習熟し、ゲームを作った 長期的に保守できると分かったときだけ、エンジンに手を入れた 人手が足りないときは、プラグインを使うことを恐れなかった ほとんどの時間を、デザイナーに必要なビルディングブロックをすべて用意することに費やした さて、このプレゼンテーションの締めくくりに、ゲームリリース時に遭遇した美味しい苦労話のおまけを少し!
終わる前に、いくつかのバトル秘話(1/3) ● セーブデータのバージョニング: ○ セーブデータにバージョンを付けたのは、開発のかなり終盤 ○ 最悪のシナリオだった:BlueprintのみのSaveGameクラスが、BP上の多くのゲームプレイシステムと 密結合 ○ この結合のせいで、BPクラスを維持するしかできなかった ○ そこで次の組み合わせを使った: ■ 継承を使って、セーブデータの各バージョンをクラスとして定義 ■ 移行関数で、古いバージョンを N から N+1 へアップグレード(連鎖で複数回のことも) ■ カスタムのディープコピーで、それらのバージョンをBlueprintのみのSaveGameオブジェクトに流 し込む
終わる前に、いくつかのバトル秘話(2/3) ● PlayGo/ストリーミングインストール向けにゲームデータをチャンク化。目標:20GB未満のプレイ可能な チャンクを作ること ○ 私たちのプロジェクトは、Soft Referenceだらけの地獄でした。(Data Tableがあらゆるものを参 照していたため) ○ そのせいでゲーム全体がChunk 0に入ってしまった ○ ステップ1:参照をいくつか整理した(どこかに不要な参照って、必ずありますよね) ○ ステップ2:次の組み合わせを使った: ■ -FileOpenOrderの実行で、環境アセットのリストを収集 ■ ゲームデザイナーの協力を得て、「Early Game」に必要なData Tableの特定の行をリスト化 するスクリプト ■ 不足している参照をすべて探索するカスタムの依存関係探索ロジックを実装 ● (ということは:Data Table以外をすべて探索する)
終わる前に、いくつかのバトル秘話 (3/3) ● PSOコンパイルの最適化: ○ 5.4のPSOプリキャッシュはあまり良くなく、すぐに詰まって多くのカクつきを引き起こした。後で改善さ れたが、変更をすべて手動でバックポートする時間はなかった ○ PSOプリキャッシュを直す代わりに、コンパイルするシェーダー数を単純に減らすことに取り組んだ: ■ 不要なstatic switchを削除 ■ すべてのMaterial Instanceを親付け直しして、PSOプリキャッシュ時にエンジンが同一シェーダ ーを識別しやすくした ○ ちょうど問題に取り組んでいたときに、Epicから公式ドキュメントやガイドが出てきて幸運だった (遅かったけど、手遅れではなかった! ) 今回の教訓:困ったことがあれば、EPSに投稿し、Epicの担当者にも相談しましょう! Sandfall Interactive - Confidential - Do Not Share
(VISUAL SCRIPTING IS LIFE ) (ビジュアルスクリプティングは人生) 質問はありますか? Sandfall Interactive - Confidential - Do Not Share
MERCI(ありがとうございます) Sandfall Interactive - Confidential - Do Not Share
プラグイン 使うことを恐れないで! - 統合が簡単で、素早い試作に向く - ゲームを作り込む際の試行錯誤のサイクルを大幅に短縮 でも注意: - バグ、特にコンソールで - UE更新時にブロッキングな依存関係になりうる - 整理してクリーンアップが必要 46