Graph Map Generator 紹介記事
Graph Map Generator 紹介記事
1. 前言
在Unity中制作非开放世界类的JRPG风格游戏时,您是否曾为如何设计广场和通道的地形而感到困扰?
由广场和蜿蜒通道构成的地图。
您是否曾因在Unity中手动创建此类地图,并疲于使NavMesh、Terrain(地形)和用户自定义地图保持完美同步而苦恼?
我也曾在 Unity 3D 中为制作由广场和通道构成的地图而苦恼。
为了高效且不出错地制作“可行走区域清晰明确、其外侧有背景延展的地图”,我自己开发了 Graph Map Generator。
虽然最初是为我自己使用而开发的,但既然已能在Unity Asset Store上发布,在此进行介绍。
术语定义
本文中会出现多个术语,为避免混淆,定义如下。
| 定義 | 意味 |
|---|---|
| 广场:Plaza | 可移动领域中具有一定广度的空间 |
| 通路:Corridor | 连接广场与广场之物 |
| 地形:Landmass | 通过通道连接的两个广场 |
| 地形 | 作为外观的地形 |
| 导航网格 | 作为可移动区域的地面 |
| 用户地图 | 用于向玩家显示的地图 |
此外,该库名称中的 Graph 并非通常所说的图表(Chart),而是指图论中的有向图。
简而言之如下。
| 定義 | 意味 |
|---|---|
| 节点 | 空间中的点 |
| 边 | 连接各个节点的元素 |
| 图 | 节点与边的集合 |
在本库中,只需定义一个作为广场和通道的 Landmass,即可通过从同一骨架烘焙出 NavMesh、Terrain 和 UserMap 来生成的 Unity 包。
本文除了介绍功能外,还将说明为何以 Graph 为核心,以及为何不采用独立实现而是选择烘焙到 Unity 标准机制中。
2. 该机制的目标
出发点是为了在自己的游戏中创建一个步行区域清晰明确,其外侧背景广阔的地图。
就像 JRPG 中的野外地图一样,由蜿蜒的通道连接起来的广场组成的地图。
然而,在实际开始制作时,我们遇到了以下三个障碍。
-
制限の壁
- 在开放世界风格的制作中,很难自然地实现“此处无法通行”的效果。”
-
NavMesh の壁
- 如果从地形生成导航网格(NavMesh),则难以按预期确定可行走范围。”
-
整合の壁
- 如果分别制作导航网格(NavMesh)、地形(Terrain)和用户地图(UserMap),它们之间会出现错位。”
- 最重要的是,不想在地图制作上花费过多精力。”
起初,我们曾寻找地形相关的资产,但由于开放世界风格与可移动地面的兼容性较差,且从世界观统一的角度考虑,最终决定不予采用。
因此,我们制定了以下要求并开始将其库化。
-
直感的な定義
- 在空间中放置广场并仅连接道路的简单定义
-
歩ける範囲が明確
- 所定义的地形直接成为 NavMesh
-
地図がある
- 存在用于显示所定义地形的 UserMap
-
地形がつながる
- 存在与所定义地形自然相连的 Terrain
- 存在与地形相匹配的自然植被
Unity 的标准工具中没有从同一骨骼数据中一体生成这三者的机制。
Graph Map Generator 的存在意义正是为了满足这一需求。
3. 前提知识与权衡的整理
在将其库化的过程中,我定义了以下强有力的前提条件。
那就是遵循“搭乘现有生态系统”这一大原则。
该库不处理自定义的地形或自定义的移动方式。
它使用现有的计算类库,并使用现有的 Terrain 和 NavMesh。
即使我不再维护此库,已写入的 Terrain 或 NavMesh 也不会受到影响。
4. 整体构成(三大支柱)
该库最初仅打算创建 NavMesh。
然而,地形难以自然生成,让植被自然地覆盖在地形上也颇为棘手。
MiniMap 也让人费了一番功夫。
因此,我们以地形为核心,从那里开始构建所需的功能并进行了扩展。
使用该库时,请按以下步骤操作。
-
地形を作る
- 从广场和通道定义地形
-
Adapter を付与してBake
- 为 Terrain 等附加 Adapter
- 从地形计算形状,并将结果写入输出文件
- 「Bake All」でまとめて実行も可能
-
Unity 標準データ化
- 実行時の処理は、標準の仕組みが担います
成果物は同じ形から作るので、互いにずれません。
具体例
Graph で作成された Landmass
Landmass と NavMesh
Landmass と Terrain
5. 実装・設計の深掘り
設計の核は、独自のランタイムを持たず、Unity 標準のデータへ Bake することです。
なぜ独自実装ではなく Bake なのか
経路探索や地形描画を自作すると、開発だけでなく保守のコストも抱えます。
さらに、既存のエコシステムも流用できなくなります。
そこで、成果物を標準の型に揃えました。
| 成果物 | Adapter | Bake 先 | 可直接使用的功能 |
|---|---|---|---|
| NavMesh | MapNavMeshAdapter |
NavMeshSurface 的 NavMeshData
|
标准路径搜索与 NavMeshSurface 的智能体体素设置 |
| 地形 | MapTerrainAdapter |
Terrain 的 TerrainData(高度、纹理、草地、树木) |
标准地形绘制与用户选择的素材 |
| MiniMap | MapUserMapAdapter |
MapUserMap 的 MapUserMapData
|
uGUI(表示は MapUserMapView) |
MiniMap には対応する Unity の組み込みの型が無いため、実体の MapUserMap だけはパッケージが定義しています。
ただし、Adapter が骨格から実体へ Bake する作りは、Terrain や NavMesh と同じです。
自作するのは、標準に無い「Graph から形を作る部分」だけです。
広場と通路の接続には smooth-min(滑らかな最小値関数) を用いた距離場(SDF)の合成を行い、それを LibTessDotNet による高品質な三角形分割と Marching Squares によってメッシュ化しています。
これにより、手作業では面倒な「通路と広場の滑らかな接続」を数学的に一貫して行いつつ、最終出力は完全に Unity 標準のフォーマットに落とし込んでいます。
既存の計算アルゴリズムを活かし、最終的な出力には Unity 標準の Terrain と NavMesh をそのまま採用しています。
NavMesh の Bake は、この考え方がいちばんよく表れています。
歩ける範囲の Mesh を唯一の材料として、標準の NavMeshBuilder に渡しています。
Terrain の高低差は NavMesh の判断条件になりません。
そのため、地形の見た目を調整しても、歩ける範囲は変わりません。
为什么将骨骼结构设为 Graph
Graph 可以用最少的参数表达地图的含义。
相同的 Landmass 广场和通道通过 smooth-min 合并为一个距离场。
由此可以一致地生成自然的广场与道路。
実装例
NavMesh Adapter
Terrain Adapter
MiniMap Adapter
场景导出适配器
6. 与 AI 的角色分工
软件包中随附了面向 AI 代理的 AGENT.md 和 Skill。
如果要制作大量地图,手动放置并不现实。
为了让 AI 能够主导生成地图并进行验证,我们附带了地形生成的 SKILL。
| 担当 | 役割 |
|---|---|
| AI(技能) | 听取意见,并将用户的话语转化为参数变更 |
| 系统(Adapter) | 从骨架准确烘焙成果物,并将其作为资产保留下来 |
| 人間 | 查看地图,做出最终判断 |
(対話のイメージ)
利用者:村と湖があって、洞窟の入口まで歩けるマップを作って。
AI :骨格を置いて NavMesh・Terrain・UserMap を Bake しました。
通路の幅、広場の大きさ、木の密度を調整できます。
利用者:洞窟への道をもう少し広くして。
AI :該当する通路の BaseWidth を広げて、Bake し直しました。
7. 总结
Graph Map Generator 的本质并非自动创建地形。
将地图的意义汇总为单一的 Graph,并将实际处理交由 Unity 的标准机制来完成。
-
使えるものは使う
- 无论是 NavMesh 还是 Terrain,该库都会烘焙为标准 Asset
-
無いものだけ作る
- 需要自行制作的部分是:从 Graph 构建形状的部分,以及没有接收容器的 UserMap。
-
単一のデータ
- 可以基于充分的理由说明这三个成果物均源自相同的骨架。
从小处着手即可。
只需用道路连接两个广场,然后点击「Bake All」,就能生成一个可供行走且带有地图的界面。
在此基础上逐步添加广场、湖泊和洞穴,从小规模开始,逐渐扩展完善。
使用本库可以从 Graph 生成 JRPG 所需的资产。
如果您希望摆脱 JRPG 风格地图同步带来的混乱局面,请务必查看以下内容。
https://assetstore.unity.com/packages/tools/graph-map-generator-791591
来源:Qiita · Unity 开发社区 · qiita.com







