131K Views
December 21, 23
スライド概要
Unreal Engine 5 の自動化に関する機能、およびプロジェクトの最適化に活用できる機能を紹介しています。具体的なスクリプトや最適化に活用できるTipsを紹介していますので、是非プロジェクトへ自動化や最適化を適用する際のアイデアを参考にしていただければと思います。
※本ドキュメントは UE5 Deep Dive 2023にて講演した資料を配布用に編集したものです
Unreal Engineを開発・提供しているエピック ゲームズ ジャパンによる公式アカウントです。 勉強会や配信などで行った講演資料を公開しています。 公式サイトはこちら https://www.unrealengine.com/ja/
Unreal Engine 5 - プロジェクトの自動化と最適化戦略 Epic Games Japan Software Engineer, Developer Relations Ken Kuwano 2023 Private & Confidential
セッションについて ● バージョン UE5.3 時点での内容について言及 ● スクリプトなどは後で参照できるように公開予定
セッションの目的 ● 自動化機能の再確認 ● ● ● 自動化アイデアの提供 ● ● ● エンジンにはどういった機能があるか プロジェクトでどう拡張していくか 自動化をワークフローにどう適用できるか、選択肢の提示 プロジェクトで活用する際の応用 自動化×最適化による効率化の提案 ● ● UE プロジェクトにおける自動化の生かし方 開発効率を上げるための工夫と模索
自動化の重要性と背景 ● 効率性の向上 ● ● 生産性の向上 ● ● 自動化によって別の作業にタスクを割り当てることが可能 品質の向上 ● ● 反復的な作業を迅速にすることで効率化 ヒューマンエラーの防止、テスト自動化によるバグの発見 開発コスト削減 ● 人的リソースの節約
自動化の課題 ● 自動化のための作業時間の確保 ● 自動化のスクリプト, シナリオ, テスト生成の時間が取れない ● 機能を使いこなすための学習コストが確保できない ● 自動化のネタがない
ゲーム開発における自動化 活用例 ● ● ● ● ● ● ● ● ● ビルド、デプロイ テスト アセット生成 コード生成 コード解析 ローカライズ セキュリティと不正検出 オートプレイ ログ分析 ● ● ● ● ● ● レベル生成 難易度調整 タスク管理 バグチケット管理 コードレビュー etc...
Agenda ● エンジンの自動化機能 ● 開発ワークフローの自動化 ● 最適化の自動化
Agenda ● エンジンの自動化機能 ● 開発ワークフローの自動化 ● 最適化の自動化
エンジンの自動化機能 自動化に利用できそうなエンジンの機能 ワークフロー ビルド テスト Editor Utilities Python Commandlet Unreal Automation Tool Unreal Build Tool Build Graph Functional Test Automation Driver Automation Spec Gauntlet
ここでエンジンの自動化機能の 概要のみを説明 詳しくはドキュメントを参照
エンジンの自動化機能 自動化に利用できそうなエンジンの機能 ワークフロー ビルド テスト Editor Utilities Python Commandlet Unreal Automation Tool Unreal Build Tool Build Graph Functional Test Automation Driver Automation Spec Gauntlet
自動化:ワークフロー Editor Utilities ● ● ● ● ● Blueprint で作成するスクリプト エディタから簡単に実装/試行できる 複数アセットに対して一括で設定反映など レベル上のアクターに対する設定など エディタのメニュー拡張など Unreal Editor のスクリプト処理と自動化 https://docs.unrealengine.com/5.3/ja/scripting-and-automating-the-unreal-editor/ エディタ ユーティリティ ウィジェット https://docs.unrealengine.com/5.3/ja/editor-utility-widgets-in-unreal-engine/
自動化:ワークフロー Python ● ● Python コードで作成するスクリプト スクリプトベースで試行錯誤しやすい ● ● ● ランタイムでの利用は処理コストの都合でオミット エディタで利用可能 大量のアセットへのアプローチなど Python を使用した Unreal Editor のスクリプティング https://docs.unrealengine.com/5.3/ja/scripting-the-unreal-editor-using-python/
自動化:ワークフロー Commandlet ● エンジン内で実行するコマンドラインプログラム ● ● エディタの外部で実行する ● ● C++コードで自分で拡張することも可能なコード アセットのインポート、アセットのクック、処理など コンテンツに大量の変更を加える場合や、イテ レーションする場合に使用 UCommandlet https://docs.unrealengine.com/5.3/en-US/API/Runtime/Engine/Commandlets/UCommandlet/
自動化:ビルド Unreal Automation Tool ● ● UEの無人プロセスのスクリプティングに使用でき るホストプログラム ビルド、クック、実行、自動化テストの実行、ビ ルド ファームで実行するその他の操作のスクリプ ティングなど AutomationTool の概要 https://docs.unrealengine.com/5.3/ja/unreal-automation-tool-overview-for-unreal-engine/
自動化:ビルド Unreal Build Tool ● ● Unreal Engine ソース コードのコンフィギュレー ション プロセスを管理するカスタムツール エンジンのビルドに必要なパラメータや、ビルドの オプションとなるパラメータを解析して処理 UnrealBuildTool https://docs.unrealengine.com/5.3/ja/unreal-build-tool-in-unreal-engine/ ビルド コンフィギュレーション https://docs.unrealengine.com/5.3/ja/build-configuration-for-unreal-engine/
自動化:ビルド Build Graph ● ● ● ● スクリプトベースのビルド自動化システム BuildGraph スクリプトは XML で記述 癖があり直観的ではないため学習コストが高い InstalledBuild 作成, PhysXBuild ビルドなどで利用 Build Graph https://docs.unrealengine.com/5.3/ja/buildgraph-for-unreal-engine/
自動化:テスト Automation Driver ● ● ● ● (プラットフォームを問わず)アプリケーションの ユーザー入力をシミュレートできるテスト機能 カーソル、クリック、プレス、キーボード入力、ス クロール、D&Dなどをサポート コントローラ, ジェスチャーなどは未サポート 現在も積極的な開発は停止中 Automation Driver https://docs.unrealengine.com/5.3/ja/automation-driver-in-unreal-engine/
自動化:テスト Automation Spec ● ● ● Spec:ビヘイビア駆動開発 (BDD) 手法に従って構 築されたテスト プログラムに期待される”振る舞い”, “要求仕様”に 近い形でテストコードを記述することで、動作仕様 の確認に利用 Online, BuildPatchServices のテストで利用 Automation Spec https://docs.unrealengine.com/5.3/ja/automation-spec-in-unreal-engine/
自動化:テスト Guntlet Automation Framework ● ● ● 自動テスト目的のスクリプト、物事を実行して結果 を検証するフレームワーク Unreal Engine の セッション を様々なプラット フォームで実行することを目的 アプリケーションの外側にテスト条件やアプリケー ションに影響するパラメータの定義 Gauntlet Automation Framework https://docs.unrealengine.com/5.3/ja/gauntlet-automation-framework-in-unreal-engine/
自動化:テスト 様々なテストとプラグイン ● CQTest 非同期実行で実施する様々なエンジンの機能テスト ● FBXAutomationTestBuilder FBXファイルについて独自のテストを作成可能 ● RHITests RHI 関連のテストを提供 ● Screenshot Comparison Tool テスト実行中にスクリーンショットを取得、比較 ● InterchangeTests インポートシステム Interchange 関連のテスト
Agenda ● エンジンの自動化機能 ● 開発ワークフローの自動化 ● 最適化の自動化
開発ワークフローの自動化 開発全体フロー 企画 プリプロ 本製作 量産 テスト 保守/運用 起動 実装 確認 修正 保存 開発ワークフロー 同期
開発ワークフローの自動化 自動化を開発ワークフローどう適用する? ● ● ● ● ● ● ● ● ● ● 夜間のビルド、パッケージ作成 誰もいない時に自動でテスト実施 アセットを効率的に量産する シーンを効率的に構築する アセットのレギュレーションをチェックする 多くのアセットに対して一括で修正を加える 確認を簡単に、かつ正確に行う 問題を一早く検知する、修正する データ、レポートを通知する etc...
開発ワークフローの自動化 レポート通知 ビルド クック レポート通知 ビルド クック クラウドビルド環境 ビルドマシン アセットの 自動ビルド 自動デプロイ 自動テスト アセットの 自動同期 サーバー アセットの 自動同期 ターゲット デバイス コードの 自動テスト ローカル環境 App
具体的なワークフローでの Unreal Engine での自動化例を紹介
Editor Utilities Editor Utilities の活用 ● ● ● エディタから簡単に実装したり試行できる Blueprint で書くスクリプト カスタムUIを作成して拡張が可能 エディタのメニュー拡張も簡単 アイデア ● ● ● ● 親クラスの設定が正しいかチェック アセットの bNaniteMesh が有効か Collision Preset が正しいか Physics Materia が設定されているか ● ● LODが適切か LOD Collision が設定されているか
Editor Utilities Editor Utilities の使い所 親クラス 用途 Editor Utility Widget UIを自分でカスタマイズして処理したい Editor Utility Action エディタの既存UIにメニューを追加して処理したい Editor Utility Object UIなしで Editor からスクリプトの処理したい Editor Utility Actor Actor に関連してスクリプトの処理したい Editor Utility Actor Component Actor Component に関連してスクリプトの処理したい Editor Utility Task バックグラウンドタスクで非同期に処理したい Editor Utility ToolEntryMenu Editorのツールバー/ツールメニューに項目を追加したい Asset Action Utility アセットに対して実行できるメニューを追加したい スクリプト アクション https://docs.unrealengine.com/5.3/ja/scripted-actions-in-unreal-engine/
Editor Utilities 例:LODが設定されていない SkeletalMesh を探す AssetActionUtility
Editor Utilities 例:Python Script と連動してファイルを開く EditorUtilityWidget
Editor Utilities 例:レベル編集用のActorから編集用のメニューUIを開く EditorUtilityActor + EditorUtilityActorComponent + EditorUtilityWidget ● ● Editor Utility Actor や Actor Componet を利用することは、 Editor Onlyのアセットとして利 用範囲の切り分けできる、 Editor Utility Subsystem へ アクセス可能 SpawnAndRegisterTab で Widget を動的生成
Editor Utilities EDC:33 のスクリプトの事例 選択したアセットに対して一括設定を適用したり、手動では手間がかかるような 操作に対して一括で制御を行うスクリプトを提供 Automate with 33 Scripted Action Utilities (UE5.1だがアセットバージョンについて注意) https://dev.epicgames.com/community/learning/tutorials/1x0V/unreal-engine-automate-with-33-scripted-action-utilities
Editor Utilities Tonkotsu さん:https://shuntaendo.hatenablog.com/entry/2023/07/20/174644 Kinaji さん:https://kinnaji.com/2021/12/17/editormenu/
Editor Utilities https://cgworld.jp/regular/202312-ue5tool-01.html
Python Script Python Scripting の活用 ● ● ● コードベースで作成可能で流用やファイル管理も容易 スクリプトのデバッグが必要になってくる エディタのリフレクションを利用 ● Blueprint でアクセスできる関数、パラメータへのアクセスが可能 アイデア ● ● ● ● Blueprint アセットの自動生成 FBXファイルをインポート レベル内で選択した BP Actorの Componentの名前を一括で変更 指定されたタグを持つアクターを置換 ● ● ● Control Rig の作成/編集 シーケンサーへのトラックの追加 エディタメニューの追加
Python Script import unreal 新しい Blueprint を作成してプ ロパティをセットする asset_name = "BP_MyPythonActor" package_path = "/Game/MyContentFolder" ● ● エディタから実行する場合、 Blueprint の親クラスを選択 して作成、保存が必要 初期値の設定も一括で実施 factory = unreal.BlueprintFactory() factory.set_editor_property("ParentClass", unreal.Actor) asset_tools = unreal.AssetToolsHelpers.get_asset_tools() my_new_asset = asset_tools.create_asset(asset_name, package_path, None, factory) package_name = package_path + '/' + asset_name + '.' + asset_name + "_C" bp_gc = unreal.load_object(None, package_name) bp_cdo = unreal.get_default_object(bp_gc) bp_cdo.set_editor_property("replicates", True) unreal.EditorAssetLibrary.save_loaded_asset(my_new_asset)
Python Script import unreal DataTable のインポート def import_data_table_as_json(filename): task = unreal.AssetImportTask() task.filename = filename task.destination_path = "/Game/DataTables" task.replace_existing = True task.automated = True task.save = False ● ● ● 指定したパスの.jsonファイル からデータテーブルに変換 エディタからインポートする 場合、構造体の選択が必要 複数のデータテーブルをまと めてインポートするような ケースではループで回す task.factory = unreal.ReimportDataTableFactory() task.factory.automated_import_settings.import_row_struct = unreal.load_object(None, '/Game/DataTables/TestStruct.TestStruct') task.factory.automated_import_settings.import_type = unreal.CSVImportType.ECSV_DATA_TABLE unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks([task]) import_data_table_as_json("D:/scenes/python-scripts/import_data_table. json")
Python Script サブエントリを含むメニューを Level Editor Toolbar に追加 ● ● ● Pyhton からエディタのメ ニューを追加 Project Settings からエディ タ起動時に実行 チェックボックスなどのUIも 独自に作成可能 コードは次のページで
import unreal menu_owner = "ExampleOwnerName" tool_menus = unreal.ToolMenus.get() owning_menu_name = "LevelEditor.LevelEditorToolBar.PlayToolBar" @unreal.uclass() class example_ToolbarButton(unreal.ToolMenuEntryScript): def init_as_toolbar_button(self): self.data.menu = owning_menu_name self.data.advanced.entry_type = unreal.MultiBlockType.TOOL_BAR_COMBO_BUTTON self.data.icon = unreal.ScriptSlateIcon("EditorStyle", "MaterialEditor.CameraHome") #This below is required to show text properly on this specific toolbar in UE5 self.data.advanced.style_name_override = "CalloutToolbar" @unreal.uclass() class entry_ToggleButton(unreal.ToolMenuEntryScript): is_checked = unreal.uproperty(bool) def init(self, something_we_want_passed_in): print("Hey look we inited with something we passed in: " + str(something_we_want_passed_in)) @unreal.ufunction(override=True) def execute(self, context): self.is_checked = not self.is_checked print("Check: " +str(self.is_checked)) @unreal.ufunction(override=True) def get_check_state(self, context): if self.is_checked: return unreal.CheckBoxState.CHECKED else: return unreal.CheckBoxState.UNCHECKED def Run(): if True: #Testing stuff tool_menus.unregister_owner_by_name(menu_owner) #For Testing: Allow iterating on this menu python file without restarting editor main_entry = example_ToolbarButton() main_entry.init_as_toolbar_button() main_entry.init_entry(menu_owner, owning_menu_name, "", "exampleToolbarEntry", "Example Menu", "Open Foundation Browser") # Create menu that goes with the combo button above sub_menu = tool_menus.register_menu(owning_menu_name + ".exampleToolbarEntry", "", unreal.MultiBoxType.MENU, False) sub_entry = unreal.ToolMenuEntryExtensions.init_menu_entry( menu_owner, "ExampleSubMenuEntry", "Example Entry", "Example Entry Tooltip", unreal.ToolMenuStringCommandType.PYTHON, "", "print(\"Toolbar combo button's Item01 has been clicked\")") sub_menu.add_menu_entry("", sub_entry) sub_entry = entry_ToggleButton() sub_entry.init_entry(menu_owner, owning_menu_name + ".exampleToolbarEntry", "", "ExampleToggleButton", "Example of Toggle", "Example Toggle Tooltip") sub_entry.data.advanced.user_interface_action_type = unreal.UserInterfaceActionType.TOGGLE_BUTTON sub_entry.init("This is something passed in for init") sub_menu.add_menu_entry_object(sub_entry) toolbar = tool_menus.extend_menu(owning_menu_name) toolbar.add_menu_entry_object(main_entry) tool_menus.refresh_all_widgets() Run()
CPU最適化のためのアイデアを事前に EditorUtility や Python でチェック ● CollisionTestは高コスト 可能な場合はコンポーネントの”ColisionEnabled”を常に”NoCollision”に設定, これによりスポーンのコストも軽減 ● Collisionを有効にした状態でコンポーネントを移動させない 例:回転するコインの場合、Collisionは静止してCollision無効のメッシュを回転, もしくはマテリアルエフェクトを使用 ● コンポーネントの “bGenerateOverlapEvent” をオフにする Componentとの Overlap イベントが本当に必要な場合にのみ有効にする ● 可能な場合は”AsyncTrace”を使用する 次のフレームで結果が得られますが、ワーカースレッドで実行される (PhysicsMaterialの足音など) ● 実行するSweep/Laycast/Overlapの数を減らす 特にSweepとOverlapはLaycastよりもコストが高い ● フレームごとに行う必要がありますか? 重要性に基づいたものにする必要がありますか? ● コンポーネントの数を最小限に抑える アクターのスポーン時間はコンポーネントの作成が支配的 C++ で追加されたコンポーネントは、BP で追加されたコンポーネントよりも安価に生成される コンポーネントが少ないほど移動時のコスト低下 ● Partitcle、Audioコンポーネントで”bAutoManageAttachment”オプションを活用 コンポーネントがアクティブな場合にのみ移動 ● 可能であれば、プールされたパーティクル、またはワンショット(コンポーネントのない) サウンドを使用 カメラからの距離、画面上のサイズ、または可視性を使用してクライアント効果をカルリングします (例: WasRecentlyRendered) ● 複数のオーディオ コンポーネントを 1 つに置き換え ”bCanPlayMultipleInstances”を有効にして複数音源を再生 ● 実際にアクタをスポーンする必要があるかどうかを検討
● ブループリンとの BeginPlay のロジックに注意 マテリアルパラメータのコピーにはコストがかかる、AddToWorld 時に負荷が集中しがち コンポーネントを登録する前に構成しておくとコストが抑えることができる 大量にスポーンする場合はプーリングシステムの追加を検討 ● Tickを避ける 離れた場所ではティックを無効にする Significance Manager を使用して関連性がある状況に応じて制御する “dumpticks enable“コマンドでTickオブジェクトをチェック ● アニメーションを最小限で行う マテリアルエフェクトやパーティクルはより安価なオプション “メッシュ コンポーネント更新フラグ”を”レンダリング時にポーズのみチェックする”に設定する ● Significance Manager の使用 カメラに近づいた場合にのみ処理を行うことが重要 プラットフォームごとに設定可能 ● “Max Simulation Iterations”を使用してサブステップを無効にする ● 一般的な動作/アタッチメントの最適化 極力“NoCollision”または”QueryOnly”を使用する 可能な限り bAutoManageAttachment (FX/サウンド) を使用してください コンポーネント自身のバウンスを必要としない場合は ”bUseAttachParentBound=True” を使用 ● ブループリント Tickでの更新頻度を減らす、並行して実行できる場合は別のTickGroupに移動する ● Invalidation Widget を使用 “Slate.invalidationdebugging” を有効にして無効化する必要のないものを探す ● 不要なWidgetの作成を避ける プールされたウィジェットを使用、ロード画面の背後に作成して再表示/非表示を切り替える ● フォントのキャッシュ 新しいゲーム内フォントの追加を避ける
Commandlet Commandlet の活用 ● ● ● ● エディタ内だけでなくエディタ外から実行可能 UATを介して実行されるためスケジュールに組み込みやすい 拡張は簡単でプロジェクトで独自のコマンド追加も容易 C++での拡張が前提となるためスクリプトというよりはコード アイデア ● ● ● ● ● ● .fbx インポート アセットのクック DDCクリーンアップ アセットレジストリのダンプ IOStoreのコンテナ作成 アニメーションの圧縮 ● ● ● すべてのTextureのリスト アセット検証 スモークテスト実行
開発ワークフローの自動化 ワークフローへの活用 可用性 利便性 保守性 拡張性 自動化適用 Editor Utility Python Scripting Commandlet ○ ○ ○ Blueprint Python C++ ◎ ○ △ UIカスタマイズ可 UIはないが早い UIはない/要ビルド Blueprintベースで 保守しやすい デバッグが必要だが ファイル管理が容易 デバッグが必要だが ファイル管理が容易 ○ × ○ Blueprintで拡張可 特になし 独自のコマンド作成可 ○ ○ ◎ エディタのみ エディタのみ エディタ/エディタ外
開発ワークフローの自動化 Unreal Automation Tool の活用 ● 特定のファイルの解凍/圧縮 ● RunUAT.bat を使用して実行することも可能 Engine\Build\BatchFiles\RunUAT.bat ZipUtils -archive=D:/Content.zip -add=D:/UE/Pojects/SampleGame/Content/ Engine\Build\BatchFiles\RunUAT.bat ZipUtils -archive=D:/Content.zip -extract=D:/UE/Pojects/SampleGame/Content/ Engine\Build\BatchFiles\RunUAT.bat ZipUtils -archive=D:/Content.zip -extract=D:/UE/Pojects/SampleGame/Content/ -compression=9
開発ワークフローの自動化 Unreal Build Tool の活用 ● 静的コード解析 ● 夜間でビルドを回して静的コード解析まで実施 ● エラーが出たら夜のうちに通知→朝来たらすぐに修正 ● PVS-Studio、MSVC、Clang 静的分析 Engine\Build\BatchFiles\RunUBT.bat UnrealEditor Win64 Development -StaticAnalyzer=Default 静的コード解析 https://docs.unrealengine.com/5.3/ja/static-code-analysis-in-unreal-engine/
Agenda ● エンジンの自動化機能 ● 開発ワークフローの自動化 ● 最適化の自動化
最適化の自動化 最適化のためのテスト ● エディタテスト ● ● ● ランタイムテスト ● ● ● ● まずはエディタで確認できる範囲で試す プラットフォーム依存しない機能が動作できること 実機で確認してみないと分からない機能や見た目の問題 実機のみで発生する問題がないかを探す 想定通りに動いているかを確認 パフォーマンステスト ● ● コンテンツが出荷に耐えられる性能か クオリティが担保されているかを確認
エディタテスト エディタテスト ● ● ● まずはエディタで確認できる範囲で試す プラットフォーム依存しない機能が動作できること アセットの妥当性(サイズ、構成、設定)
エディタテスト Editor Tests:Editor Utility ● ● ● Editor Test プラグインが有効化 Editor Utility Test を親クラスとしてBlueprintを作成 テストに自動的に登録される
エディタテスト Editor Utility でのテスト例 ● ● 特にこれといって Editor Utility Test を実施するメリットはあまりない Script のリグレッションテスト
エディタテスト Editor Tests:Python ● Python をテストに登録するには以下の設定が必要 ● ● ● ● スクリプト は “/Content/Python/” フォルダに配置 スクリプト名 は “test_*.py” の形式 Script のリグレッションテスト 複数テストの実行
エディタテスト import unreal 特定のレベルで全カメラからス クリーンショットを取るテスト @unreal.AutomationScheduler.add_latent_command def setup_level(): unreal.EditorLevelLibrary.load_level("/Game/mymap") ● ● ● 各シーンで見た目の調整用 レベルロード後に全てのカ メラを取得して、スクリー ンショット取得して終了し たらテスト完了 スクリーンショット比較 ツールで取得した画像を比 較可能 @unreal.AutomationScheduler.add_latent_command def take_all_cam_screenshots(): level_actors = unreal.EditorLevelLibrary.get_all_level_actors() all_cameras = unreal.EditorFilterLibrary.by_class( level_actors, unreal.CameraActor ) for cam in all_cameras: camera_name = cam.get_actor_label() task = unreal.AutomationLibrary.take_high_res_screenshot(1280, 720, camera_name, camera=cam,) if not task.is_valid_task(): continue print ('Requested screenshot for '+ camera_name ) while not task.is_task_done(): yield
ランタイムテスト ランタイムテスト ● ● ● ● ● ゲームプレイの検証、ユーザー入力の確認 実機で確認してみないと分からない機能や見た目の問題 実機のみで発生する問題がないかを探す確認 仕様/想定通りに動いているかを確認 自動テストでは Gauntlet Framework の利用がおすすめ
ランタイムテスト ランタイムテストの例 ● Boot Test アプリケーションが起動したらすぐに終了する ● Smoke Test 基本的な機能を確認するために設計された簡単なスモーク テスト ● LLM Heatmap Test テスト実行中にさまざまな場所でLLMの情報をキャプチャするテスト ● PGO Test さまざまな場所でパフォーマンスデータを生成/取得するテスト 全て Gauntlet Frameworkを利用してテストすることが可能
ランタイムテスト:サンプル CitySample Test ● CitySampleTest.AutoTest 独自のレポート、ビデオキャプチャ、コンフィグ解析して自動化されたプレイスルーテスト実行 ● CitySampleTest.PerformanceReport FPSCharts/CSVProfiling 有効で AutoTest 実行 ● CitySampleTest.MemoryReport MemReport を有効にして AutoTest を実行 ● CitySampleTest.PGO PGO用コンフィグ設定を行い AutoTest を実行 LyraStarterGame Test ● LyraTest.BootTest 起動のみ実施するシンプルなテスト実行 ● LyraTest.LyraTestConfig テスト用コンフィグを設定してテスト実行
パフォーマンステスト パフォーマンステスト ● ● ● コンテンツが出荷に耐えられる性能か クオリティが担保されているか 最終的なスケーラビリティの設定を調整
パフォーマンステスト パフォーマンステストの例 ● 一般的なゲームプレイでのテスト ゲームプレイ時にヒッチが発生してゲームプレイに支障がないことを確認するテスト ● ロード時間計測テスト ゲーム起動時、パーシスタントレベル切り替え時など、大量のアセットロードを検証するテスト ● レベルストリーミングテスト レベルストリーミング時のヒッチやパフォーマンスを計測するテスト ● 負荷テスト ゲームプレイ上の最大数を表示/出力した時のパフォーマンスを検証するテスト ● GCテスト オブジェクトの破棄や生成、定周期実行のGCでパフォーマンスに支障がないことを確認するテスト
パフォーマンステスト ① 定期実行 ● ● ● ビルド・パッケージング 自動テスト実行 レポート作成・配信 ② デプロイ テスト テストデバイス ビルドマシン ③ レポート 配信 ユーザー 毎日実施してパフォーマンスの経過を観察
パフォーマンステスト パフォーマンステストに用いるビルド ● パフォーマンステスト用 一般的なテスト用、動的解像度を有効、出荷時のパフォーマンスに近い ● GPUパフォーマンステスト用 GPU計測用に動的解像度を無効にした設定でパフォーマンスを計測 ● LLMテスト用 LLMプロファイラーを有効化、主にメモリ計測用でパフォーマンスは無視 ● Insights テスト用 Insights キャプチャを有効化、パフォーマンスレポートから更に深掘り テキストファイルを使用してコマンドラインを指定 -CmdLineFile="D:\Users\MyName\Desktop\TestCmdLine.txt"
パフォーマンステスト パフォーマンスレポート [UE4] PerfReportToolを用いたパフォーマンスレポート作成 https://qiita.com/EGJ-Ken_Kuwano/items/d43f305da17c8f63a10c ● ● 軽量でパフォーマンス計測向き CIシナリオに組み込みやすい
パフォーマンスレポート
パフォーマンステスト MVP:欠落したVsyncの割合。テストで目標フレームレートをどのくらいの頻度で逃すかを示す、最 も重要な統計カテゴリの1つ。値が大きいほどゲーム体験が悪くなり、MVP5.0以上は要改善の目安。 Hitches/Min:テスト中に発生した1分あたりのヒッチの数。 MemFreeMB Min:任意の時点で記録された利用可能な物理メモリの最小量。 MemusedMB Max :デバイス上で消費された物理メモリの最大量。 GameThreadtime、RenderThreadtime、RHIThreadTime、GPUtime の平均:特定のスレッドまたは GPU に費やされた時間をms単位で示す。範囲外である場合 (例:60 FPS=16.67ms)、問題箇所を絞り込 むのに役立つ。 DynRes % Avg:コンソールのみ。RTがフレームレートを維持するのが困難な場合は、安定したフレー ムレートを維持するために出力解像度を動的に下げる。75%以下の場合は比較的高負荷の状況。 PlayerTick Avg:同時にTickするプレーヤー数は、パフォーマンスに劇的な影響を与える可能性があ る。FPS または MVP が予想よりも低い理由についてのコンテキストを提供するために平均を示す。
パフォーマンステスト パフォーマンスレポートについては、\Engine\Binaries\DotNET\CsvTools\ に ある、ReportTypes.xml、ReportGraphs.xml で閾値の変更が可能
パフォーマンスレポート
パフォーマンステスト パフォーマンスの目安例 パフォーマンス Good Min < 5% < 15 % HTP (Hitch Time Percent) ヒッチ割合 < 0.5 % < 1.0 % Avg Dynamic Resolution 動的解像度 > 90 % > 75 % > 300 MB > 200 MB MVP (Missed Vsync Percent) トレース期間中の Vsync 欠落率 Memory 使用メモリ 予めパフォーマンスにおいても目標値を決める パフォーマンスレポートや各種コマンドで情報を自動収集
パフォーマンステスト 自動検出:Memory gc.LowMemory.MemoryThresholdMB (default:0.0f) 低メモリGCモードのメモリ閾値(MB)。安定性を優先するため、この値を下回るとGCを発生させてメモ リを確保しようとする。 gc.LowMemory.TimeBetweenPurgingPendingKillObjects (default:30.0f) 低メモリ状態となったときに、Killを保留しているオブジェクトへのオブジェクト参照をパージするま での時間(ゲーム時間)。 memory.MemoryPressureCriticalThresholdMB (default:0) 利用可能な物理メモリがこの閾値を下回ると、メモリはこれを危険水域と見なす。この値を利用してメ モリに対するアプローチを実施することも可能。
パフォーマンステスト
メモリの危険水域チェック
●
メモリ使用量が.iniファイル
で定義した危険水域まで到達
することを検出するサンプル
●
このケースでは危険水域に到
達したらログを出力
●
危険水域に超えることが無い
ような対策を入れておくか、
到達時に何か処理させるか
// 危険水域チェック
static IConsoleVariable* CVarMemThreshold =
IConsoleManager::Get().FindConsoleVariable(TEXT("memory.MemoryPressure
CriticalThresholdMB"));
const float ThresholdMB = CVarMemThreshold ?
CVarMemThreshold->GetFloat() : 0.0f;
float MBFree =
float(PlatformMemoryHelpers::GetFrameMemoryStats().AvailablePhysical /
1024 / 1024);
#if !UE_BUILD_SHIPPING
MBFree -=
float(FPlatformMemory::GetExtraDevelopmentMemorySize() / 1024 / 1024);
#endif
if( MBFree < ThresholdMB )
{
UE_LOG(LogTemp, Warning, TEXT(“ Over memory pressure critical
threshold : Current=%f.2, Threshold=%f.2” ),MBFree, ThresholdMB);
}
Engine.ini ファイルへの定義
[ConsoleVariables]
memory.MemoryPressureCriticalThresholdMB=50
パフォーマンステスト 自動検出:Level Streaming LevelStreaming.Profiling.Enabled (LevelStreaming.Profiling.Enabled.Shipping) レベルストリーミングのプロファイル有効化 LevelStreaming.Profiling.StartAutomatically プロファイル有効時からすぐにキャプチャを開始
パフォーマンステスト レベルストリーミングが発生した時に、 ロード時間やAddToWorldに掛かった時間等を計測して自動的に出力
パフォーマンステスト Unreal Insights ● ● 開始時点からトレースしたい場合は通常通り -trace=[Channel] 途中からトレース(遅延接続)時は Trace.File/Trace.Stop を利用 ● ● ● ● ● ● Memory Insights は遅延トレース不可 トレースシーンのスクリーンショット -trace=Screenshot CPU (Main) 計測時 -trace=cpu CPU (全般) 計測時 -trace=cpu,task コンソールCPU計測 -trace=cpu,task,contextswitch ロード時間計測 -trace=cpu,loadtime,file ※ WinのContextSwitchトレースは管理者として実行が必要
まとめ
まとめ ● エンジンには沢山の自動化機能がある ● 自動化を利用して開発を効率化 ● ● ● ● アセット量産とチェック ● Blueprint、マップ生成、データテーブル 特に時間のかかるフロー ● クック、デプロイ、パッケージング 時間が取れない箇所も自動化でカバー ● 最適化、エラー検出、自動テスト 一度作成したテスト、ツール、アセットはプラグイン化してPJで流用
Thank you! 2023 Private & Confidential