> For the complete documentation index, see [llms.txt](https://docs.allout.game/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.allout.game/all-out-docs/docs-zh/shi-yong-bian-ji-qi/tilemap.md).

# 瓦片地图

瓦片地图系统让你使用自动贴图蒙版、多层以及带内置碰撞生成的墙体挤出，绘制基于瓦片的世界。

## 添加瓦片地图

添加一个 `Tilemap_Component` 到任意实体上。瓦片地图以实体的位置为中心，跨越一个由区块组成的网格（每个区块 32×32 个瓦片）。瓦片总尺寸为 `width_in_chunks × 32` 乘以 `height_in_chunks × 32`.

## 瓦片地图属性

| 属性            | 说明                                                    |
| ------------- | ----------------------------------------------------- |
| **区块宽度 / 高度** | 瓦片网格的大小。每个区块为 32×32 个瓦片。一个 10×10 的瓦片地图就是 320×320 个瓦片。 |

进入编辑模式后，各图层会分别配置（见下文）。

新的地面图层具有透明轮廓。新的墙体图层具有不透明黑色主体和顶部轮廓，并且没有顶部纹理，因此主体纹理会填充顶行。两个蒙版默认都是 `$AO/tile_mask.png`。地面或墙体主体填充纹理需分别选择。这些创建默认值适用于编辑器、MCP、CSL 和 C#；加载现有图层会保留其已保存的设置。

对于黑色墙顶，如果项目中不存在 1×1 的不透明黑色 PNG，请将其添加为 `res/ao_black.png` ，然后将其设为每个墙体图层的顶部纹理。引擎不再随附 `$AO/black.png`：使用它保存的图层加载时不会有顶部纹理，脚本应改为加载 `ao_black.png` 。

更改图层种类会切换默认的地面/主体轮廓以匹配新种类。自定义轮廓颜色会被保留。

对于建筑物，请在同一个瓦片地图上使用地面和墙体图层。地板应延伸到每个墙体瓦片下方以及内部；只停在内侧墙边会留下缝隙。门洞会移除墙体瓦片，同时保留地板。

## MCP 编写

代理必须将瓦片大小保持为默认值 1，包括运行时代码中，并将结构实体保持为单位缩放。瓦片大小不是 MCP 选项。请通过瓦片数量更改占地面积，并通过纹理缩放更改材质图案。

* `tilemap_inspect` 读取图层设置、占用边界、分页后的水平占用区段，以及瓦片/世界坐标转换。
* `asset_prepare_tileable` 通过资源裁剪设置去除下载的填充纹理的透明边框填充并启用重复。它会保留现有裁剪和不透明美术；请检查 `opaqueEdges` 以查看剩余的边缘透明度。 `apply:false` 预览裁剪。提供 `crop` ，以便在已知还需要去除羽化边框时替换当前内边距。裁剪使用 `[left,bottom,right,top]` 源像素内边距，并会影响资源的所有用法，而不会改变源图像。
* `tilemap_configure` 会调整网格大小，并添加、修补、移除或清空图层。新图层需要填充纹理；提供 `textures` 会替换整个列表。项目填充纹理会被准备为可重复，但不会自动裁剪。蒙版保持不变。
* `tilemap_paint` 可设置或擦除矩形、连通的画笔笔触以及明确指定的单元格。
* `tilemap_stamp` 通过显式图层映射复制占用状态，并且可跨地图操作。旋转在 Y 向上的网格中按逆时针进行。合并会保留源孔洞下方的目标单元格；替换会清空它们。

使用 `modify_scene` 来创建实体，并使用 `Tilemap_Component`。工具通过 AOID 或名称定位实体，必要时使用 `componentId` 。瓦片坐标和图层索引都从 0 开始；瓦片矩形端点是包含式的，而世界矩形覆盖其中心位于 \[min,max) 内的单元格。放置对象在瓦片中心时请使用 `tilemap_inspect`的 `worldCenter` ：原生瓦片到世界坐标转换会返回瓦片角点。位置和缩放会被尊重；实体旋转会被忽略。

画笔和印章会拒绝越界目标，除非 `clip: true`。按顺序的操作会在应用每次编辑前进行验证，并在第一个错误处停止，同时保留之前的成功结果。MCP 将每个请求限制为 128 个操作、1,000,000 次单元格访问和 1,000,000 个展开的瓦片实例，网格每个轴方向为 2 到 100 个区块。

使用 `editor_scene_screenshot(colliderDebug: true)`检查碰撞轮廓。只有启用碰撞的墙体图层才会生成这些形状；请在游戏中使用玩家验证开口和实心边界。

## 运行时脚本

`Tilemap_Component` 暴露了与编辑器使用的相同持久图层数据。图层按从 0 开始的索引寻址。移除图层会使其后所有索引减 1，因此除非你同步更新，否则不要在图层删除后继续保留该索引。

### CSL

```csl
tilemap := entity.get_component(Tilemap_Component);
ground := tilemap.add_layer(.GROUND);

tilemap.set_layer_tint(ground, v4{0.8, 0.9, 1, 1});
grass := tilemap.add_layer_texture(ground, get_asset(Texture_Asset, "tiles/grass.png"), 1);
tilemap.set_layer_texture_scale(ground, grass, {2, 1});
tilemap.set_layer_texture_offset(ground, grass, {0.5, 0});
tilemap.set_layer_mask(ground, get_asset(Texture_Asset, "$AO/tile_mask.png"));
tilemap.set_tile(ground, 10, 12);

world_position := tilemap.tile_to_world(ground, 10, 12);
tile_x, tile_y := tilemap.world_to_tile(ground, world_position);
```

CSL 的瓦片地图变更属于普通场景状态。它们会像其他 CSL 游戏状态一样参与预测、回滚和服务器协调。

### C\#

```csharp
Tilemap_Component tilemap = Entity.GetComponent<Tilemap_Component>();
int ground = tilemap.AddLayer(TilemapLayerKind.Ground);

tilemap.SetLayerTint(ground, new Vector4(0.8f, 0.9f, 1.0f, 1.0f));
int grass = tilemap.AddLayerTexture(ground, Assets.GetAsset<Texture>("tiles/grass.png"));
tilemap.SetLayerTextureScale(ground, grass, new Vector2(2.0f, 1.0f));
tilemap.SetLayerTextureOffset(ground, grass, new Vector2(0.5f, 0.0f));
tilemap.SetLayerMask(ground, Assets.GetAsset<Texture>("$AO/tile_mask.png"));
tilemap.SetTile(ground, 10, 12);

Vector2 worldPosition = tilemap.TileToWorld(ground, 10, 12);
tilemap.WorldToTile(ground, worldPosition, out int tileX, out int tileY);
```

C# 调用只会变更当前模拟。对于多人运行时更改，请使用游戏现有的 RPC 流程在每个对等端调用相同的变更；瓦片地图 API 不会创建新的复制通道。

运行时 API 包括：

* `调整大小`、区块/瓦片尺寸，以及按图层感知的本地/世界坐标转换。
* 图层添加、移除、清空、种类、渲染模式/顺序、色调、蒙版、轮廓、墙体设置和碰撞设置。
* 带权纹理的添加、替换、重新加权、移除、查找，以及每个纹理的缩放/偏移。
* 单个瓦片的查询、设置和清除操作。

瓦片地图至少为 2×2 个区块。调整大小会保留地图中心，将现有瓦片坐标按尺寸差的一半平移，并裁剪新边界之外的瓦片。越界写入瓦片不会产生任何效果，查询返回 false。纹理权重必须非负，且每个图层最多支持 256 个纹理。

无效的图层或纹理索引以及无效的图层设置会在脚本边界处被拒绝。纹理缩放在两个轴上都必须为正。C# 会抛出一个 `ArgumentOutOfRangeException` （或 `ArgumentException` ，用于纹理数量上限），而 CSL 会报告包含无效值和有效范围的脚本错误。

图层色调会乘以整个图层，包括轮廓和墙顶。色调更改会作为渲染统一变量应用，不会重新烘焙瓦片或重建碰撞。在瓦片地图下次更新之前进行的多个瓦片和碰撞更改会合并为一次几何/碰撞重建。

## 编辑模式

选择瓦片地图实体，然后在检查器中点击 **编辑** 按钮以进入瓦片地图编辑模式。点击 **取消** 退出。如果取消选择该实体，编辑模式会自动停用。

在编辑时，瓦片地图边界会以红色边框标出，并在场景视图中绘制网格叠加层。

## 工具

瓦片地图编辑器有三种工具模式，可通过热键切换：

| 工具      | 热键    | 说明                      |
| ------- | ----- | ----------------------- |
| **画笔**  | `B/W` | 通过单击并拖动来绘制瓦片。           |
| **橡皮擦** | `E`   | 通过单击并拖动来移除瓦片。           |
| **印章**  | `S/R` | 选择一个区域进行复制，然后将其粘贴到其他位置。 |

你也可以 **按住 Shift** 在画笔模式下临时擦除。

## 画笔绘制

单击并拖动可在所选图层上绘制瓦片。画笔在帧与帧之间使用 Bresenham 线插值，因此即使快速移动也不会跳过瓦片。

**画笔大小** 通过 `[` 和 `]` 调整（范围 1–32）。画笔是圆形的——半径内的瓦片都会受到影响。

**Alt+单击** 会从你上一次单击的位置到当前瓦片绘制一条直线，这对长直边很有用。

**Ctrl+拖动** 会切换到矩形填充模式——拖动以定义一个矩形，释放时区域内的所有瓦片都会被填充（如果同时按住 Shift，则会被擦除）。

## 图层

每个瓦片地图都支持多个图层。点击检查器中的某个图层即可选择它进行绘制。所选图层会以蓝色高亮显示。

### 添加和移除图层

* 点击 **添加图层** 底部创建一个新图层。
* 点击 **移除图层** 图层面板内将其删除。

### 图层属性

| 属性       | 说明                                                                           |
| -------- | ---------------------------------------------------------------------------- |
| **种类**   | `地面` 或 `墙体`。地面瓦片是平的；墙体瓦片会垂直挤出。                                               |
| **图层模式** | `默认` 使用自动分层（地面在玩家后方，墙体按 Y 排序）。 `手动` 允许你设置固定的渲染层值。                            |
| **手动图层** | 仅在手动模式下显示。显式的渲染层值。                                                           |
| **瓦片大小** | 每个瓦片在世界单位中的视觉大小；默认为 1。代理必须保持其不变。                                             |
| **色调**   | 完整图层的颜色乘数，包括墙顶和轮廓。                                                           |
| **纹理**   | 一个或多个带权重的纹理，用于随机多样性，并为每个纹理的重复图案提供独立的缩放和偏移控制。引擎会通过瓦片坐标哈希，基于权重为每个瓦片确定性地选择一个纹理。 |
| **蒙版**   | 用于自动贴图的 8×8 网格纹理。每个单元格对应不同的邻接配置（边缘、角落、孤立等）。内置一个默认地图 `$AO/tile_mask.png`      |
| **轮廓**   | 瓦片轮廓颜色（alpha 0 = 无轮廓）。                                                       |

### 多纹理多样性

每个图层都可以有多个带权重的纹理。瓦片会根据其网格坐标的哈希值确定性地选择一个纹理变体，因此图案在保存之间保持稳定，添加/移除瓦片时也不会移动。

每个纹理都显示为一张卡片，包含一个全宽资源选择器以及单独的 **权重**, **缩放（瓦片）**，以及 **偏移（瓦片）** 行。权重控制该纹理相对于其他纹理的出现频率。

缩放控制一个重复在瓦片单位中的大小。例如，Y 缩放为 `2` 会使纹理每两个垂直堆叠的瓦片重复一次。缩放必须保持为正。偏移会在本地瓦片单位中移动重复原点；正的 X 或 Y 值会将原点朝该正向瓦片地图方向移动。这些控制项只影响纹理图案，不影响瓦片几何、蒙版、碰撞或纹理选择。

## 自动贴图

瓦片会根据其 8 向邻居配置自动选择正确的蒙版单元格。系统会：

1. 检查全部 8 个邻居（N、NE、E、SE、S、SW、W、NW）。
2. 只有在两侧相邻的正交邻居都存在时，斜对角邻居才计入（可防止角落处的视觉伪影）。
3. 将得到的 8 位邻接蒙版映射到 8×8 蒙版纹理中的 64 个单元格之一。

这意味着你只需要绘制瓦片存在性——正确的边缘、角落和内部视觉效果会自动计算出来。

## 墙体图层

将图层种类设为 **墙体** 会启用垂直挤出。墙体瓦片像地面瓦片一样放置在网格上，但每个放置的瓦片都会生成一列主体瓦片，向上延伸 **墙高**.

### 墙体属性

| 属性       | 说明                                                    |
| -------- | ----------------------------------------------------- |
| **墙高**   | 每列墙体的高度（最小 2）。                                        |
| **顶部纹理** | 墙体顶行的单独纹理（“帽盖”），其缩放和偏移控制与主体纹理相同。它的卡片始终可见，而不是嵌套在纹理部分中。 |
| **顶部蒙版** | 墙顶的蒙版纹理（与地面使用相同的 8 邻居自动贴图）。                           |
| **顶部轮廓** | 墙顶瓦片的轮廓颜色。                                            |

墙体主体使用图层的主纹理。墙顶使用基准行的邻居，这样可保持帽盖边缘整洁。

墙体会按其基准行进行 Y 排序，因此玩家会走在上方墙体后面、下方墙体前面。

瓦片地图会遵循其实体的 X/Y 缩放。渲染、场景视图中的绘制和选择、坐标转换、墙体碰撞以及导航网格输入，都会使用缩放后的瓦片几何。负缩放会镜像瓦片地图。零缩放轴会使几何体塌缩，不能用于世界到瓦片的编辑或转换。

### 墙体碰撞

| 属性       | 说明                                                   |
| -------- | ---------------------------------------------------- |
| **碰撞**   | 为导航网格重建生成障碍边缘。                                       |
| **内缩**   | 从瓦片边界向内收缩碰撞边缘，以获得更贴合的碰撞。数值以未缩放的瓦片地图本地世界单位表示，并遵循实体缩放。 |
| **偏移**   | 先以未缩放的瓦片地图本地世界单位平移所有碰撞边缘，然后再遵循实体缩放。                  |
| **调试绘制** | 在场景视图中绘制绿色碰撞边缘以供调试。                                  |

启用碰撞后，引擎会从暴露的瓦片边界构建障碍边缘。启用自动重建的导航网格会接收这些边缘。在 CSL 中，这些边缘只会阻挡绑定到此类导航网格的代理；否则请添加碰撞体。

## 印章工具（复制与粘贴）

按 `S` 切换到印章模式。这会启用一个区域选择流程：

1. **选择**：单击并拖动以高亮一个矩形区域。选中的瓦片会复制到剪贴板。一个“已复制”弹窗会确认该操作。
2. **粘贴**：按 `Ctrl+V` 进入幽灵模式。剪贴板的半透明预览会跟随光标。
3. **旋转**：滚动鼠标滚轮以 90 度为增量旋转幽灵预览。
4. **放置**：单击以印出这些瓦片。单击时按住 Shift 可在不退出幽灵模式的情况下放置多个副本。
5. **取消**：按 `Escape` 以在不放置的情况下退出幽灵模式。

按住 **Ctrl** 在开始印章选择时，可从 **所有图层** 一次性复制，保留多图层结构。

## 键盘快捷键摘要

| 快捷键          | 操作                 |
| ------------ | ------------------ |
| `B` 或 `W`    | 切换到画笔工具            |
| `E`          | 切换到橡皮擦工具           |
| `S` 或 `R`    | 切换到印章工具            |
| `Shift` （按住） | 在画笔模式下临时擦除         |
| `[` / `]`    | 减小 / 增大画笔大小        |
| `Ctrl+拖动`    | 使用当前画笔或橡皮擦工具进行矩形填充 |
| `Alt+单击`     | 从上一次单击处绘制直线        |
| `Ctrl+V`     | 进入粘贴/幽灵模式          |
| `鼠标滚轮`       | 旋转幽灵预览（在幽灵模式下）     |
| `Shift+单击`   | 放置多个副本（在幽灵模式下）     |
| `Escape`     | 取消幽灵模式             |
