scenario-unity-world-building について
Unity のレベル・環境アーティスト向けのワールド構築スキルです。地形、グレーボックス、ナビゲーション、誘導、ストリーミング、プロファイリングを扱い、キャラクター寸法や経路、キャプチャ、Player テストで検証します。
主な機能
- 01プロシージャル地形の構築と監査
- 02キャラクターとカメラの寸法でグレーボックスを作成
- 03NavMesh とレベルの接続性を確認
- 04ランドマーク、経路、海岸のコンテンツを配置
- 05シーンストリーミングをテスト
- 06視点ごとの予算をプロファイリング
活用シーン
- 01道路や植生を含む地形の生成
- 02各エリアへのキャラクターの到達性確認
- 03ランドマーク誘導とワールド端のコンテンツ確認
- 04Player でシーン読み込みとフレーム予算を測定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-unity-world-buildingインストール後、Claude Code で/scenario-unity-world-buildingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/critique.mdexpert-notes.mdgui-paths.mdprocedures.mdsources.mdscripts/ut_world.pyscripts/AgentKit/World/WorldBlockout.csWorldCommon.csWorldGuidance.csWorldGym.csWorldKit.csWorldNav.csWorldScenes.csWorldStreaming.csWorldTerrain.csscripts/Runtime/World/AgentKit.World.Runtime.asmdefProfileTour.csStreamProbe.csWfc.csWorldGuide.csWorldNoise.csWorldStreamer.cs詳細
Unity ワールド構築(レベルおよび環境アーティスト)
熟練したワールド構築では、まず構造を作り、次に再生成可能なコンテンツを生成し、その後に検証します。つまり、キャラクターがあらゆる空間に収まり、カメラがあらゆる出入口を通り抜けられ、プレイヤーがすべての空間に到達して戻ってこられ、ワールドの端にコンテンツが保たれ、最悪の視点でも Player のフレーム予算を守れることを確認します。マウスを使わないエージェントは、TerrainData、ProBuilder API、PrefabUtility、シーン API を通じてこれらすべてを行い、その後、レイキャスト、NavMesh パス、キャプチャ、プロファイリングツアー、Player プローブで確認します。対象:Unity 6000.3.21f1、URP 17.3、ProBuilder 6.1.2、Splines 2.9.0、AI Navigation 2.0.14。ここに記載された関連スキルが利用可能なスキルにない場合は、ユーザーにインストールを依頼してください(npx skills add scenario-labs/skills --skill <name>)。無人で実行する場合は、ツールスキーマに基づいて進め、不足しているスキルを明記してください。
必須の背景知識: scenario-unity-expert(チャネル、レビューの反復、6.3 の落とし穴)。そのツールキットをインポートしてください。このスキルでは、scripts/ut_world.py、scripts/AgentKit/World/ 内の C# ジョブ、scripts/Runtime/World/ 内のランタイムアセンブリを追加します。
ステータス(2026-09-24、ブラインド評価のリファクタリング後): references/procedures.md で [未実行] と記された計画を除くすべての手順を、この Mac 上の Unity 6000.3.21f1 で実行しました。
tests/code/unity-world-building/test_live_world.py(ライブテスト 13 件)、test_live_world_v2.py(ライブテスト 12 件)、test_offline.py(7 件)。
姿勢(専門家ならではの知見)
- 内容を作り始める前に、構造を固定します。 地形のサイズと、彫刻を始める前にすべてのテクスチャ解像度を決めます(後から変更すると再スケーリングまたは再サンプリングされます。6.3 Terrain manual)。ブロックアウトの前に、キャラクターとそのカメラのメトリクスを確定し、コントローラーを変更するたびに作り直すジムで検証します(level design e-book、gym/zoo)。配置を始める前にキットのグリッドを決めます(Christina Creates Games、0o-QnNs-stc [00:07:35])。コードでは、スプラットを書き込む前に
TerrainDataアセットを永続化します。そうしないとアルファマップが失われます(実測)。 - 非破壊で作成し、決定論的に再生成します。 Albaは移動可能な地形要素、レベラー、道路をハイトマップにレンダリングし、プレイ前とCIで、順序付けされ、スキップ可能なステップを使ってワールドを再生成します。生成されたシーンは
git update-index --skip-worktreeを使ってチェックインされます(Manesh Mistry、YOtDVv5-0A4 [00:06:10]、[00:09:52]、[00:10:05])。フットプリントから再構築したPolyShapeは、それ以降の編集をすべて失います(ProBuilder manual。実測では面が12から7に減少)。編集済みメッシュではなく、生成レシピを保持します。 - 生のプロシージャル出力には、もう1段階の調整が必要です。 ノイズには侵食処理が必要です(Lague、eaXk97ujbPQ)。WFCには作成済みのタイルが必要です(DV Gen、20KHNA9jTsE [00:04:22])。道路には経路探索が必要です。傾斜を考慮したA*経路が切り開いたのは2.6 mで、直線のノットでは9.1 mの峡谷ができました(Alba [00:07:45]、実測)。
- まず汎用パーツ1つでブロックアウトし、その後まとめて置き換えます。すべてのパーツと複合パーツをプレハブ化します。 まず全体に壁を配置し、次に置き換えてドアと窓を追加します(Christina [00:15:14])。メトリクスの修正は、プレハブを1つ編集するだけで済みます(YsBniZ5ya7k [00:06:25])。スクリプトでは、置き換える前にインスタンスのオーバーライドを記録します。
RecordPrefabInstancePropertyModificationsなしではReplacePrefabAssetOfPrefabInstanceにより配置30件中0件が維持されましたが、指定すると30件すべてが維持されました(実測。グリッド監査では問題が見つからず、スロット監査と外周監査で検出)。 - グレーボックスの終了条件は機械的に判断します。 ドアはエージェントの半径とカメラのブームを基準にします。NavMeshは各フロア全体に配置し、ドアの開き戸はベイク対象から外し、部屋を分割しないように障害物を配置します。屋根はNot Walkableとしてマークし、上階はリンクで接続し、エリアごとにNavMesh Surfaceを1つ配置します(Christina [00:17:12]、[00:19:27]、YsBniZ5ya7k [00:15:24])。暗いエリアを確認するためにクイックベイクを行います。ランドマークと道を先に作り、標識は最後に配置します(Adam Robinson-Yu、ZW8gWgpptI8 [00:18:37])。
- プレイヤーはまず端を試します。はしごをかけるように導線を作ります。 島では、プレイヤーは泳いで外へ、そして島の周りへ向かいます。壁を作るのではなく、海岸のあらゆる区間にコンテンツと戻る道を用意します([00:16:54]、[00:17:58])。ランドマーク、パンくず、戻り道につながる経路、目標へ向かう上り坂を用意し、標識は最後に配置します。偽の頂上には存在する理由が必要です。ここでは、36方向の海岸のうち32方向で、150 m以内に何もありませんでした(実測)。
- 常駐するコアの周りで、収まりきらないものだけをストリーミングし、Playerで評価します。 Albaでは、LODと関連性システムを使い、島を常駐させていました([00:12:43])。コアがRenderSettings、ライトマップ、フォグを管理します。パスを使ってロードし、プレイ中に
allowSceneActivation = falseのままにしてはいけません(キューに入ったアンロードが1秒間停止しました。実測)。アンロード後にアセットを整理し、表示中のチャンクが外れている間は統合プロキシを表示します。backgroundLoadingPriorityとIntegrateマーカーが意味を持つのはビルド済みPlayerだけです(6.3 Scripting API。ここではEditorのカウンターは0を示しました)。 - 最悪の視点でプロファイルを取り、統計を比較し、デバイスの条件に合わせて修正します。 アンカー地点へテレポートして360度見回し、最悪の向きを維持します(Alba [00:29:46])。各側で約200フレームを比較します(Profile Analyzer、[00:17:00])。タイルベースのモバイルGPUでは、アルファテストのインポスターより、不透明なLODフォリッジのほうが優れています(32.5 ms中7.12 ms、[00:20:14])。Firewatchの距離ベースのアルファカットオフは、PCとコンソール向けの選択です(Jane Ng、ZYnS3kKTcGg [00:20:29])。LOD Groupの木は
Terrain.treeDistanceを無視します(60 mと700 mでフレーム数は同じでした。実測)。調整するのはLOD Groupです。
最初に決めること
プラットフォームと予算(デフォルトはデスクトップで 60 fps = 16.67 ms、モバイルで 30 fps:33.3 ms のフレーム時間の 65 % =
21.7 ms、scenario-unity-expert);最も性能の低いデバイスのメモリ(そもそもストリーミングするかを決定);ワールドのサイズと移動速度;キャラクター(半径、高さ、斜面の上限、段差、ジャンプ距離)とそのカメラ(ピボット、肩のオフセット、ブーム、ピッチ);アートスタイルとフォグの表現方針;コンテンツのソース(作成、プロシージャル、混合)と作成担当者;ユーザーのエディターがプロジェクトを保持するか(ut_env.project_lock)。デフォルト:URP、地形 1 km、ハイトマップ 1025、グレーボックスのグリッド 1 m、キットのグリッド 2.5 m、階高 3 m、カプセル 0.4 x 1.8 m、斜面 45、段差 0.3、ジャンプ 2.5 m [追加]。
ワークフロー
各ステージは 1 回の ut_world 呼び出しです。エンジンの呼び出し、引数、記録された結果については references/procedures.md を参照してください。
- 仕様。 メトリクス、解像度、グリッド、予算、アンカー、メモリ予算。ゲート:以降のすべてのチェックに数値があること。
- 地形。
build_island(解像度を先に設定、fBm、侵食、整地、A* 道路、ルールベースのスプラット、LOD ツリー、インスタンス化された詳細オブジェクト)、DCC のハイトマップにはraw_roundtrip、Toolbox で一括設定できないタイルごとの設定にはset_terrain_settingsを使用します。ゲート:2^n+1、パッチ 16、詳細オブジェクトのシードが重複しないこと、道路の勾配 <= 10 %、新しいエディターでのauditのエラーが 0 件。 - ジム、次にグレーボックス。
build_gym(P, metrics)(コントローラーを変更した後はgym_is_stale)、続いてbuild_village。ゲート:ドアのサイズが NavMesh の条件を満たし、そのカメラクリップ率が判明していること;すべての建物にPathCompleteで到達できること;すべての場所に UV2 があること;名前にサイズが含まれていること。 - キット。
build_kitの後にkit_nav_gateを実行します。ゲート:グリッド、階高、ヨー、スロット、外周の監査がすべて問題ないこと;ベイクでドアの開き戸が無視されること;屋根の孤立島がないこと;上階が接続されていること。 - 誘導。
setup_views(ブックマーク、アンカー、視線、スポーン)、audit_guidanceを実行し、最長の空白区間が条件を満たすまでfill_coastを実行します。ゲート:すべてのアンカーからランドマークが見えるか、メインパス上にあること;すべての POI から歩いて戻れること;スポーンのドット >= 0.7。 - 見た目。
captureでフォグをオフ(レイアウト)とオン(見た目)にして撮影し、詳細、LOD、カリングの距離でcapture_popsを実行します。すべてのシートを開き、references/critique.mdに従って評価します。ゲート:空白、黒、白、マゼンタのフレームがないこと;ポップのサイズが記録されていること。 - ストリーミング(必要な場合のみ)。 まず
scene_reportを実行し、次にsplit_streaming、build_proxies、streaming_tests、stream_probeを実行します。ゲート:PlayMode が 5/5 であること;Player Integrate マーカーが優先予算内であること;スイープ後にメモリがベースラインに戻ること。 - ツアー。
tour_profileを実行し、変更の前後でcompare_runsを実行します。ゲート:各アンカーでbudget_checkに合格すること;カウントはエディターで、ミリ秒はデバイスで判断します。
数値
| 値 | 比較対象 | 出典 |
|---|---|---|
| 2^n+1(513、1025、2049) | ハイトマップ。浸食には1025以上 | 6.3 Terrain manual |
| 16 | パッチあたりのディテール解像度(まばらな遠景の草地以外では増やさない) | 6.3 manual |
| 4 | 高さブレンドを使用するスプラットマップあたりの地形レイヤー数 | smnLYvF40s4 [00:04:23] |
| 2 / 4 / 10 / 50 ms | フレームあたりの統合予算。Low / BelowNormal / Normal / High、Player のみ | 6.3 Scripting API |
| 2.5 x 3 m、Y = 3 n | キットの壁、階高 | 0o-QnNs-stc [00:07:35] |
| 1.0 m | 0.4 m のカプセルに必要な最小幅のドア(0.8 では通過不可) | gym、実測 |
| 80 % / 27 % | 1.4 x 2.4 m / 2 x 3 m のドア越しに遮られるカメラブーム(3.5 m、20 度) | gym、実測 |
| 40 pass、45 fail | 傾斜制限45度でのランプの角度。NavMesh と CharacterController の判定が一致 | gym、実測 |
| 0.13 to 0.06 m | Build Height Mesh なし/ありでの階段上の NavMesh 高さ誤差 | gym、実測 |
| 0.5 to 1.13 of 2 ms | Low での Player Integrate のフレームあたり最大値(村のチャンク、ロードに34~371 ms) | stream_probe、実測 |
| 7.12 of 32.5 ms | インポスター foliage の GPU コスト、iPad Mini 4 | YOtDVv5-0A4 frame [00:19:53] |
| ~200 frames | 比較の前後それぞれのフレーム数 | YOtDVv5-0A4 [00:17:00] |
| 150 m、300 m | POI の半径、最長の無人沿岸区間(調整対象のデフォルト値) | [追加] |
品質ゲート
- 測定可能性: envelope
ok、コンパイルエラーゼロ。地形監査でエラー0件(デスクトップおよびmobile=True)。ブロックアウト、キットスロット、周辺部の監査に問題がないこと。キット NavMesh ゲート、ジムの表、 ガイダンスゲート、NUnit EditMode 8/8 と PlayMode 5/5、Player プローブの判定、各 アンカーのbudget_check、compare_runsの p 値。 - ビジュアル: フォグなし、フォグあり、ポップ、プロキシの各シートを開く。
ut_reviewのフラグがないこと。同じブックマークからの比較前後。ディテールが表現として機能していること。汎用の岩や木は形状のみ、物語性のあるプロップは詳細に、3つで足りるなら4つ目の岩は置かない(Firewatch、ZYnS3kKTcGg [00:24:27]、[00:25:50])。
よくある間違い
| 間違い | 実際に起こること | 修正 |
|---|---|---|
SetAlphamaps の後に CreateAsset(terrainData) | 新しいエディターで地形の全体が最初のレイヤーになる | 先にアセットを作成し、その後にレイヤーを設定します |
記録されていない移動の後に ReplacePrefabAssetOfPrefabInstance | 置き換えた壁が家の原点に積み重なり、穴ができます。グリッド監査では問題なし | 配置後に RecordPrefabInstancePropertyModifications を呼び出し、トランスフォームを復元してスロットを監査します |
| 1つのエリアに2つの NavMesh Surface がある | 古い Surface 上で壁を通り抜ける経路が「完全」と判定されます | エリアごとに Surface を1つにし、重複部分を再ベイクします |
| 閉じたドアがベイクに残っている | 部屋にたどり着けません | ドアに NavMeshModifier.ignoreFromBuild を設定します |
| エージェントの半径を考慮せずに小物を配置する | ドアを開けても部屋が分断され、フロアの25%しか到達できません(観測値) | ドア周辺を空け、フロアを分断するアイテムを却下し、フロア全体をサンプリングします |
| 屋根や上階をベイクに含める | 到達できない領域ができます | 屋根のエリアを Not Walkable に設定するか、階段または NavMeshLink を使用します |
| カプセルだけを基準にドアのサイズを決める | どの出入り口でもカメラが内側に引き込まれます | ジムでブームの長さを測定し、室内カメラを使います |
| PolyShape を再度編集する | 押し出しが消えます | フットプリントをロックし、レシピを再実行します |
LOD ツリーに treeDistance を調整する | まったく変化しません | LOD Group を調整し、カリングをキャプチャします |
| インスタンス化されたディテールに Healthy/Dry Color を設定する | 色が変化しません | シェーダーで色を変化させます |
| Bake Light Probes For Trees(デフォルトでオン)のみを設定する | 効果がありません | ツリーのレンダラーは Light Probes から GI を受け取ります |
| アクティベーションを保持してプリロードする | アンロード時にフリーズします | すぐにロードし、ローディング画面だけを条件付きで表示します |
| ストリーマーに Start スキャンがない | エディターで開いたチャンクが2回ロードされます(コピー数が1から2に増加、観測値) | Start でロード済みのシーンをスキャンします |
| エディターでストリーミングやメモリを判断する | カウンターが0になり、優先度も無視されます | 開発用 Player で stream_probe を使います |
マーカーに new ProfilerRecorder(handle) を使う | ずっと 0 ms のままです | ProfilerRecorderOptions.StartImmediately を追加する(または StartNew を使う)。一度もサンプリングされないマーカーはデータなしとして扱います |
FrameTimingManager でシステムごとの GPU ms を測定する | フレーム全体を示す「地形 2 ms」になります | システムを切り替えて差分を取るか、GPU キャプチャを行います |
| フォグ越しや上空からの正投影でレイアウトを判断する | 空撮画像が白っぽくなり、LOD によりツリーがカリングされます | フォグをオフにして空撮画像をキャプチャします |
引き継ぎ
- 受け取るもの:scenario-3d、scenario-textures、scenario-skyboxes、scenario-blender-expert からアセットを受け取ります。キャラクターコントローラーとカメラリグは scenario-unity-gameplay および scenario-unity-animation(Cinemachine)から、入力は scenario-unity-architecture から受け取ります。
- 引き渡すもの:scenario-unity-rendering-lighting へは、静的フラグと UV2 を設定したシーン、ライティングの所有者となるコア、コアとすべてのチャンクを含む 1 つの APV Baking Set、すべてのシーンを開いた状態でベイク済みのデータ(およびオクルージョン)[ここでは実行していません]、フォグのベースライン、タイルごとのプローブ設定を渡します。scenario-unity-shaders へは、フルスクリーンパス仕様としての Firewatch グラデーションストリップフォグ、ディテールシェーダーでの草の色のバリエーションを渡します。scenario-unity-performance へは、ツアーの CSV と JSON、
compare_runs、Player プローブ、LOD に関する調査結果、チャンクのプロップにおける GPU Resident Drawer 候補(Forward+、SRP Batcher、Mesh Renderer のみ、第 5 節の差分)を渡します。scenario-unity-mobile へは、audit(mobile=True)とストリーミングの優先順位を渡します。scenario-unity-gameplay へは、NavMesh サーフェス、リンク、ジムのテーブル、スポーンポイントを渡します。scenario-unity-pipeline-automation へは、Addressable のシーン、ビルドリスト、AssetPostprocessors としてのインポートルールを渡します。 - パケット:プロジェクト、チャネル、シーン、数値を含むゲート、すべてのシート、未解決の課題。
Unity 6.3 に関するメモ
- Polybrush は非推奨であり、Terrain では動作しません。レイキャストで散布してください。ProBuilder 6.1.2:ウィンドウはありません(Scene ビューのツールコンテキストを使用)。
PivotLocation.FirstVertex(ドキュメントでの名称は「First Corner」)を使用します。デフォルトのマテリアルは頂点カラーの Shader Graph です。 - Terrain Tools 5.3.2 が同梱されています。Splines 2.9.0、AI Navigation 2.0.14(NavMesh Surface、Modifier、Link、Build Height Mesh)を使用します。Build Profiles は
EditorBuildSettings.scenesを共有します。Memory Profiler 1.1.12 と Profile Analyzer 1.4.0 はパッケージです。 FindObjectsByTypeにはソートモードが必要です(6.4 では非推奨)。6.6 では、新規プロジェクトはドメインリロードなしで Play モードに入ります。
参考資料
references/procedures.md:完全な呼び出し、実環境でのテストパス、記録済みの結果を含む 24 の手順。references/expert-notes.md:専門家による原則と判断、および出典とタイムスタンプ。references/critique.md:地形、ジム、ブロックアウト、キット、ガイダンス、雰囲気、ストリーミング、パフォーマンスの評価基準。references/gui-paths.md:Terrain Toolbar、ProBuilder のツールコンテキスト、Splines、NavMesh、複数シーン、プロファイリングウィンドウ。references/sources.md:認証情報、URL、最適なタイムスタンプ、改訂履歴を含むすべての出典。