(client)feat:视野范围检测,
This commit is contained in:
@ -3,102 +3,271 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Base;
|
||||
using Entity;
|
||||
using Map;
|
||||
using Prefab;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Managers
|
||||
{
|
||||
|
||||
public class EntityManage : Utils.MonoSingleton<EntityManage>, ITick
|
||||
{
|
||||
public Dictionary<string, LinkedList<EntityPrefab>> factionEntities = new();
|
||||
// --- 新增:维度感知的实体存储结构 ---
|
||||
// 外层字典:DimensionId -> 内层字典
|
||||
// 内层字典:FactionKey -> LinkedList<EntityPrefab>
|
||||
private Dictionary<string, Dictionary<string, LinkedList<EntityPrefab>>> _dimensionFactionEntities = new();
|
||||
|
||||
// --- 新增:当前场景中活跃的维度实例 ---
|
||||
private Dictionary<string, Dimension> _activeDimensions = new();
|
||||
|
||||
// --- 新增:维度感知的层级缓存 ---
|
||||
// DimensionId -> LayerName -> Transform
|
||||
private Dictionary<string, Dictionary<string, Transform>> _dimensionLayerCache = new();
|
||||
|
||||
// --- 待添加实体列表,现在包含 DimensionId ---
|
||||
private List<Tuple<string, string, EntityPrefab>>
|
||||
_pendingAdditions = new(); // Item1: DimensionId, Item2: FactionKey, Item3: EntityPrefab
|
||||
|
||||
// --- 现有预制体 (保持不变) ---
|
||||
public EntityPrefab characterPrefab;
|
||||
public EntityPrefab buildingPrefab;
|
||||
public EntityPrefab bulletPrefab;
|
||||
|
||||
public EntityPrefab defaultEntityPrefab;
|
||||
|
||||
private Dictionary<string, Transform> layerCache = new Dictionary<string, Transform>();
|
||||
private List<Tuple<string, EntityPrefab>> pendingAdditions = new();
|
||||
|
||||
public LinkedList<EntityPrefab> FindEntitiesByFaction(string factionKey)
|
||||
public void RegisterDimension(Dimension dimension)
|
||||
{
|
||||
if (factionEntities.TryGetValue(factionKey, out var entities))
|
||||
if (dimension == null || string.IsNullOrEmpty(dimension.DimensionId))
|
||||
{
|
||||
return entities; // 如果找到,返回对应的实体列表
|
||||
Debug.LogError("Attempted to register a null or invalid Dimension.");
|
||||
return;
|
||||
}
|
||||
|
||||
return new(); // 如果未找到,返回一个空列表
|
||||
if (_activeDimensions.TryGetValue(dimension.DimensionId, out var existingDimension))
|
||||
{
|
||||
if (existingDimension == dimension)
|
||||
{
|
||||
// 【逻辑修改】如果是同一个实例重复注册,只做信息提示,不警告
|
||||
Debug.Log($"Dimension with ID '{dimension.DimensionId}' already registered with the same instance. Skipping re-registration.");
|
||||
return; // 已经注册且是同一个实例,直接返回
|
||||
}
|
||||
else
|
||||
{
|
||||
// 【逻辑修改】如果是不同实例但ID相同,这是严重错误
|
||||
Debug.LogError(
|
||||
$"CRITICAL ERROR: Dimension with ID '{dimension.DimensionId}' is already registered with a DIFFERENT instance ({existingDimension.name} vs {dimension.name}). This indicates a duplicate DimensionId in the scene. The new instance will overwrite the old one, which may lead to unexpected behavior. Please ensure all Dimension objects have unique IDs.");
|
||||
// 允许覆盖,但以错误日志形式提示,强制开发者修复场景配置。
|
||||
}
|
||||
}
|
||||
|
||||
_activeDimensions[dimension.DimensionId] = dimension;
|
||||
Debug.Log($"Dimension '{dimension.DimensionId}' registered with EntityManage.");
|
||||
|
||||
// 为新注册的维度初始化其数据结构
|
||||
// 这些检查是必要的,以防止在重复注册时清空现有数据。
|
||||
if (!_dimensionFactionEntities.ContainsKey(dimension.DimensionId))
|
||||
{
|
||||
_dimensionFactionEntities[dimension.DimensionId] = new Dictionary<string, LinkedList<EntityPrefab>>();
|
||||
}
|
||||
|
||||
if (!_dimensionLayerCache.ContainsKey(dimension.DimensionId))
|
||||
{
|
||||
_dimensionLayerCache[dimension.DimensionId] = new Dictionary<string, Transform>();
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
foreach (var faction in factionEntities)
|
||||
{
|
||||
var entitiesToRemove = new List<EntityPrefab>();
|
||||
|
||||
foreach (var entityPrefab in faction.Value)
|
||||
/// <summary>
|
||||
/// 从实体管理器注销一个维度。
|
||||
/// </summary>
|
||||
/// <param name="dimension">要注销的维度实例。</param>
|
||||
public void UnregisterDimension(Dimension dimension)
|
||||
{
|
||||
if (dimension == null || string.IsNullOrEmpty(dimension.DimensionId))
|
||||
{
|
||||
Debug.LogError("Attempted to unregister a null or invalid Dimension.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_activeDimensions.Remove(dimension.DimensionId))
|
||||
{
|
||||
// 当维度被注销时,清理其所有相关的实体和层级缓存
|
||||
_dimensionFactionEntities.Remove(dimension.DimensionId);
|
||||
_dimensionLayerCache.Remove(dimension.DimensionId);
|
||||
|
||||
// 【逻辑修改】立即清理_pendingAdditions中属于该维度的实体
|
||||
// 创建一个新列表来存储不属于该维度的实体
|
||||
var remainingPendingAdditions = new List<Tuple<string, string, EntityPrefab>>();
|
||||
foreach (var pending in _pendingAdditions)
|
||||
{
|
||||
if (entityPrefab.entity.IsDead)
|
||||
if (pending.Item1 == dimension.DimensionId)
|
||||
{
|
||||
entitiesToRemove.Add(entityPrefab);
|
||||
// 销毁实体GameObject
|
||||
if (pending.Item3 != null && pending.Item3.gameObject != null) // 增加gameObject的null检查
|
||||
{
|
||||
Destroy(pending.Item3.gameObject);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ITick itike = entityPrefab.entity;
|
||||
itike.Tick();
|
||||
remainingPendingAdditions.Add(pending);
|
||||
}
|
||||
}
|
||||
_pendingAdditions = remainingPendingAdditions; // 更新_pendingAdditions列表
|
||||
}
|
||||
}
|
||||
|
||||
// 删除所有标记为死亡的实体
|
||||
foreach (var entityToRemove in entitiesToRemove)
|
||||
|
||||
/// <summary>
|
||||
/// 根据ID获取一个活跃的维度实例。
|
||||
/// </summary>
|
||||
/// <param name="dimensionId">维度的唯一标识符。</param>
|
||||
/// <returns>对应的 Dimension 实例,如果不存在则为 null。</returns>
|
||||
public Dimension GetDimension(string dimensionId)
|
||||
{
|
||||
_activeDimensions.TryGetValue(dimensionId, out var dimension);
|
||||
return dimension;
|
||||
}
|
||||
|
||||
// --- 查找实体 (现在维度感知) ---
|
||||
/// <summary>
|
||||
/// 在指定维度中,根据派系键查找所有实体。
|
||||
/// </summary>
|
||||
/// <param name="dimensionId">维度的唯一标识符。</param>
|
||||
/// <param name="factionKey">派系键。</param>
|
||||
/// <returns>指定派系下的实体列表,如果未找到则返回空列表。</returns>
|
||||
public LinkedList<EntityPrefab> FindEntitiesByFaction(string dimensionId, string factionKey)
|
||||
{
|
||||
if (_dimensionFactionEntities.TryGetValue(dimensionId, out var factionDict))
|
||||
{
|
||||
if (factionDict.TryGetValue(factionKey, out var entities))
|
||||
{
|
||||
faction.Value.Remove(entityToRemove);
|
||||
Destroy(entityToRemove.gameObject);
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
|
||||
if (pendingAdditions.Any())
|
||||
{
|
||||
foreach (var entity in pendingAdditions)
|
||||
{
|
||||
if (!factionEntities.ContainsKey(entity.Item1))
|
||||
{
|
||||
factionEntities[entity.Item1] = new LinkedList<EntityPrefab>();
|
||||
}
|
||||
return new LinkedList<EntityPrefab>(); // 如果未找到,返回一个空列表
|
||||
}
|
||||
|
||||
factionEntities[entity.Item1].AddLast(entity.Item2);
|
||||
// --- Tick 方法 (现在维度感知) ---
|
||||
public void Tick()
|
||||
{
|
||||
// 遍历每个活跃的维度
|
||||
foreach (var dimensionEntry in _dimensionFactionEntities.ToList()) // ToList() 避免在迭代时修改字典
|
||||
{
|
||||
var dimensionId = dimensionEntry.Key;
|
||||
var factionDict = dimensionEntry.Value;
|
||||
|
||||
// 检查维度对象本身是否仍然活跃在场景中
|
||||
// 注意:这里检查的是 _activeDimensions,确保 Dimension 对象实例仍然存在且被管理器追踪。
|
||||
if (!_activeDimensions.ContainsKey(dimensionId))
|
||||
{
|
||||
Debug.LogWarning(
|
||||
$"Skipping Tick for dimension '{dimensionId}' as its Dimension object is no longer active. Clearing its entities.");
|
||||
_dimensionFactionEntities.Remove(dimensionId); // 移除已失效维度的实体数据
|
||||
_dimensionLayerCache.Remove(dimensionId); // 移除已失效维度的层级缓存
|
||||
continue;
|
||||
}
|
||||
|
||||
pendingAdditions.Clear();
|
||||
foreach (var faction in factionDict)
|
||||
{
|
||||
var entitiesToRemove = new List<EntityPrefab>();
|
||||
var currentEntities = faction.Value.ToList(); // 创建副本以避免在迭代时修改列表
|
||||
|
||||
foreach (var entityPrefab in currentEntities)
|
||||
{
|
||||
// 检查实体预制体或其内部实体是否已销毁或死亡
|
||||
if (entityPrefab == null || entityPrefab.entity == null || entityPrefab.entity.IsDead)
|
||||
{
|
||||
entitiesToRemove.Add(entityPrefab);
|
||||
}
|
||||
else
|
||||
{
|
||||
ITick itike = entityPrefab.entity;
|
||||
itike.Tick();
|
||||
}
|
||||
}
|
||||
|
||||
// 删除所有标记为死亡的实体
|
||||
foreach (var entityToRemove in entitiesToRemove)
|
||||
{
|
||||
faction.Value.Remove(entityToRemove);
|
||||
if (entityToRemove != null) // 确保它没有被外部销毁
|
||||
{
|
||||
Destroy(entityToRemove.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理待添加实体 (现在维度感知)
|
||||
if (_pendingAdditions.Any())
|
||||
{
|
||||
foreach (var pending in _pendingAdditions)
|
||||
{
|
||||
var dimensionId = pending.Item1;
|
||||
var factionKey = pending.Item2;
|
||||
var entityPrefab = pending.Item3;
|
||||
|
||||
// 再次检查维度是否活跃,防止在添加前维度被注销
|
||||
if (!_dimensionFactionEntities.ContainsKey(dimensionId))
|
||||
{
|
||||
Debug.LogError(
|
||||
$"Attempted to add entity '{entityPrefab.name}' to unregistered or inactive dimension '{dimensionId}'. Entity will be destroyed.");
|
||||
if (entityPrefab != null) Destroy(entityPrefab.gameObject);
|
||||
continue;
|
||||
}
|
||||
|
||||
var factionDict = _dimensionFactionEntities[dimensionId];
|
||||
if (!factionDict.ContainsKey(factionKey))
|
||||
{
|
||||
factionDict[factionKey] = new LinkedList<EntityPrefab>();
|
||||
}
|
||||
|
||||
factionDict[factionKey].AddLast(entityPrefab);
|
||||
}
|
||||
|
||||
_pendingAdditions.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据给定的Def生成实体对象(内部通用方法)。
|
||||
/// </summary>
|
||||
/// <param name="dimensionId">实体所属的维度ID。</param>
|
||||
/// <param name="prefab">要实例化的预制体</param>
|
||||
/// <param name="parent">生成的父级Transform</param>
|
||||
/// <param name="pos">生成位置</param>
|
||||
/// <param name="def">实体定义对象</param>
|
||||
/// <param name="extraInit">额外的初始化操作(如子弹方向设置)</param>
|
||||
/// <returns>成功时返回EntityPrefab组件,失败时返回null</returns>
|
||||
private EntityPrefab GenerateEntityInternal(
|
||||
string dimensionId, // 新增参数:维度ID
|
||||
GameObject prefab,
|
||||
Transform parent,
|
||||
Vector3 pos,
|
||||
Data.EntityDef def, // 所有Def类型需继承自BaseDef
|
||||
Data.EntityDef def,
|
||||
Action<EntityPrefab> extraInit = null)
|
||||
{
|
||||
// 验证维度是否活跃
|
||||
if (!_activeDimensions.TryGetValue(dimensionId, out var dimension))
|
||||
{
|
||||
Debug.LogError($"Cannot generate entity: Dimension '{dimensionId}' is not active or registered.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取或创建实体所属的层级Transform,并确保其在维度根下
|
||||
var parentLayer = EnsureLayerExists(dimensionId, "DefaultEntityLevel"); // 使用一个默认层级名称
|
||||
if (parentLayer == null)
|
||||
{
|
||||
Debug.LogError($"Failed to get or create parent layer for entity in dimension '{dimensionId}'.");
|
||||
return null;
|
||||
}
|
||||
|
||||
GameObject instantiatedEntity = null;
|
||||
try
|
||||
{
|
||||
// 实例化实体
|
||||
instantiatedEntity = Instantiate(prefab, pos, Quaternion.identity, parent);
|
||||
// 实例化实体,并将其父级设置为维度下的层级Transform
|
||||
instantiatedEntity = Instantiate(prefab, pos, Quaternion.identity, parentLayer);
|
||||
|
||||
// 获取并验证EntityPrefab组件
|
||||
var entityComponent = instantiatedEntity.GetComponent<EntityPrefab>();
|
||||
if (!entityComponent)
|
||||
{
|
||||
@ -106,204 +275,231 @@ namespace Managers
|
||||
$"EntityPrefab component missing on: {instantiatedEntity.name}");
|
||||
}
|
||||
|
||||
// 初始化核心数据
|
||||
entityComponent.Init(def);
|
||||
|
||||
// 执行类型特有的额外初始化
|
||||
extraInit?.Invoke(entityComponent);
|
||||
|
||||
// 管理派系列表
|
||||
var factionKey = def.attributes.defName ?? "default";
|
||||
pendingAdditions.Add(Tuple.Create(factionKey, entityComponent));
|
||||
var factionKey = def.attributes.defName ?? "default"; // 假设 attributes.defName 是派系键
|
||||
_pendingAdditions.Add(Tuple.Create(dimensionId, factionKey, entityComponent)); // 添加维度ID
|
||||
return entityComponent;
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
// 清理失败实例
|
||||
if (instantiatedEntity) Destroy(instantiatedEntity);
|
||||
|
||||
Debug.LogError($"Entity generation failed: {ex.Message}\n{ex.StackTrace}");
|
||||
Debug.LogError($"Entity generation failed in dimension '{dimensionId}': {ex.Message}\n{ex.StackTrace}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态创建层(如果层不存在)
|
||||
/// 动态创建层(如果层不存在),现在是维度感知的。
|
||||
/// 每个维度有自己的层级结构,根在 Dimension.DimensionRoot 下。
|
||||
/// </summary>
|
||||
private Transform EnsureLayerExists(string layerName)
|
||||
/// <param name="dimensionId">维度的唯一标识符。</param>
|
||||
/// <param name="layerName">要确保存在的层级名称。</param>
|
||||
/// <returns>层级Transform,如果维度不存在或其根Transform为空则返回null。</returns>
|
||||
private Transform EnsureLayerExists(string dimensionId, string layerName)
|
||||
{
|
||||
// 先从缓存中查找
|
||||
if (layerCache.TryGetValue(layerName, out var layerTransform))
|
||||
// 尝试从维度层级缓存中获取
|
||||
if (!_dimensionLayerCache.TryGetValue(dimensionId, out var layerCacheForDimension))
|
||||
{
|
||||
Debug.LogError(
|
||||
$"Dimension '{dimensionId}' not found in layer cache. This should not happen if dimension is registered.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (layerCacheForDimension.TryGetValue(layerName, out var layerTransform))
|
||||
{
|
||||
return layerTransform;
|
||||
}
|
||||
|
||||
// 如果缓存中没有,尝试通过 transform.Find 查找
|
||||
layerTransform = transform.Find(layerName);
|
||||
// 如果缓存中没有,尝试在维度根下查找
|
||||
var dimension = GetDimension(dimensionId);
|
||||
if (dimension == null || dimension.DimensionRoot == null)
|
||||
{
|
||||
Debug.LogError(
|
||||
$"Dimension '{dimensionId}' or its root transform is null. Cannot create layer '{layerName}'.");
|
||||
return null;
|
||||
}
|
||||
|
||||
layerTransform = dimension.DimensionRoot.Find(layerName);
|
||||
|
||||
if (!layerTransform)
|
||||
{
|
||||
// 如果层不存在,动态创建
|
||||
// 如果层不存在,动态创建并将其父级设置为维度的根Transform
|
||||
var layerObject = new GameObject(layerName);
|
||||
layerTransform = layerObject.transform;
|
||||
layerTransform.SetParent(dimension.DimensionRoot);
|
||||
}
|
||||
|
||||
// 将新创建的层加入缓存
|
||||
layerCache[layerName] = layerTransform;
|
||||
|
||||
layerCacheForDimension[layerName] = layerTransform;
|
||||
return layerTransform;
|
||||
}
|
||||
|
||||
// --- 公共生成方法 (现在维度感知) ---
|
||||
/// <summary>
|
||||
/// 根据PawnDef生成普通实体
|
||||
/// 在指定维度中,根据PawnDef生成普通实体。
|
||||
/// </summary>
|
||||
public void GenerateEntity(Data.EntityDef entityDef, Vector3 pos)
|
||||
public void GenerateEntity(string dimensionId, Data.EntityDef entityDef, Vector3 pos)
|
||||
{
|
||||
// 验证关键参数
|
||||
if (!characterPrefab)
|
||||
{
|
||||
Debug.LogError("entityPrefab is null! Assign a valid prefab.");
|
||||
GenerateDefaultEntity(pos);
|
||||
Debug.LogError("characterPrefab is null! Assign a valid prefab.");
|
||||
GenerateDefaultEntity(dimensionId, pos);
|
||||
return;
|
||||
}
|
||||
|
||||
if (entityDef == null)
|
||||
{
|
||||
Debug.LogError("EntityDef is null! Cannot generate entity.");
|
||||
GenerateDefaultEntity(pos);
|
||||
GenerateDefaultEntity(dimensionId, pos);
|
||||
return;
|
||||
}
|
||||
|
||||
// 确保层存在
|
||||
var entityLevelTransform = EnsureLayerExists("EntityLevel");
|
||||
|
||||
// 调用通用生成逻辑
|
||||
var result = GenerateEntityInternal(
|
||||
dimensionId,
|
||||
characterPrefab.gameObject,
|
||||
entityLevelTransform,
|
||||
pos,
|
||||
entityDef
|
||||
);
|
||||
|
||||
if (!result) GenerateDefaultEntity(pos);
|
||||
if (!result) GenerateDefaultEntity(dimensionId, pos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成建筑实体(位置使用Vector3Int)
|
||||
/// 在指定维度中,生成建筑实体(位置使用Vector3Int)。
|
||||
/// </summary>
|
||||
public void GenerateBuildingEntity(Data.BuildingDef buildingDef, Vector3Int pos)
|
||||
public void GenerateBuildingEntity(string dimensionId, Data.BuildingDef buildingDef, Vector3Int pos)
|
||||
{
|
||||
// 修正:检查正确的预制体 (buildingPrefab)
|
||||
if (!buildingPrefab)
|
||||
{
|
||||
Debug.LogError("buildingPrefab is null! Assign a valid prefab.");
|
||||
GenerateDefaultEntity(pos);
|
||||
GenerateDefaultEntity(dimensionId, pos);
|
||||
return;
|
||||
}
|
||||
|
||||
if (buildingDef == null)
|
||||
{
|
||||
Debug.LogError("BuildingDef is null! Cannot generate building.");
|
||||
GenerateDefaultEntity(pos);
|
||||
GenerateDefaultEntity(dimensionId, pos);
|
||||
return;
|
||||
}
|
||||
|
||||
var worldPos = new Vector3(pos.x, pos.y, pos.z);
|
||||
|
||||
// 确保层存在
|
||||
var buildingLevelTransform = EnsureLayerExists("BuildingLevel");
|
||||
|
||||
var result = GenerateEntityInternal(
|
||||
dimensionId,
|
||||
buildingPrefab.gameObject,
|
||||
buildingLevelTransform,
|
||||
worldPos,
|
||||
buildingDef
|
||||
);
|
||||
|
||||
if (!result) GenerateDefaultEntity(worldPos);
|
||||
if (!result) GenerateDefaultEntity(dimensionId, worldPos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成子弹实体(含方向设置)
|
||||
/// 在指定维度中,生成子弹实体(含方向设置)。
|
||||
/// </summary>
|
||||
public void GenerateBulletEntity(Data.BulletDef bulletDef, Vector3 pos, Vector3 dir,
|
||||
public void GenerateBulletEntity(string dimensionId, Data.BulletDef bulletDef, Vector3 pos, Vector3 dir,
|
||||
Entity.Entity source = null)
|
||||
{
|
||||
// 修正:检查正确的预制体 (bulletPrefab)
|
||||
if (!bulletPrefab)
|
||||
{
|
||||
Debug.LogError("bulletPrefab is null! Assign a valid prefab.");
|
||||
GenerateDefaultEntity(pos);
|
||||
GenerateDefaultEntity(dimensionId, pos);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bulletDef == null)
|
||||
{
|
||||
Debug.LogError("BulletDef is null! Cannot generate bullet.");
|
||||
GenerateDefaultEntity(pos);
|
||||
GenerateDefaultEntity(dimensionId, pos);
|
||||
return;
|
||||
}
|
||||
|
||||
// 确保层存在
|
||||
var bulletLevelTransform = EnsureLayerExists("BulletLevel");
|
||||
|
||||
var result = GenerateEntityInternal(
|
||||
dimensionId,
|
||||
bulletPrefab.gameObject,
|
||||
bulletLevelTransform,
|
||||
pos,
|
||||
bulletDef,
|
||||
// 子弹特有的方向设置
|
||||
entityComponent => entityComponent.entity.SetTarget(pos + dir)
|
||||
);
|
||||
if (result.entity is Bullet bullet)
|
||||
|
||||
// 确保 result 不为 null 且 entity 是 Bullet 类型
|
||||
if (result != null && result.entity is Bullet bullet)
|
||||
{
|
||||
bullet.bulletSource = source;
|
||||
if (source) bullet.affiliation = source.affiliation;
|
||||
if (source != null) bullet.affiliation = source.affiliation; // 确保 source 不为 null
|
||||
}
|
||||
|
||||
if (!result) GenerateDefaultEntity(pos);
|
||||
if (!result) GenerateDefaultEntity(dimensionId, pos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成默认实体(错误回退)
|
||||
/// 在指定维度中,生成默认实体(错误回退)。
|
||||
/// </summary>
|
||||
public void GenerateDefaultEntity(Vector3 pos)
|
||||
public void GenerateDefaultEntity(string dimensionId, Vector3 pos)
|
||||
{
|
||||
// 确保层存在
|
||||
var entityLevelTransform = EnsureLayerExists("EntityLevel");
|
||||
if (!_activeDimensions.ContainsKey(dimensionId))
|
||||
{
|
||||
Debug.LogError(
|
||||
$"Cannot generate default entity: Dimension '{dimensionId}' is not active or registered.");
|
||||
return;
|
||||
}
|
||||
|
||||
var entity = Instantiate(defaultEntityPrefab, pos, Quaternion.identity, entityLevelTransform);
|
||||
var parentLayer = EnsureLayerExists(dimensionId, "DefaultEntityLevel");
|
||||
if (parentLayer == null)
|
||||
{
|
||||
Debug.LogError($"Failed to get parent transform for default entity in dimension '{dimensionId}'.");
|
||||
return;
|
||||
}
|
||||
|
||||
var entity = Instantiate(defaultEntityPrefab, pos, Quaternion.identity, parentLayer);
|
||||
var entityComponent = entity.GetComponent<EntityPrefab>();
|
||||
|
||||
const string factionKey = "default";
|
||||
pendingAdditions.Add(Tuple.Create(factionKey, entityComponent));
|
||||
|
||||
_pendingAdditions.Add(Tuple.Create(dimensionId, factionKey, entityComponent));
|
||||
entityComponent.DefaultInit();
|
||||
}
|
||||
|
||||
|
||||
// --- 单例生命周期与场景切换处理 ---
|
||||
protected override void OnStart()
|
||||
{
|
||||
SceneManager.sceneLoaded += OnSceneLoaded;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
SceneManager.sceneLoaded -= OnSceneLoaded;
|
||||
}
|
||||
|
||||
protected override void OnStart()
|
||||
{
|
||||
SceneManager.sceneLoaded += OnSceneLoaded;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 场景加载完成时的回调。
|
||||
/// 清理旧场景的实体数据,并重新扫描新场景中的维度。
|
||||
/// </summary>
|
||||
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
||||
{
|
||||
factionEntities.Clear();
|
||||
layerCache.Clear();
|
||||
pendingAdditions.Clear();
|
||||
_dimensionFactionEntities.Clear(); // 清理所有维度下的实体数据
|
||||
_dimensionLayerCache.Clear(); // 清理所有维度下的层级缓存
|
||||
_pendingAdditions.Clear(); // 清理待添加实体列表
|
||||
_activeDimensions.Clear(); // 清理活跃维度列表,因为旧场景的维度对象已被销毁
|
||||
}
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
var pre = Resources.Load<GameObject>("Default/DefaultEntity");
|
||||
defaultEntityPrefab = pre.GetComponent<EntityPrefab>();
|
||||
layerCache.Clear();
|
||||
if (defaultEntityPrefab == null)
|
||||
{
|
||||
var pre = Resources.Load<GameObject>("Default/DefaultEntity");
|
||||
if (pre != null)
|
||||
{
|
||||
defaultEntityPrefab = pre.GetComponent<EntityPrefab>();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError(
|
||||
"Failed to load DefaultEntity prefab from Resources/Default/DefaultEntity. Please ensure it exists at 'Assets/Resources/Default/DefaultEntity.prefab'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user