// Managers/TileManager.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Data; using Map; using UnityEngine; using UnityEngine.Tilemaps; using Utils; using Object = UnityEngine.Object; // 明确指定UnityEngine.Object namespace Managers { public class TileManager : Singleton, ILaunchManager { // 缓存所有根据定义生成的RuleTile实例 private readonly Dictionary _cachedTiles = new(); // 地图生成器工作类映射,Key: MapGeneratorDef.defName, Value: MapGeneratorWorkClassBase private readonly Dictionary _mapGeneratorWorkClassMap = new(); /// /// 指示管理器是否已完成初始化。 /// public bool Completed { get; set; } // 新增:实现 ILaunchManager 接口的 Completed 属性 public string StepDescription => "正在加载瓦片"; /// /// 初始化瓦片管理器:加载所有瓦片定义并创建RuleTile实例,加载地图生成器定义。 /// /// 一个表示异步操作完成的 Task。 public Task Init() // 接口变更:方法签名变为 async Task { // 使用 Completed 属性作为统一的状态检查,防止重复初始化 if (Completed) return Task.CompletedTask; // 遵循不检查单例的原则,假定 DefineManager.Instance 始终可用。 var tileDefs = DefineManager.Instance.QueryDefinesByType(); if (tileDefs == null) { Completed = true; // 即使没有定义,也认为初始化流程已完成 return Task.CompletedTask; } foreach (var def in tileDefs) { if (string.IsNullOrEmpty(def.defName)) { Debug.LogWarning("发现未定义名称或defName的TileDef,已跳过。"); continue; } var tileName = def.defName; var ruleTile = ScriptableObject.CreateInstance(); ruleTile.name = tileName; // 设置ScriptableObject的名称 ruleTile.m_DefaultColliderType = def.collider; // 遵循不检查单例的原则,假定 PackagesImageManager.Instance 始终可用。 ruleTile.m_DefaultSprite = PackagesImageManager.Instance.GetSprite(def.texture); ruleTile.m_TilingRules = GetTileRules(def.rules); _cachedTiles[tileName] = ruleTile; } // 遵循不检查单例的原则,假定 DefineManager.Instance 始终可用。 var generatorDefs = DefineManager.Instance.QueryDefinesByType(); if (generatorDefs != null) // 检查 generatorDefs 是否为 null { foreach (var mapGeneratorDef in generatorDefs) { var workClass = StringUtils.CreateMapGeneratorInstance(mapGeneratorDef.workClass); if (workClass == null) { Debug.LogWarning($"无法为地图生成器 '{mapGeneratorDef.defName}' 创建工作类 '{mapGeneratorDef.workClass}',已跳过。"); continue; } workClass.Init(mapGeneratorDef.value); _mapGeneratorWorkClassMap[mapGeneratorDef.defName] = workClass; } } Completed = true; // 在所有初始化逻辑完成后设置 Completed 为 true return Task.CompletedTask; // 由于 Init 方法内部当前没有真正的异步操作,不需要显式 await Task.CompletedTask; // 编译器会为同步的 async Task 方法自动生成一个已完成的 Task。 } /// /// 清空所有缓存的瓦片定义和地图生成器工作类。 /// public void Clear() { foreach (var tile in _cachedTiles.Values) if (tile != null) Object.Destroy(tile); // 销毁动态创建的 ScriptableObject 实例 _cachedTiles.Clear(); _mapGeneratorWorkClassMap.Clear(); // 清空地图生成器工作类映射 Completed = false; // 清理后将 Completed 置为 false } private static List GetTileRules(RuleTileRuleDef[] rules) { // Null-conditional operator 和 ToList() 确保即使 rules 为 null 也不会抛出异常 return rules?.Select(GetTileRule).ToList() ?? new List(); } /// /// 将自定义的 RuleTileRuleDef 转换为 Unity 的 RuleTile.TilingRule。 /// /// 自定义的 RuleTileRuleDef 规则定义。 /// 转换后的 RuleTile.TilingRule 实例。 private static RuleTile.TilingRule GetTileRule(RuleTileRuleDef ruleDef) { if (ruleDef == null) return null; var tilingRule = new RuleTile.TilingRule { // 遵循不检查单例的原则,假定 PackagesImageManager.Instance 始终可用。 m_Sprites = PackagesImageManager.Instance.GetSprites(ruleDef.animationTextures.ToArray()), m_Output = ruleDef.outputType, m_ColliderType = ruleDef.outputCollider, m_PerlinScale = ruleDef.chance, m_MaxAnimationSpeed = ruleDef.animationSpeed, m_MinAnimationSpeed = ruleDef.animationSpeed, m_RuleTransform = ruleDef.transform }; // 使用 Dictionary 存储邻居条件,键为位置,值为邻居类型 var neighborConditionsMap = new Dictionary(); // 预设的8个邻居位置 var defaultPositions = new[] { new Vector3Int(-1, 1, 0), new Vector3Int(0, 1, 0), new Vector3Int(1, 1, 0), new Vector3Int(-1, 0, 0), new Vector3Int(1, 0, 0), new Vector3Int(-1, -1, 0), new Vector3Int(0, -1, 0), new Vector3Int(1, -1, 0) }; // 处理标准8个邻居条件 for (var i = 0; i < ruleDef.neighborConditions.Length && i < 8; i++) { int neighborType; switch (ruleDef.neighborConditions[i]) { case RuleTileRuleDef.NeighborConditionType.NotThis: neighborType = RuleTile.TilingRuleOutput.Neighbor.NotThis; neighborConditionsMap[defaultPositions[i]] = neighborType; // 添加或更新 break; case RuleTileRuleDef.NeighborConditionType.This: neighborType = RuleTile.TilingRuleOutput.Neighbor.This; neighborConditionsMap[defaultPositions[i]] = neighborType; // 添加或更新 break; case RuleTileRuleDef.NeighborConditionType.Any: default: // 如果是Any或默认,则不添加到map中,表示不关心此位置 break; } } // 处理扩展邻居条件,如果位置重复,则覆盖标准8个邻居的定义 if (ruleDef.neighborConditionExtend != null) foreach (var neighborConditionDef in ruleDef.neighborConditionExtend) { var pos = StringUtils.StringToVector3Int(neighborConditionDef.position); int neighborType; switch (neighborConditionDef.Type) { case RuleTileRuleDef.NeighborConditionType.NotThis: neighborType = RuleTile.TilingRuleOutput.Neighbor.NotThis; neighborConditionsMap[pos] = neighborType; // 添加或覆盖 break; case RuleTileRuleDef.NeighborConditionType.This: neighborType = RuleTile.TilingRuleOutput.Neighbor.This; neighborConditionsMap[pos] = neighborType; // 添加或覆盖 break; case RuleTileRuleDef.NeighborConditionType.Any: default: // 如果是Any或默认,则不添加到map中 // 如果我们希望Any清除之前的显式定义,可以在这里neighborConditionsMap.Remove(pos); // 但通常Any意味着不关心,所以保持不添加即可 break; } } tilingRule.m_NeighborPositions = new List(neighborConditionsMap.Keys); tilingRule.m_Neighbors = new List(neighborConditionsMap.Values); return tilingRule; } /// /// 根据名称获取一个 RuleTile 实例。 /// /// 瓦片的名称 (TileDef.defName) /// 对应的 RuleTile 实例,如果找不到则返回 null。 public TileBase GetTile(string tileName) { if (_cachedTiles.TryGetValue(tileName, out var tile)) return tile; Debug.LogWarning($"瓦片 '{tileName}' 未在TileManager缓存中找到。"); return null; } /// /// 应用指定的地图生成器,现在是非阻塞的异步操作。 /// /// 要应用的生成器名称。 /// 可选:指定要使用的 MapGenerator 实例。如果为 null,将尝试从 Program.Instance.FocusedDimension 获取。 /// 一个表示异步操作完成的 Task。 public async Task ApplyMapGenerator(string generatorName, Landform landform = null) { if (landform == null) { // 尝试从 Program.Instance.FocusedDimension 获取 mapGenerator // 假设 Program 和 FocusedDimension 结构存在 // 遵循不检查单例、不检查给定的API的原则。 landform = Program.Instance.FocusedDimension.landform; if (landform == null) { Debug.LogError( $"ApplyMapGenerator: 无法找到地图生成器 '{generatorName}' 对应的 mapGenerator。Program.Instance、FocusedDimension 或其 landform 可能为空。"); return; // async Task 方法直接 return; 意味着返回 Task.CompletedTask } } if (_mapGeneratorWorkClassMap == null) // 这个检查在 Init 保证了 map 不会为 null 后,理论上在这里是不需要的。 { Debug.LogError($"ApplyMapGenerator: _mapGeneratorWorkClassMap 未初始化,无法找到生成器 '{generatorName}'。"); return; } if (_mapGeneratorWorkClassMap.TryGetValue(generatorName, out var mapGeneratorWorkClass)) { if (mapGeneratorWorkClass == null) { Debug.LogError( $"ApplyMapGenerator: 为生成器 '{generatorName}' 找到了一个空的 IMapGeneratorWorkClass 实例。这表明 _mapGeneratorWorkClassMap 配置存在问题。"); return; } try { await mapGeneratorWorkClass.Process(landform); // <-- 使用 await 调用异步 Process 方法 } catch (Exception ex) { Debug.LogError($"ApplyMapGenerator: 地图生成器 '{generatorName}' 异步处理过程中发生错误: {ex.Message}"); throw; // 抛出异常以通知调用者,或者根据实际情况选择捕获并完全处理 } } else { Debug.LogError( $"ApplyMapGenerator: 未找到名为 '{generatorName}' 的 IMapGeneratorWorkClass。请确保该生成器已在 _mapGeneratorWorkClassMap 中注册。"); } } public MapGeneratorWorkClassBase GetMapGeneratorWorkClass(string defName) { return _mapGeneratorWorkClassMap?.GetValueOrDefault(defName, null); } } }