using UnityEngine; using Newtonsoft.Json; using System; using System.Threading.Tasks; // 引入 System.Threading.Tasks using Managers; using Utils; namespace Map { /// /// 植物生成器配置类。 /// public class PlantGeneratorConfig { /// /// 植物瓦片的定义名称。 /// [JsonProperty("tileDefName", Required = Required.Always)] public string TileDefName { get; set; } = "DefaultPlantTile"; /// /// 柏林噪声的缩放因子。 /// [JsonProperty("scale")] public double Scale { get; set; } = 0.08; /// /// 柏林噪声阈值,高于此值才可能生成植物 (-1到1之间)。 /// [JsonProperty("threshold")] public double Threshold { get; set; } = 0.3; /// /// 植物生成概率 (0-1之间),控制稀疏度。 /// [JsonProperty("density")] public double Density { get; set; } = 0.6; /// /// 柏林噪声的X轴偏移。 /// [JsonProperty("offsetX")] public double OffsetX { get; set; } = 0.0; /// /// 柏林噪声的Y轴偏移。 /// [JsonProperty("offsetY")] public double OffsetY { get; set; } = 0.0; /// /// 植物必须生长在其上的基础瓦片名称 (可空)。 /// [JsonProperty("requiredBaseTileDefName")] public string RequiredBaseTileDefName { get; set; } = null; /// /// 地图生成区域的宽度(单元格数量)。 /// [JsonProperty("mapCellSizeX")] public int MapCellSizeX { get; set; } = 100; /// /// 地图生成区域的高度(单元格数量)。 /// [JsonProperty("mapCellSizeY")] public int MapCellSizeY { get; set; } = 100; /// /// 是否避免植物瓦片互相重叠。 /// [JsonProperty("preventOverlap")] public bool PreventOverlap { get; set; } = true; } public class PlantMapGenerator : MapGeneratorWorkClassBase { private PlantGeneratorConfig _config; /// /// 初始化植物生成器,解析JSON配置字符串。 /// /// 包含植物生成参数的JSON字符串。 public override void Init(string value) { try { _config = JsonConvert.DeserializeObject(value); if (_config == null) { Debug.LogError("植物地图生成器:配置反序列化为空。请检查JSON格式。将使用默认配置。"); _config = new PlantGeneratorConfig(); } if (string.IsNullOrWhiteSpace(_config.TileDefName)) { Debug.LogWarning("植物地图生成器:瓦片定义名称为空。将使用默认值 'DefaultPlantTile'。"); _config.TileDefName = "DefaultPlantTile"; } if (_config.Scale <= 0) { Debug.LogWarning($"植物地图生成器:缩放值必须为正数。将设置为默认值 0.08。当前值: {_config.Scale}"); _config.Scale = 0.08; } // Unity的Mathf.PerlinNoise输出0-1,如果PerlinNoise.Instance.Noise也如此,这里需要修改范围 // 假设 PerlinNoise.Instance.Noise() 返回值在 -1 到 1 之间。 if (_config.Threshold < -1.0 || _config.Threshold > 1.0) { Debug.LogWarning($"植物地图生成器:阈值 ({_config.Threshold}) 超出柏林噪声典型范围 (-1.0到1.0)。已钳制到 0.3。"); _config.Threshold = 0.3; } if (_config.Density < 0 || _config.Density > 1) { Debug.LogWarning($"植物地图生成器:密度 ({_config.Density}) 必须在 0 到 1 之间。已钳制到 0.6。"); _config.Density = Mathf.Clamp((float)_config.Density, 0f, 1f); } if (_config.MapCellSizeX <= 0) { Debug.LogWarning($"植物地图生成器:地图宽度 ({_config.MapCellSizeX}) 必须为正数。将设置为默认值 100。"); _config.MapCellSizeX = 100; } if (_config.MapCellSizeY <= 0) { Debug.LogWarning($"植物地图生成器:地图高度 ({_config.MapCellSizeY}) 必须为正数。将设置为默认值 100。"); _config.MapCellSizeY = 100; } } catch (JsonSerializationException ex) { Debug.LogError($"植物地图生成器:配置JSON反序列化错误:{ex.Message}。输入JSON: '{value}'"); _config = new PlantGeneratorConfig(); } catch (Exception ex) { Debug.LogError($"植物地图生成器:初始化过程中发生未预期错误:{ex.Message}。输入JSON: '{value}'"); _config = new PlantGeneratorConfig(); } } /// /// 根据柏林噪声和配置参数在 `MapGenerator` 的 `plantTilemap` 上生成植物。 /// 此方法现在是异步的,以避免阻塞主线程。 /// /// MapGenerator实例,包含要操作的Tilemap。 public override async Task Process(MapGenerator map) // 标记为 async Task { if (_config == null) { Debug.LogError("植物地图生成器:在Init方法调用前或Init失败后调用Process。中止生成。"); return; // async Task 方法直接 return; 意味着返回 Task.CompletedTask } if (map == null || map.plantTilemap == null) { Debug.LogError("植物地图生成器:MapGenerator或植物瓦片地图为空。无法生成植物。中止。"); return; } var plantTile = TileManager.Instance.GetTile(_config.TileDefName); if (plantTile == null) { Debug.LogError($"植物地图生成器:无法获取名称为 '{_config.TileDefName}' 的瓦片。请确保瓦片管理器返回有效瓦片。中止生成。"); return; } // 缓存 requiredBaseTile 的引用,避免在循环中重复查询 TileManager UnityEngine.Tilemaps.TileBase requiredBaseTile = null; if (!string.IsNullOrEmpty(_config.RequiredBaseTileDefName)) { if (map.baseTilemap == null) { Debug.LogWarning($"植物地图生成器:已配置基础瓦片名称 ('{_config.RequiredBaseTileDefName}') 但基础瓦片地图为空。将忽略基础地形要求。"); } else { requiredBaseTile = TileManager.Instance.GetTile(_config.RequiredBaseTileDefName); if (requiredBaseTile == null) { Debug.LogWarning($"植物地图生成器:无法获取所需的基础瓦片 '{_config.RequiredBaseTileDefName}'。将忽略基础地形要求。"); } } } for (var x = 0; x < _config.MapCellSizeX; x++) { for (var y = 0; y < _config.MapCellSizeY; y++) { var cellPosition = new Vector3Int(x, y, 0); var sampleX = (x / (double)_config.MapCellSizeX) * _config.Scale + _config.OffsetX; var sampleY = (y / (double)_config.MapCellSizeY) * _config.Scale + _config.OffsetY; var noiseValue = PerlinNoise.Instance.Noise(sampleX, sampleY); if (noiseValue < _config.Threshold) { continue; } // 检查所需的基础瓦片 if (requiredBaseTile != null) { var baseTileOnMap = map.baseTilemap.GetTile(cellPosition); if (baseTileOnMap == null || baseTileOnMap.name != requiredBaseTile.name) { continue; } } // 检查是否重叠 if (_config.PreventOverlap) { var existingPlant = map.plantTilemap.GetTile(cellPosition); if (existingPlant != null) { continue; } } // 检查密度 if (UnityEngine.Random.value >= _config.Density) { continue; } map.plantTilemap.SetTile(cellPosition, plantTile); } // 每处理完一列,就让出控制权给主线程 await Task.Yield(); } } } }