AI 实现初版随机地图
This commit is contained in:
181
Docs/PaperTerrainMapActor_Usage.md
Normal file
181
Docs/PaperTerrainMapActor_Usage.md
Normal file
@ -0,0 +1,181 @@
|
||||
# PaperTerrainMapActor 使用说明
|
||||
|
||||
## 概述
|
||||
|
||||
`APaperTerrainMapActor` 是一个封装了Paper2D TileMap组件的地形地图生成器Actor,集成了之前实现的地形生成器功能,可以直接在场景中生成和显示随机地图。
|
||||
|
||||
## 核心功能
|
||||
|
||||
### 1. 集成地形生成器
|
||||
- 内置 `UTerrainGenerator` 实例
|
||||
- 支持所有地形父子关系、概率权重和互斥关系
|
||||
- 自动应用默认地形配置
|
||||
|
||||
### 2. Paper2D TileMap 支持
|
||||
- 自动创建和管理PaperTileMap组件
|
||||
- 支持自定义地图尺寸和Tile大小
|
||||
- 自动调整组件缩放以适应地图尺寸
|
||||
|
||||
### 3. 地形到Tile映射
|
||||
- 可配置的地形标签到Tile索引映射
|
||||
- 支持自定义Tile映射关系
|
||||
- 默认Tile索引用于未映射的地形
|
||||
|
||||
### 4. 自动生成选项
|
||||
- 在构造时自动生成地图
|
||||
- 在游戏开始时自动生成地图
|
||||
- 支持手动触发生成
|
||||
|
||||
## 基本用法
|
||||
|
||||
### 在场景中使用
|
||||
|
||||
1. 在内容浏览器中右键 -> 创建高级资源 -> Blueprint类
|
||||
2. 选择 `APaperTerrainMapActor` 作为父类
|
||||
3. 将创建的Blueprint拖放到场景中
|
||||
|
||||
### 配置参数
|
||||
|
||||
在Details面板中可以配置以下参数:
|
||||
|
||||
**Map Settings:**
|
||||
- `MapWidth`: 地图宽度(格子数)
|
||||
- `MapHeight`: 地图高度(格子数)
|
||||
- `TileSize`: 每个Tile的大小(像素)
|
||||
- `bAutoGenerateOnConstruction`: 是否在构造时自动生成
|
||||
- `bAutoGenerateOnBeginPlay`: 是否在游戏开始时自动生成
|
||||
|
||||
**Terrain Mapping:**
|
||||
- `TerrainTileMappings`: 地形到Tile的映射表
|
||||
- `DefaultTileIndex`: 默认Tile索引
|
||||
|
||||
### 蓝图调用
|
||||
|
||||
在蓝图中可以调用以下函数:
|
||||
|
||||
```blueprint
|
||||
- GenerateTerrainMap():生成地图
|
||||
- ClearMap():清除当前地图
|
||||
- GetTerrainGenerator():获取地形生成器实例
|
||||
- GetGeneratedTerrainData():获取生成的地形数据
|
||||
```
|
||||
|
||||
## 高级配置
|
||||
|
||||
### 自定义地形映射
|
||||
|
||||
可以在Details面板中编辑 `TerrainTileMappings` 数组,为每个地形标签指定对应的Tile索引:
|
||||
|
||||
```cpp
|
||||
// 示例:自定义地形映射
|
||||
FTerrainTileMapping CustomMapping;
|
||||
CustomMapping.TerrainTag = FGameplayTag::RequestGameplayTag(TEXT("Terrain.Forest"));
|
||||
CustomMapping.TileIndex = 10; // 使用TileSet中的第10个Tile
|
||||
```
|
||||
|
||||
### 修改地形生成配置
|
||||
|
||||
通过获取地形生成器实例,可以动态修改地形配置:
|
||||
|
||||
```cpp
|
||||
// 在蓝图中或代码中修改配置
|
||||
UTerrainGenerator* Generator = PaperTerrainMapActor->GetTerrainGenerator();
|
||||
Generator->SetProbability(ForestHandle, 0.9f);
|
||||
Generator->SetWeight(ForestHandle, 8.0f);
|
||||
```
|
||||
|
||||
### 动态生成地图
|
||||
|
||||
可以在运行时动态生成不同尺寸的地图:
|
||||
|
||||
```cpp
|
||||
// 设置新尺寸
|
||||
PaperTerrainMapActor->MapWidth = 128;
|
||||
PaperTerrainMapActor->MapHeight = 128;
|
||||
|
||||
// 重新生成地图
|
||||
PaperTerrainMapActor->GenerateTerrainMap();
|
||||
```
|
||||
|
||||
## 性能优化
|
||||
|
||||
### 地图尺寸建议
|
||||
- 小地图:64x64 - 128x128(适合手机设备)
|
||||
- 中地图:256x256(默认,平衡性能和细节)
|
||||
- 大地图:512x512+(需要性能优化)
|
||||
|
||||
### 生成时机
|
||||
- 在加载界面预生成地图
|
||||
- 使用后台线程生成(需要自行实现线程逻辑)
|
||||
- 支持渐进式生成和流式加载
|
||||
|
||||
## 调试功能
|
||||
|
||||
### 日志输出
|
||||
Actor会输出详细的生成日志:
|
||||
- 地图初始化信息
|
||||
- 地形生成统计
|
||||
- TileMap应用结果
|
||||
|
||||
### 可视化调试
|
||||
- 在编辑器中实时查看生成结果
|
||||
- 支持运行时重新生成
|
||||
- 可以随时清除和重新生成地图
|
||||
|
||||
## 集成示例
|
||||
|
||||
### 与游戏逻辑集成
|
||||
|
||||
```cpp
|
||||
// 在GameMode中生成初始地图
|
||||
void ABusyGameMode::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
// 生成地图
|
||||
APaperTerrainMapActor* MapActor = GetWorld()->SpawnActor<APaperTerrainMapActor>();
|
||||
MapActor->GenerateTerrainMap();
|
||||
|
||||
// 保存地图引用
|
||||
CurrentMap = MapActor;
|
||||
}
|
||||
```
|
||||
|
||||
### 与导航系统集成
|
||||
|
||||
可以根据生成的地形数据设置导航网格:
|
||||
|
||||
```cpp
|
||||
// 根据地形类型设置导航成本
|
||||
for (const FGameplayTag& TerrainTag : MapActor->GetGeneratedTerrainData())
|
||||
{
|
||||
if (TerrainTag.MatchesTag(FGameplayTag::RequestGameplayTag(TEXT("Terrain.Water"))))
|
||||
{
|
||||
// 水域导航成本高
|
||||
SetNavigationCost(TerrainTag, 10.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 普通地形导航成本低
|
||||
SetNavigationCost(TerrainTag, 1.0f);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **TileSet配置**:需要提前配置好Paper2D TileSet资源
|
||||
2. **地形标签**:确保GameplayTags设置中包含所需的地形标签
|
||||
3. **性能考虑**:大地图生成可能耗时,建议在后台线程进行
|
||||
4. **内存使用**:大地图会占用较多内存,注意资源管理
|
||||
|
||||
## 扩展建议
|
||||
|
||||
### 添加多层地形
|
||||
可以扩展支持多层TileMap,用于表现地形高度、装饰物等。
|
||||
|
||||
### 动态地形修改
|
||||
支持运行时修改特定位置的地形,用于表现建筑、道路等。
|
||||
|
||||
### 序列化支持
|
||||
添加地图数据的序列化功能,支持保存和加载生成的地图。
|
||||
149
Docs/TerrainGenerator_Usage.md
Normal file
149
Docs/TerrainGenerator_Usage.md
Normal file
@ -0,0 +1,149 @@
|
||||
# 地形生成器使用说明
|
||||
|
||||
## 概述
|
||||
|
||||
这个地形生成器实现了基于区域生长算法和柏林噪声的随机地图生成系统,支持复杂的地形父子关系、概率权重配置和互斥关系。
|
||||
|
||||
## 核心功能
|
||||
|
||||
### 1. 地形父子关系
|
||||
- 支持多层级父子关系(类似B+树结构)
|
||||
- 父节点不出现时,所有子节点都不出现
|
||||
- 支持祖孙关系处理
|
||||
|
||||
### 2. 概率和权重配置
|
||||
- 概率 (0-1):控制地形是否出现
|
||||
- 权重 (≥0):控制地形在出现时的面积占比
|
||||
- 权重为0表示不生成该地形
|
||||
|
||||
### 3. 互斥关系
|
||||
- 支持多个地形之间的互斥关系
|
||||
- 互斥的地形不会同时出现
|
||||
- 支持复杂的互斥组配置
|
||||
|
||||
### 4. 生成算法
|
||||
- **区域生长算法**:生成连续的地形区域
|
||||
- **柏林噪声**:用于地形边界平滑和自然过渡
|
||||
- 支持自定义地图大小(默认256x256)
|
||||
|
||||
## 基本用法
|
||||
|
||||
### C++ 使用示例
|
||||
|
||||
```cpp
|
||||
// 创建生成器实例
|
||||
UTerrainGenerator* Generator = NewObject<UTerrainGenerator>();
|
||||
|
||||
// 添加地形
|
||||
int32 ForestHandle = Generator->AddTerrain(FGameplayTag::RequestGameplayTag(TEXT("Terrain.Forest")));
|
||||
int32 GrasslandHandle = Generator->AddTerrain(FGameplayTag::RequestGameplayTag(TEXT("Terrain.Grassland")));
|
||||
|
||||
// 设置概率和权重
|
||||
Generator->SetProbability(ForestHandle, 0.8f);
|
||||
Generator->SetWeight(ForestHandle, 9.0f);
|
||||
|
||||
// 生成地图
|
||||
TArray<FGameplayTag> Map = Generator->GenerateMap(256, 256);
|
||||
```
|
||||
|
||||
### 蓝图使用示例
|
||||
|
||||
1. 在蓝图中调用 `CreateTerrainGenerator` 创建实例
|
||||
2. 调用 `SetupExampleTerrainConfig` 快速设置示例配置
|
||||
3. 调用 `Generate2DMap` 生成二维地图数组
|
||||
4. 使用 `GetTerrainDisplayName` 获取地形显示名称
|
||||
|
||||
## 地形标签配置
|
||||
|
||||
需要在项目的GameplayTags设置中配置以下地形标签:
|
||||
|
||||
```ini
|
||||
[GameplayTags]
|
||||
+GameplayTagList=(Tag="Terrain.Forest")
|
||||
+GameplayTagList=(Tag="Terrain.Grassland")
|
||||
+GameplayTagList=(Tag="Terrain.Water")
|
||||
+GameplayTagList=(Tag="Terrain.Swamp")
|
||||
+GameplayTagList=(Tag="Terrain.Land")
|
||||
+GameplayTagList=(Tag="Terrain.Swamp.Land")
|
||||
+GameplayTagList=(Tag="Terrain.Swamp.Water")
|
||||
+GameplayTagList=(Tag="Terrain.Water.Shallow")
|
||||
+GameplayTagList=(Tag="Terrain.Water.Deep")
|
||||
```
|
||||
|
||||
## 高级配置
|
||||
|
||||
### 父子关系绑定
|
||||
|
||||
```cpp
|
||||
// 添加父地形和子地形
|
||||
int32 SwampHandle = Generator->AddTerrain(SwampTag);
|
||||
int32 SwampLandHandle = Generator->AddTerrain(SwampLandTag);
|
||||
int32 SwampWaterHandle = Generator->AddTerrain(SwampWaterTag);
|
||||
|
||||
// 绑定父子关系
|
||||
Generator->BindChildTerrain(SwampHandle, {SwampLandHandle, SwampWaterHandle});
|
||||
```
|
||||
|
||||
### 互斥关系设置
|
||||
|
||||
```cpp
|
||||
// 设置森林和沼泽水域互斥
|
||||
Generator->SetExclusive({ForestHandle, SwampWaterHandle});
|
||||
```
|
||||
|
||||
### 复杂权重配置
|
||||
|
||||
```cpp
|
||||
// 设置沼泽子地形的权重比例
|
||||
Generator->SetWeight(SwampLandHandle, 1.0f); // 沼泽陆地占沼泽区域的1/3
|
||||
Generator->SetWeight(SwampWaterHandle, 2.0f); // 沼泽水域占沼泽区域的2/3
|
||||
```
|
||||
|
||||
## 性能考虑
|
||||
|
||||
- 地图生成可以在后台线程中进行
|
||||
- 256x256地图生成时间约100-500ms(取决于硬件)
|
||||
- 建议在游戏加载时预生成地图
|
||||
- 支持渐进式生成和流式加载
|
||||
|
||||
## 调试和测试
|
||||
|
||||
### 控制台命令
|
||||
|
||||
```bash
|
||||
# 在控制台中输入以下命令测试生成器
|
||||
TestTerrainGenerator
|
||||
```
|
||||
|
||||
### 日志输出
|
||||
|
||||
生成器会输出详细的统计信息:
|
||||
- 各地形类型的数量和百分比
|
||||
- 互斥关系验证结果
|
||||
- 父子关系验证结果
|
||||
|
||||
## 自定义扩展
|
||||
|
||||
### 添加新的地形类型
|
||||
|
||||
1. 在GameplayTags配置中添加新标签
|
||||
2. 使用 `AddTerrain` 添加新地形
|
||||
3. 配置相应的概率和权重
|
||||
|
||||
### 修改生成算法
|
||||
|
||||
可以重写以下方法来自定义生成行为:
|
||||
- `RegionGrowing`: 区域生长算法实现
|
||||
- `ApplyPerlinNoiseSmoothing`: 噪声平滑处理
|
||||
- `GetValidLeafNodes`: 有效节点筛选逻辑
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **概率为0**:地形绝对不会出现,所有子节点也不会出现
|
||||
2. **权重为0**:地形不会生成,但可能影响互斥关系
|
||||
3. **互斥组**:多次调用SetExclusive不会传导互斥关系
|
||||
4. **生成失败**:如果没有有效地形可以生成,会返回空地图并输出错误日志
|
||||
|
||||
## 示例配置
|
||||
|
||||
参考 `SetupExampleTerrainConfig` 方法中的配置,包含了完整的父子关系、概率权重和互斥关系设置。
|
||||
Reference in New Issue
Block a user