using System; using System.Collections.Generic; // 新增,用于List using Data; using Managers; using UnityEngine; using Random = UnityEngine.Random; using Newtonsoft.Json; // 新增Newtonsoft.Json的引用 namespace EventWorkClass { /// /// Event_EntityGenerater 事件的配置数据结构。 /// [Serializable] public class EntityGenerateConfig { /// /// 要生成的实体定义列表,将从中随机选择。 /// public List DefinitionsToChooseFrom; /// /// 要生成的实体总数。 /// public int Count = 1; // 默认生成一个 /// /// 生成位置类型。 /// public EntitySpawnLocationType LocationType; // 以下是各种LocationType可能需要的配置参数 /// /// 用于 AroundSpecificCoordinates 类型:生成中心坐标。 /// public Vector3 CenterCoordinates; /// /// 用于 AroundSpecificCoordinates 或 AroundTargetEntity 类型:生成半径。 /// public float Radius = 10f; // 默认半径 /// /// 用于 InsideSpecificBuildingType 类型:目标建筑的类型ID。 /// public string BuildingTypeDefName; /// /// 用于 AroundTargetEntity 类型:目标派系的定义名 (factionDefName)。 /// public string TargetFactionDefName; /// /// 用于 AtPredefinedSpawnPoint 类型:预定义生成点的ID。 /// public string SpawnPointTileMapDefName; /// /// 用于 OffMap 类型:距离地图边界的额外偏移量。 /// public float OffMapOffset = 5f; } /// /// 单个实体定义的配置条目。 /// [Serializable] // 保持可序列化,以便在Unity Inspector中显示 public class EntityDefinitionEntry { /// /// 实体定义名 (defName)。 /// public string DefName; /// /// 实体定义的具体类型名。 /// public string DefTypeName; } /// /// 定义生成器生成地图实体的可能位置类型。 /// public enum EntitySpawnLocationType { /// /// 未指定或无效的生成位置类型。 /// None = 0, /// /// 在地图的可玩区域边界之外生成实体。 /// 例如:用于在地图边缘或不可见区域生成物体,然后开始移动进入地图。 /// OffMap, /// /// 在指定类型建筑的内部或附近生成实体。 /// 例如:在 "工厂"、"商店"、"居住区" 等建筑内或其出入口。 /// 需要一个标识符来指定建筑类型。 /// InsideSpecificBuildingType, /// /// 在指定坐标点的周围区域内生成实体。 /// 需要额外的坐标参数和半径/范围参数。 /// AroundSpecificCoordinates, /// /// 在特定派系(或其他指定目标实体,例如NPC或特定对象)的周围区域内生成实体。 /// 需要一个标识符来指定目标派系的定义名,以及一个半径/范围参数。 /// AroundTargetEntity, /// /// 在地图上的随机可生成点生成实体。 /// RandomlyOnMap, /// /// 在预定义的生成点(Spawn Point)生成实体。 /// 这些点通常由地图设计者放置,并带有唯一的ID或名称。 /// AtPredefinedSpawnPoint } public class Event_EntityGenerater : EventWorkClassBase { private EntityGenerateConfig _config; private List _validatedEntityDefs; // 用于存储所有已验证的实体定义 /// /// 初始化实体生成器事件。 /// /// 包含事件配置的JSON字符串。 public override void Init(string value) { if (string.IsNullOrEmpty(value)) { Debug.LogError("初始化值为空或null。请提供一个JSON配置字符串。"); return; } try { _config = JsonConvert.DeserializeObject(value); // 使用Newtonsoft.Json } catch (Exception ex) { Debug.LogError($"解析配置JSON时出错: {value}。异常信息: {ex.Message}"); return; // 解析失败,直接返回 } if (_config == null) { Debug.LogError($"无法解析配置JSON: {value}"); return; } if (_config.DefinitionsToChooseFrom == null || _config.DefinitionsToChooseFrom.Count == 0) { Debug.LogError($"实体生成配置中没有定义任何要生成的实体。请检查 'DefinitionsToChooseFrom' 列表。"); return; } _validatedEntityDefs = new List(); foreach (var entry in _config.DefinitionsToChooseFrom) { if (string.IsNullOrEmpty(entry.DefTypeName)) { Debug.LogWarning($"实体定义类型名为空或null (实体定义名: '{entry.DefName}')。跳过此定义。"); continue; } var entityDef = (EntityDef)DefineManager.Instance.FindDefine(entry.DefTypeName, entry.DefName); if (entityDef == null) { Debug.LogWarning($"未找到实体定义 (名称: '{entry.DefName}', 类型: '{entry.DefTypeName}')。请检查配置。跳过此定义。"); } else { _validatedEntityDefs.Add(entityDef); } } if (_validatedEntityDefs.Count == 0) { Debug.LogError($"所有配置的实体定义都无效或未找到。事件初始化失败。"); } } /// /// 运行实体生成器事件,在指定维度生成实体。 /// /// 要生成实体的维度ID。 public override void Run(string dimensionID) { if (_config == null) { Debug.LogError("事件配置(_config)为空。Init()可能失败了。"); return; } if (_validatedEntityDefs == null || _validatedEntityDefs.Count == 0) { Debug.LogError("没有有效实体定义可供生成。请检查Init()方法和配置。"); return; } for (int i = 0; i < _config.Count; i++) { // 随机选择一个实体定义 var selectedEntityDef = _validatedEntityDefs[Random.Range(0, _validatedEntityDefs.Count)]; var position = GetPosition(dimensionID); // 检查 GetPosition 是否返回了有效的非零位置,除非它是 AroundSpecificCoordinates 且中心点就是 Vector3.zero if (position == Vector3.zero && (_config.LocationType != EntitySpawnLocationType.AroundSpecificCoordinates || _config.CenterCoordinates != Vector3.zero)) { Debug.LogWarning($"未能为类型 {_config.LocationType} 获取有效的生成位置。实体可能在原点 (0,0,0) 生成。"); } if (selectedEntityDef is CharacterDef characterDef) { EntityManage.Instance.GenerateEntity(dimensionID, characterDef, position); continue; } if (selectedEntityDef is MonsterDef monsterDef) { EntityManage.Instance.GenerateMonsterEntity(dimensionID, monsterDef, position); continue; } Debug.LogWarning($"目标实体 '{selectedEntityDef.defName}' (类型: {selectedEntityDef.GetType().Name}) 既不是 CharacterDef 也不是 MonsterDef。" + $"如果你想生成其他类型,EntityManage需要一个通用的生成实体方法。没有生成此实体。"); } } /// /// 根据配置获取实体生成位置。 /// /// 要获取位置的维度ID。 /// 计算出的生成位置,如果失败则返回 Vector3.zero。 private Vector3 GetPosition(string dimensionID) { if (_config == null) { Debug.LogError("获取位置时配置为空。返回 Vector3.zero。"); return Vector3.zero; } var dimension = Program.Instance.GetDimension(dimensionID); if (dimension == null) { Debug.LogError($"未找到维度 '{dimensionID}'。无法确定生成位置。"); return Vector3.zero; } var mapGenerator = dimension.mapGenerator; if (mapGenerator == null) { Debug.LogError($"维度 '{dimensionID}' 的地图生成器为空。无法确定生成位置。"); return Vector3.zero; } switch (_config.LocationType) { case EntitySpawnLocationType.OffMap: { var size = mapGenerator.GetSize(); var dir = Random.Range(0, 4); // 0:上, 1:下, 2:左, 3:右 Vector2Int gridCoord; // 地图网格坐标 Vector2Int worldCoord2D; // GetWorldCoordinates 返回的 Vector2Int Vector3 worldPos3D; // 最终的 Vector3 世界坐标 var offset = _config.OffMapOffset; switch (dir) { case 0: // Top border (max Y) gridCoord = new Vector2Int(Random.Range(0, size.x), size.y); worldCoord2D = mapGenerator.GetWorldCoordinates(gridCoord); worldPos3D = new Vector3(worldCoord2D.x, worldCoord2D.y, 0f); // 转换为 Vector3 worldPos3D.y += offset; break; case 1: // Bottom border (min Y) gridCoord = new Vector2Int(Random.Range(0, size.x), 0); worldCoord2D = mapGenerator.GetWorldCoordinates(gridCoord); worldPos3D = new Vector3(worldCoord2D.x, worldCoord2D.y, 0f); // 转换为 Vector3 worldPos3D.y -= offset; break; case 2: // Left border (min X) gridCoord = new Vector2Int(0, Random.Range(0, size.y)); worldCoord2D = mapGenerator.GetWorldCoordinates(gridCoord); worldPos3D = new Vector3(worldCoord2D.x, worldCoord2D.y, 0f); // 转换为 Vector3 worldPos3D.x -= offset; break; case 3: // Right border (max X) gridCoord = new Vector2Int(size.x, Random.Range(0, size.y)); worldCoord2D = mapGenerator.GetWorldCoordinates(gridCoord); worldPos3D = new Vector3(worldCoord2D.x, worldCoord2D.y, 0f); // 转换为 Vector3 worldPos3D.x += offset; break; default: Debug.LogError("OffMap 生成方向无效。不应该发生此情况。"); return Vector3.zero; } worldPos3D.x += Random.Range(-offset / 2f, offset / 2f); worldPos3D.y += Random.Range(-offset / 2f, offset / 2f); return worldPos3D; } case EntitySpawnLocationType.AroundSpecificCoordinates: { var center = _config.CenterCoordinates; var radius = _config.Radius; var randomOffset = Random.insideUnitCircle * radius; return new Vector3(center.x + randomOffset.x, center.y + randomOffset.y, center.z); } case EntitySpawnLocationType.AroundTargetEntity: { if (string.IsNullOrEmpty(_config.TargetFactionDefName)) { Debug.LogWarning($"配置了 'AroundTargetEntity',但 'TargetFactionDefName' 为空或null。无法找到派系实体。将在原点生成。"); return Vector3.zero; } var factionEntities = EntityManage.Instance.FindEntitiesByFaction(dimensionID, _config.TargetFactionDefName); if (factionEntities == null || factionEntities.Length == 0) { Debug.LogWarning($"在维度 '{dimensionID}' 中未找到派系 '{_config.TargetFactionDefName}' 的任何实体。将在原点生成。"); return Vector3.zero; } var randomIndex = Random.Range(0, factionEntities.Length); var targetEntityPrefab = factionEntities[randomIndex]; if (targetEntityPrefab == null || targetEntityPrefab.transform == null) { Debug.LogWarning($"从派系 '{_config.TargetFactionDefName}' 中随机选择的实体为空或没有Transform组件。将在原点生成。"); return Vector3.zero; } var center = targetEntityPrefab.transform.position; var radius = _config.Radius; var randomOffset = Random.insideUnitCircle * radius; Debug.Log($"围绕派系 '{_config.TargetFactionDefName}' 的实体 (世界坐标: {center}) 生成。生成的偏移量: {randomOffset}。"); return new Vector3(center.x + randomOffset.x, center.y + randomOffset.y, center.z); } case EntitySpawnLocationType.RandomlyOnMap: { var size = mapGenerator.GetSize(); var randomGridPos = new Vector2Int(Random.Range(0, size.x), Random.Range(0, size.y)); var worldCoord2D = mapGenerator.GetWorldCoordinates(randomGridPos); var worldPos3D = new Vector3(worldCoord2D.x, worldCoord2D.y, 0f); Debug.Log($"随机地图生成位置: {worldPos3D} (网格坐标: {randomGridPos})。"); return worldPos3D; } case EntitySpawnLocationType.InsideSpecificBuildingType: { Debug.LogWarning($"类型为 'InsideSpecificBuildingType' ({_config.BuildingTypeDefName}) 的生成逻辑尚未实现。返回 Vector3.zero。"); return Vector3.zero; } case EntitySpawnLocationType.AtPredefinedSpawnPoint: { Debug.LogWarning($"类型为 'AtPredefinedSpawnPoint' ({_config.SpawnPointTileMapDefName}) 的生成逻辑尚未实现。返回 Vector3.zero。"); return Vector3.zero; } case EntitySpawnLocationType.None: default: Debug.LogWarning($"未知或不支持的生成位置类型: {_config.LocationType}。返回 Vector3.zero。"); return Vector3.zero; } } } }