Unity记录5.8-地图-矿物分布
汇总:Unity 记录
摘要:矿物分布的生成。
矿物分布-2023/9/15
和地形类似,都是使用柏林噪声生成。
- 地形的柏林噪声是y固定,x变化的。
- 矿物这种2D分布的,则是xy都变化。
每个地形包含若干可生成的矿物,每个矿物有其标签,标签可指示其稀有度。
- 将稀有度映射为一个阈值,当2D噪声的值高于阈值时,矿物被生成。
之后的地形,生物之类的生成应该都会基于标签。
- 为了扩充一下知识面,最近晚上睡前在看中国国家地理,
- 看到墨脱在一个区域能有非常丰富的地形,海拔差特别大:【生命奇观】墨脱森林——世界第一大峡谷里的绝美生灵
- 以及一个特别高的树,树上能长不同类型植物,比世界树都nb,世界树也只是长果子而已:史无前例!我们爬上了中国最高树
- 以及几厘米的石块缝隙展示了几亿年的时间:这条缝,北京几乎所有地质专业的学生都要来参观
- 大自然真是神奇,所以我也想这么搞,看上去很有意思。
下面是效果,还可以。
- 土块的矿物是石块和蓝色块。石块的矿物是蓝色块。
- 石块稀有度是二级,蓝色块三级。
实现代码-2023/9/15
- 核心部分。
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System;
using Unity.VisualScripting;
using UnityEngine;
public class TilemapBlockMineral {
TilemapConfig _tilemap_base;
GameConfigs _game_configs;
TilemapTerrain _terrain;
public TilemapBlockMineral(TilemapConfig tilemap_base, GameConfigs game_configs, TilemapTerrain terrain){
_tilemap_base = tilemap_base;
_game_configs = game_configs;
_terrain = terrain;
}
// Start is called before the first frame update
void Start(){
}
// Update is called once per frame
void Update(){
}
public TilemapBlock _generate_2DBlock_mineral(TilemapBlock block){
// ---------- init ----------
Vector3Int BSize = _game_configs.__block_size__; // for convenience
float perlin;
int tile_index; // for generate different mineral in different place
RaritySearcher rarity_searcher = new(_tilemap_base, _game_configs);
// tile to rarity
string[] minerals = _terrain.ID2TerrainInfo[block.terrain_ID].minerals;
if (minerals.Count() == 0) return block;
Dictionary<string, float> tile2rarity = rarity_searcher._mapping_tilesID_to_rarity(minerals);
// ---------- fill map ----------
for (int x = 0; x < BSize.x; x++){
for (int y = 0; y < BSize.y; y++){
if (block.map[x][y] == "0") continue;
tile_index = 0;
foreach (KeyValuePair<string, float> kvp in tile2rarity){
tile_index += 1;
perlin = block._perlin(x + BSize.x * tile_index, y + BSize.y * tile_index, 10f);
if(perlin > kvp.Value){
block.map[x][y] = kvp.Key;
break;
}
}
}
}
return block;
}
}
class RaritySearcher{
Dictionary<string, float> _rarity = new() {
{"common", 0.8f},
{"uncommon", 0.6f},
{"rare", 0.4f},
{"mysterious", 0.2f},
{"root", 0.1f}};
TilemapConfig _tilemap_base;
GameConfigs _game_configs;
public RaritySearcher(TilemapConfig tilemap_base, GameConfigs game_configs){
_tilemap_base = tilemap_base;
_game_configs = game_configs;
}
float mapping_tileID_to_rarity(string tile_ID){
string tile_name = _tilemap_base._ID2tileName[tile_ID];
string[] tile_tags = _tilemap_base._tilemap_info.tiles[tile_name].tags;
foreach (KeyValuePair<string, float> kvp in _rarity){
if (tile_tags.Contains(kvp.Key)) return 1 - kvp.Value;
}
throw new ArgumentException("404: Rarity of tile-" + tile_ID + " Not Found.");
}
public Dictionary<string, float> _mapping_tilesID_to_rarity(string[] tile_ID){
Dictionary<string, float> rarity_dict = new();
// The tile further back has a higher priority
for (int i = tile_ID.Count()-1; i >= 0; i--){
rarity_dict.Add(tile_ID[i], mapping_tileID_to_rarity(tile_ID[i]));
}
return rarity_dict;
}
}
- Tile信息
{
"version": "0.0.1",
"tiles":{
"BlockSoilGrassySoil":{
"ID": "1",
"name": "Grassy Soil",
"description": "",
"path": "Tilemap/Block/Soil/BlockSoilGrassySoil",
"tags": ["common"]
},
"BlockMineralTest":{
"ID": "2",
"name": "Mineral Test",
"description": "",
"path": "Tilemap/Block/Mineral/BlockMineralTest",
"tags": ["rare"]
},
"BlockStoneGravel":{
"ID": "3",
"name": "Gravel",
"description": "",
"path": "Tilemap/Block/Stone/BlockStoneGravel",
"tags": ["uncommon"]
}
}
}
文章目录
关闭
共有 0 条评论